Whamcloud - gitweb
40e3d8263f7c5dc27ec526849cfef7d8ec3179f7
[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_sub() {
5812         local stripecount=$1
5813         local nfiles=$((200 * $OSTCOUNT))
5814
5815         log "create files with stripecount=$stripecount"
5816         $LFS setstripe -C $stripecount $DIR/$tdir
5817         createmany -o $DIR/$tdir/t- $nfiles
5818         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5819         for ((n = 0; n < $OSTCOUNT; n++)); do
5820                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5821                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5822                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5823                             '($1 == '$n') { objs += 1 } \
5824                             END { printf("%0.0f", objs) }')
5825                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5826         done
5827         unlinkmany $DIR/$tdir/t- $nfiles
5828         rm  -f $TMP/$tfile
5829
5830         local nlast
5831         local min=4
5832         local max=5 # allow variance of (1 - $min/$max) = 20% by default
5833
5834         # For some combinations of stripecount and OSTCOUNT current code
5835         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
5836         # than others. Rather than skipping this test entirely, check that
5837         # and keep testing to ensure imbalance does not get worse. LU-15282
5838         (( (OSTCOUNT == 6 && stripecount == 4) ||
5839            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
5840            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
5841         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
5842                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5843                         { $LFS df && $LFS df -i &&
5844                         error "OST $n has fewer objects vs. OST $nlast " \
5845                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
5846                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5847                         { $LFS df && $LFS df -i &&
5848                         error "OST $n has fewer objects vs. OST $nlast " \
5849                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
5850
5851                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
5852                         { $LFS df && $LFS df -i &&
5853                         error "OST $n has fewer #0 objects vs. OST $nlast " \
5854                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
5855                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
5856                         { $LFS df && $LFS df -i &&
5857                         error "OST $n has fewer #0 objects vs. OST $nlast " \
5858                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
5859         done
5860 }
5861
5862 test_51d() {
5863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5864         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5865
5866         local stripecount
5867         local qos_old=$(do_facet mds1 \
5868                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5869
5870         do_nodes $(comma_list $(mdts_nodes)) \
5871                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5872         stack_trap "do_nodes $(comma_list $(mdts_nodes)) \
5873                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5874
5875         test_mkdir $DIR/$tdir
5876
5877         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
5878                 test_51d_sub $stripecount
5879         done
5880 }
5881 run_test 51d "check object distribution"
5882
5883 test_51e() {
5884         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5885                 skip_env "ldiskfs only test"
5886         fi
5887
5888         test_mkdir -c1 $DIR/$tdir
5889         test_mkdir -c1 $DIR/$tdir/d0
5890
5891         touch $DIR/$tdir/d0/foo
5892         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5893                 error "file exceed 65000 nlink limit!"
5894         unlinkmany $DIR/$tdir/d0/f- 65001
5895         return 0
5896 }
5897 run_test 51e "check file nlink limit"
5898
5899 test_51f() {
5900         test_mkdir $DIR/$tdir
5901
5902         local max=100000
5903         local ulimit_old=$(ulimit -n)
5904         local spare=20 # number of spare fd's for scripts/libraries, etc.
5905         local mdt=$($LFS getstripe -m $DIR/$tdir)
5906         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5907
5908         echo "MDT$mdt numfree=$numfree, max=$max"
5909         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5910         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5911                 while ! ulimit -n $((numfree + spare)); do
5912                         numfree=$((numfree * 3 / 4))
5913                 done
5914                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5915         else
5916                 echo "left ulimit at $ulimit_old"
5917         fi
5918
5919         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5920                 unlinkmany $DIR/$tdir/f $numfree
5921                 error "create+open $numfree files in $DIR/$tdir failed"
5922         }
5923         ulimit -n $ulimit_old
5924
5925         # if createmany exits at 120s there will be fewer than $numfree files
5926         unlinkmany $DIR/$tdir/f $numfree || true
5927 }
5928 run_test 51f "check many open files limit"
5929
5930 test_52a() {
5931         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5932         test_mkdir $DIR/$tdir
5933         touch $DIR/$tdir/foo
5934         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5935         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5936         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5937         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5938         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5939                                         error "link worked"
5940         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5941         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5942         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5943                                                      error "lsattr"
5944         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5945         cp -r $DIR/$tdir $TMP/
5946         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5947 }
5948 run_test 52a "append-only flag test (should return errors)"
5949
5950 test_52b() {
5951         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5952         test_mkdir $DIR/$tdir
5953         touch $DIR/$tdir/foo
5954         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5955         cat test > $DIR/$tdir/foo && error "cat test worked"
5956         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5957         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5958         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5959                                         error "link worked"
5960         echo foo >> $DIR/$tdir/foo && error "echo worked"
5961         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5962         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5963         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5964         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5965                                                         error "lsattr"
5966         chattr -i $DIR/$tdir/foo || error "chattr failed"
5967
5968         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5969 }
5970 run_test 52b "immutable flag test (should return errors) ======="
5971
5972 test_53() {
5973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5974         remote_mds_nodsh && skip "remote MDS with nodsh"
5975         remote_ost_nodsh && skip "remote OST with nodsh"
5976
5977         local param
5978         local param_seq
5979         local ostname
5980         local mds_last
5981         local mds_last_seq
5982         local ost_last
5983         local ost_last_seq
5984         local ost_last_id
5985         local ostnum
5986         local node
5987         local found=false
5988         local support_last_seq=true
5989
5990         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5991                 support_last_seq=false
5992
5993         # only test MDT0000
5994         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5995         local value
5996         for value in $(do_facet $SINGLEMDS \
5997                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5998                 param=$(echo ${value[0]} | cut -d "=" -f1)
5999                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6000
6001                 if $support_last_seq; then
6002                         param_seq=$(echo $param |
6003                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6004                         mds_last_seq=$(do_facet $SINGLEMDS \
6005                                        $LCTL get_param -n $param_seq)
6006                 fi
6007                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6008
6009                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6010                 node=$(facet_active_host ost$((ostnum+1)))
6011                 param="obdfilter.$ostname.last_id"
6012                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6013                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6014                         ost_last_id=$ost_last
6015
6016                         if $support_last_seq; then
6017                                 ost_last_id=$(echo $ost_last |
6018                                               awk -F':' '{print $2}' |
6019                                               sed -e "s/^0x//g")
6020                                 ost_last_seq=$(echo $ost_last |
6021                                                awk -F':' '{print $1}')
6022                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6023                         fi
6024
6025                         if [[ $ost_last_id != $mds_last ]]; then
6026                                 error "$ost_last_id != $mds_last"
6027                         else
6028                                 found=true
6029                                 break
6030                         fi
6031                 done
6032         done
6033         $found || error "can not match last_seq/last_id for $mdtosc"
6034         return 0
6035 }
6036 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6037
6038 test_54a() {
6039         perl -MSocket -e ';' || skip "no Socket perl module installed"
6040
6041         $SOCKETSERVER $DIR/socket ||
6042                 error "$SOCKETSERVER $DIR/socket failed: $?"
6043         $SOCKETCLIENT $DIR/socket ||
6044                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6045         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6046 }
6047 run_test 54a "unix domain socket test =========================="
6048
6049 test_54b() {
6050         f="$DIR/f54b"
6051         mknod $f c 1 3
6052         chmod 0666 $f
6053         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6054 }
6055 run_test 54b "char device works in lustre ======================"
6056
6057 find_loop_dev() {
6058         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6059         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6060         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6061
6062         for i in $(seq 3 7); do
6063                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6064                 LOOPDEV=$LOOPBASE$i
6065                 LOOPNUM=$i
6066                 break
6067         done
6068 }
6069
6070 cleanup_54c() {
6071         local rc=0
6072         loopdev="$DIR/loop54c"
6073
6074         trap 0
6075         $UMOUNT $DIR/$tdir || rc=$?
6076         losetup -d $loopdev || true
6077         losetup -d $LOOPDEV || true
6078         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6079         return $rc
6080 }
6081
6082 test_54c() {
6083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6084
6085         loopdev="$DIR/loop54c"
6086
6087         find_loop_dev
6088         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6089         trap cleanup_54c EXIT
6090         mknod $loopdev b 7 $LOOPNUM
6091         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6092         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6093         losetup $loopdev $DIR/$tfile ||
6094                 error "can't set up $loopdev for $DIR/$tfile"
6095         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6096         test_mkdir $DIR/$tdir
6097         mount -t ext2 $loopdev $DIR/$tdir ||
6098                 error "error mounting $loopdev on $DIR/$tdir"
6099         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6100                 error "dd write"
6101         df $DIR/$tdir
6102         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6103                 error "dd read"
6104         cleanup_54c
6105 }
6106 run_test 54c "block device works in lustre ====================="
6107
6108 test_54d() {
6109         local pipe="$DIR/$tfile.pipe"
6110         local string="aaaaaa"
6111
6112         mknod $pipe p
6113         echo -n "$string" > $pipe &
6114         local result=$(cat $pipe)
6115         [[ "$result" == "$string" ]] || error "$result != $string"
6116 }
6117 run_test 54d "fifo device works in lustre ======================"
6118
6119 test_54e() {
6120         f="$DIR/f54e"
6121         string="aaaaaa"
6122         cp -aL /dev/console $f
6123         echo $string > $f || error "echo $string to $f failed"
6124 }
6125 run_test 54e "console/tty device works in lustre ======================"
6126
6127 test_56a() {
6128         local numfiles=3
6129         local numdirs=2
6130         local dir=$DIR/$tdir
6131
6132         rm -rf $dir
6133         test_mkdir -p $dir/dir
6134         for i in $(seq $numfiles); do
6135                 touch $dir/file$i
6136                 touch $dir/dir/file$i
6137         done
6138
6139         local numcomp=$($LFS getstripe --component-count $dir)
6140
6141         [[ $numcomp == 0 ]] && numcomp=1
6142
6143         # test lfs getstripe with --recursive
6144         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6145
6146         [[ $filenum -eq $((numfiles * 2)) ]] ||
6147                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6148         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6149         [[ $filenum -eq $numfiles ]] ||
6150                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6151         echo "$LFS getstripe showed obdidx or l_ost_idx"
6152
6153         # test lfs getstripe with file instead of dir
6154         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6155         [[ $filenum -eq 1 ]] ||
6156                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6157         echo "$LFS getstripe file1 passed"
6158
6159         #test lfs getstripe with --verbose
6160         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6161         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6162                 error "$LFS getstripe --verbose $dir: "\
6163                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6164         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6165                 error "$LFS getstripe $dir: showed lmm_magic"
6166
6167         #test lfs getstripe with -v prints lmm_fid
6168         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6169         local countfids=$((numdirs + numfiles * numcomp))
6170         [[ $filenum -eq $countfids ]] ||
6171                 error "$LFS getstripe -v $dir: "\
6172                       "got $filenum want $countfids lmm_fid"
6173         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6174                 error "$LFS getstripe $dir: showed lmm_fid by default"
6175         echo "$LFS getstripe --verbose passed"
6176
6177         #check for FID information
6178         local fid1=$($LFS getstripe --fid $dir/file1)
6179         local fid2=$($LFS getstripe --verbose $dir/file1 |
6180                      awk '/lmm_fid: / { print $2; exit; }')
6181         local fid3=$($LFS path2fid $dir/file1)
6182
6183         [ "$fid1" != "$fid2" ] &&
6184                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6185         [ "$fid1" != "$fid3" ] &&
6186                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6187         echo "$LFS getstripe --fid passed"
6188
6189         #test lfs getstripe with --obd
6190         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6191                 error "$LFS getstripe --obd wrong_uuid: should return error"
6192
6193         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6194
6195         local ostidx=1
6196         local obduuid=$(ostuuid_from_index $ostidx)
6197         local found=$($LFS getstripe -r --obd $obduuid $dir |
6198                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6199
6200         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6201         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6202                 ((filenum--))
6203         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6204                 ((filenum--))
6205
6206         [[ $found -eq $filenum ]] ||
6207                 error "$LFS getstripe --obd: found $found expect $filenum"
6208         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6209                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6210                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6211                 error "$LFS getstripe --obd: should not show file on other obd"
6212         echo "$LFS getstripe --obd passed"
6213 }
6214 run_test 56a "check $LFS getstripe"
6215
6216 test_56b() {
6217         local dir=$DIR/$tdir
6218         local numdirs=3
6219
6220         test_mkdir $dir
6221         for i in $(seq $numdirs); do
6222                 test_mkdir $dir/dir$i
6223         done
6224
6225         # test lfs getdirstripe default mode is non-recursion, which is
6226         # different from lfs getstripe
6227         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6228
6229         [[ $dircnt -eq 1 ]] ||
6230                 error "$LFS getdirstripe: found $dircnt, not 1"
6231         dircnt=$($LFS getdirstripe --recursive $dir |
6232                 grep -c lmv_stripe_count)
6233         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6234                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6235 }
6236 run_test 56b "check $LFS getdirstripe"
6237
6238 test_56c() {
6239         remote_ost_nodsh && skip "remote OST with nodsh"
6240
6241         local ost_idx=0
6242         local ost_name=$(ostname_from_index $ost_idx)
6243         local old_status=$(ost_dev_status $ost_idx)
6244         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6245
6246         [[ -z "$old_status" ]] ||
6247                 skip_env "OST $ost_name is in $old_status status"
6248
6249         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6250         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6251                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6252         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6253                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6254                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6255         fi
6256
6257         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6258                 error "$LFS df -v showing inactive devices"
6259         sleep_maxage
6260
6261         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6262
6263         [[ "$new_status" =~ "D" ]] ||
6264                 error "$ost_name status is '$new_status', missing 'D'"
6265         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6266                 [[ "$new_status" =~ "N" ]] ||
6267                         error "$ost_name status is '$new_status', missing 'N'"
6268         fi
6269         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6270                 [[ "$new_status" =~ "f" ]] ||
6271                         error "$ost_name status is '$new_status', missing 'f'"
6272         fi
6273
6274         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6275         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6276                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6277         [[ -z "$p" ]] && restore_lustre_params < $p || true
6278         sleep_maxage
6279
6280         new_status=$(ost_dev_status $ost_idx)
6281         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6282                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6283         # can't check 'f' as devices may actually be on flash
6284 }
6285 run_test 56c "check 'lfs df' showing device status"
6286
6287 test_56d() {
6288         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6289         local osts=$($LFS df -v $MOUNT | grep -c OST)
6290
6291         $LFS df $MOUNT
6292
6293         (( mdts == MDSCOUNT )) ||
6294                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6295         (( osts == OSTCOUNT )) ||
6296                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6297 }
6298 run_test 56d "'lfs df -v' prints only configured devices"
6299
6300 test_56e() {
6301         err_enoent=2 # No such file or directory
6302         err_eopnotsupp=95 # Operation not supported
6303
6304         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6305         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6306
6307         # Check for handling of path not exists
6308         output=$($LFS df $enoent_mnt 2>&1)
6309         ret=$?
6310
6311         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6312         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6313                 error "expect failure $err_enoent, not $ret"
6314
6315         # Check for handling of non-Lustre FS
6316         output=$($LFS df $notsup_mnt)
6317         ret=$?
6318
6319         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6320         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6321                 error "expect success $err_eopnotsupp, not $ret"
6322
6323         # Check for multiple LustreFS argument
6324         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6325         ret=$?
6326
6327         [[ $output -eq 3 && $ret -eq 0 ]] ||
6328                 error "expect success 3, not $output, rc = $ret"
6329
6330         # Check for correct non-Lustre FS handling among multiple
6331         # LustreFS argument
6332         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6333                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6334         ret=$?
6335
6336         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6337                 error "expect success 2, not $output, rc = $ret"
6338 }
6339 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6340
6341 NUMFILES=3
6342 NUMDIRS=3
6343 setup_56() {
6344         local local_tdir="$1"
6345         local local_numfiles="$2"
6346         local local_numdirs="$3"
6347         local dir_params="$4"
6348         local dir_stripe_params="$5"
6349
6350         if [ ! -d "$local_tdir" ] ; then
6351                 test_mkdir -p $dir_stripe_params $local_tdir
6352                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6353                 for i in $(seq $local_numfiles) ; do
6354                         touch $local_tdir/file$i
6355                 done
6356                 for i in $(seq $local_numdirs) ; do
6357                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6358                         for j in $(seq $local_numfiles) ; do
6359                                 touch $local_tdir/dir$i/file$j
6360                         done
6361                 done
6362         fi
6363 }
6364
6365 setup_56_special() {
6366         local local_tdir=$1
6367         local local_numfiles=$2
6368         local local_numdirs=$3
6369
6370         setup_56 $local_tdir $local_numfiles $local_numdirs
6371
6372         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6373                 for i in $(seq $local_numfiles) ; do
6374                         mknod $local_tdir/loop${i}b b 7 $i
6375                         mknod $local_tdir/null${i}c c 1 3
6376                         ln -s $local_tdir/file1 $local_tdir/link${i}
6377                 done
6378                 for i in $(seq $local_numdirs) ; do
6379                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6380                         mknod $local_tdir/dir$i/null${i}c c 1 3
6381                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6382                 done
6383         fi
6384 }
6385
6386 test_56g() {
6387         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6388         local expected=$(($NUMDIRS + 2))
6389
6390         setup_56 $dir $NUMFILES $NUMDIRS
6391
6392         # test lfs find with -name
6393         for i in $(seq $NUMFILES) ; do
6394                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6395
6396                 [ $nums -eq $expected ] ||
6397                         error "lfs find -name '*$i' $dir wrong: "\
6398                               "found $nums, expected $expected"
6399         done
6400 }
6401 run_test 56g "check lfs find -name"
6402
6403 test_56h() {
6404         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6405         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6406
6407         setup_56 $dir $NUMFILES $NUMDIRS
6408
6409         # test lfs find with ! -name
6410         for i in $(seq $NUMFILES) ; do
6411                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6412
6413                 [ $nums -eq $expected ] ||
6414                         error "lfs find ! -name '*$i' $dir wrong: "\
6415                               "found $nums, expected $expected"
6416         done
6417 }
6418 run_test 56h "check lfs find ! -name"
6419
6420 test_56i() {
6421         local dir=$DIR/$tdir
6422
6423         test_mkdir $dir
6424
6425         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6426         local out=$($cmd)
6427
6428         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6429 }
6430 run_test 56i "check 'lfs find -ost UUID' skips directories"
6431
6432 test_56j() {
6433         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6434
6435         setup_56_special $dir $NUMFILES $NUMDIRS
6436
6437         local expected=$((NUMDIRS + 1))
6438         local cmd="$LFS find -type d $dir"
6439         local nums=$($cmd | wc -l)
6440
6441         [ $nums -eq $expected ] ||
6442                 error "'$cmd' wrong: found $nums, expected $expected"
6443 }
6444 run_test 56j "check lfs find -type d"
6445
6446 test_56k() {
6447         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6448
6449         setup_56_special $dir $NUMFILES $NUMDIRS
6450
6451         local expected=$(((NUMDIRS + 1) * NUMFILES))
6452         local cmd="$LFS find -type f $dir"
6453         local nums=$($cmd | wc -l)
6454
6455         [ $nums -eq $expected ] ||
6456                 error "'$cmd' wrong: found $nums, expected $expected"
6457 }
6458 run_test 56k "check lfs find -type f"
6459
6460 test_56l() {
6461         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6462
6463         setup_56_special $dir $NUMFILES $NUMDIRS
6464
6465         local expected=$((NUMDIRS + NUMFILES))
6466         local cmd="$LFS find -type b $dir"
6467         local nums=$($cmd | wc -l)
6468
6469         [ $nums -eq $expected ] ||
6470                 error "'$cmd' wrong: found $nums, expected $expected"
6471 }
6472 run_test 56l "check lfs find -type b"
6473
6474 test_56m() {
6475         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6476
6477         setup_56_special $dir $NUMFILES $NUMDIRS
6478
6479         local expected=$((NUMDIRS + NUMFILES))
6480         local cmd="$LFS find -type c $dir"
6481         local nums=$($cmd | wc -l)
6482         [ $nums -eq $expected ] ||
6483                 error "'$cmd' wrong: found $nums, expected $expected"
6484 }
6485 run_test 56m "check lfs find -type c"
6486
6487 test_56n() {
6488         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6489         setup_56_special $dir $NUMFILES $NUMDIRS
6490
6491         local expected=$((NUMDIRS + NUMFILES))
6492         local cmd="$LFS find -type l $dir"
6493         local nums=$($cmd | wc -l)
6494
6495         [ $nums -eq $expected ] ||
6496                 error "'$cmd' wrong: found $nums, expected $expected"
6497 }
6498 run_test 56n "check lfs find -type l"
6499
6500 test_56o() {
6501         local dir=$DIR/$tdir
6502
6503         setup_56 $dir $NUMFILES $NUMDIRS
6504         utime $dir/file1 > /dev/null || error "utime (1)"
6505         utime $dir/file2 > /dev/null || error "utime (2)"
6506         utime $dir/dir1 > /dev/null || error "utime (3)"
6507         utime $dir/dir2 > /dev/null || error "utime (4)"
6508         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6509         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6510
6511         local expected=4
6512         local nums=$($LFS find -mtime +0 $dir | wc -l)
6513
6514         [ $nums -eq $expected ] ||
6515                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6516
6517         expected=12
6518         cmd="$LFS find -mtime 0 $dir"
6519         nums=$($cmd | wc -l)
6520         [ $nums -eq $expected ] ||
6521                 error "'$cmd' wrong: found $nums, expected $expected"
6522 }
6523 run_test 56o "check lfs find -mtime for old files"
6524
6525 test_56ob() {
6526         local dir=$DIR/$tdir
6527         local expected=1
6528         local count=0
6529
6530         # just to make sure there is something that won't be found
6531         test_mkdir $dir
6532         touch $dir/$tfile.now
6533
6534         for age in year week day hour min; do
6535                 count=$((count + 1))
6536
6537                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6538                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6539                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6540
6541                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6542                 local nums=$($cmd | wc -l)
6543                 [ $nums -eq $expected ] ||
6544                         error "'$cmd' wrong: found $nums, expected $expected"
6545
6546                 cmd="$LFS find $dir -atime $count${age:0:1}"
6547                 nums=$($cmd | wc -l)
6548                 [ $nums -eq $expected ] ||
6549                         error "'$cmd' wrong: found $nums, expected $expected"
6550         done
6551
6552         sleep 2
6553         cmd="$LFS find $dir -ctime +1s -type f"
6554         nums=$($cmd | wc -l)
6555         (( $nums == $count * 2 + 1)) ||
6556                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6557 }
6558 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6559
6560 test_newerXY_base() {
6561         local x=$1
6562         local y=$2
6563         local dir=$DIR/$tdir
6564         local ref
6565         local negref
6566
6567         if [ $y == "t" ]; then
6568                 if [ $x == "b" ]; then
6569                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6570                 else
6571                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6572                 fi
6573         else
6574                 ref=$DIR/$tfile.newer.$x$y
6575                 touch $ref || error "touch $ref failed"
6576         fi
6577
6578         echo "before = $ref"
6579         sleep 2
6580         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6581         sleep 2
6582         if [ $y == "t" ]; then
6583                 if [ $x == "b" ]; then
6584                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6585                 else
6586                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6587                 fi
6588         else
6589                 negref=$DIR/$tfile.negnewer.$x$y
6590                 touch $negref || error "touch $negref failed"
6591         fi
6592
6593         echo "after = $negref"
6594         local cmd="$LFS find $dir -newer$x$y $ref"
6595         local nums=$(eval $cmd | wc -l)
6596         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6597
6598         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6599                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6600
6601         cmd="$LFS find $dir ! -newer$x$y $negref"
6602         nums=$(eval $cmd | wc -l)
6603         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6604                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6605
6606         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6607         nums=$(eval $cmd | wc -l)
6608         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6609                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6610
6611         rm -rf $DIR/*
6612 }
6613
6614 test_56oc() {
6615         test_newerXY_base "a" "a"
6616         test_newerXY_base "a" "m"
6617         test_newerXY_base "a" "c"
6618         test_newerXY_base "m" "a"
6619         test_newerXY_base "m" "m"
6620         test_newerXY_base "m" "c"
6621         test_newerXY_base "c" "a"
6622         test_newerXY_base "c" "m"
6623         test_newerXY_base "c" "c"
6624
6625         [[ -n "$sles_version" ]] &&
6626                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6627
6628         test_newerXY_base "a" "t"
6629         test_newerXY_base "m" "t"
6630         test_newerXY_base "c" "t"
6631
6632         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6633            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6634                 ! btime_supported && echo "btime unsupported" && return 0
6635
6636         test_newerXY_base "b" "b"
6637         test_newerXY_base "b" "t"
6638 }
6639 run_test 56oc "check lfs find -newerXY work"
6640
6641 btime_supported() {
6642         local dir=$DIR/$tdir
6643         local rc
6644
6645         mkdir -p $dir
6646         touch $dir/$tfile
6647         $LFS find $dir -btime -1d -type f
6648         rc=$?
6649         rm -rf $dir
6650         return $rc
6651 }
6652
6653 test_56od() {
6654         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6655                 ! btime_supported && skip "btime unsupported on MDS"
6656
6657         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6658                 ! btime_supported && skip "btime unsupported on clients"
6659
6660         local dir=$DIR/$tdir
6661         local ref=$DIR/$tfile.ref
6662         local negref=$DIR/$tfile.negref
6663
6664         mkdir $dir || error "mkdir $dir failed"
6665         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6666         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6667         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6668         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6669         touch $ref || error "touch $ref failed"
6670         # sleep 3 seconds at least
6671         sleep 3
6672
6673         local before=$(do_facet mds1 date +%s)
6674         local skew=$(($(date +%s) - before + 1))
6675
6676         if (( skew < 0 && skew > -5 )); then
6677                 sleep $((0 - skew + 1))
6678                 skew=0
6679         fi
6680
6681         # Set the dir stripe params to limit files all on MDT0,
6682         # otherwise we need to calc the max clock skew between
6683         # the client and MDTs.
6684         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6685         sleep 2
6686         touch $negref || error "touch $negref failed"
6687
6688         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6689         local nums=$($cmd | wc -l)
6690         local expected=$(((NUMFILES + 1) * NUMDIRS))
6691
6692         [ $nums -eq $expected ] ||
6693                 error "'$cmd' wrong: found $nums, expected $expected"
6694
6695         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6696         nums=$($cmd | wc -l)
6697         expected=$((NUMFILES + 1))
6698         [ $nums -eq $expected ] ||
6699                 error "'$cmd' wrong: found $nums, expected $expected"
6700
6701         [ $skew -lt 0 ] && return
6702
6703         local after=$(do_facet mds1 date +%s)
6704         local age=$((after - before + 1 + skew))
6705
6706         cmd="$LFS find $dir -btime -${age}s -type f"
6707         nums=$($cmd | wc -l)
6708         expected=$(((NUMFILES + 1) * NUMDIRS))
6709
6710         echo "Clock skew between client and server: $skew, age:$age"
6711         [ $nums -eq $expected ] ||
6712                 error "'$cmd' wrong: found $nums, expected $expected"
6713
6714         expected=$(($NUMDIRS + 1))
6715         cmd="$LFS find $dir -btime -${age}s -type d"
6716         nums=$($cmd | wc -l)
6717         [ $nums -eq $expected ] ||
6718                 error "'$cmd' wrong: found $nums, expected $expected"
6719         rm -f $ref $negref || error "Failed to remove $ref $negref"
6720 }
6721 run_test 56od "check lfs find -btime with units"
6722
6723 test_56p() {
6724         [ $RUNAS_ID -eq $UID ] &&
6725                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6726
6727         local dir=$DIR/$tdir
6728
6729         setup_56 $dir $NUMFILES $NUMDIRS
6730         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6731
6732         local expected=$NUMFILES
6733         local cmd="$LFS find -uid $RUNAS_ID $dir"
6734         local nums=$($cmd | wc -l)
6735
6736         [ $nums -eq $expected ] ||
6737                 error "'$cmd' wrong: found $nums, expected $expected"
6738
6739         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6740         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6741         nums=$($cmd | wc -l)
6742         [ $nums -eq $expected ] ||
6743                 error "'$cmd' wrong: found $nums, expected $expected"
6744 }
6745 run_test 56p "check lfs find -uid and ! -uid"
6746
6747 test_56q() {
6748         [ $RUNAS_ID -eq $UID ] &&
6749                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6750
6751         local dir=$DIR/$tdir
6752
6753         setup_56 $dir $NUMFILES $NUMDIRS
6754         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6755
6756         local expected=$NUMFILES
6757         local cmd="$LFS find -gid $RUNAS_GID $dir"
6758         local nums=$($cmd | wc -l)
6759
6760         [ $nums -eq $expected ] ||
6761                 error "'$cmd' wrong: found $nums, expected $expected"
6762
6763         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6764         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6765         nums=$($cmd | wc -l)
6766         [ $nums -eq $expected ] ||
6767                 error "'$cmd' wrong: found $nums, expected $expected"
6768 }
6769 run_test 56q "check lfs find -gid and ! -gid"
6770
6771 test_56r() {
6772         local dir=$DIR/$tdir
6773
6774         setup_56 $dir $NUMFILES $NUMDIRS
6775
6776         local expected=12
6777         local cmd="$LFS find -size 0 -type f -lazy $dir"
6778         local nums=$($cmd | wc -l)
6779
6780         [ $nums -eq $expected ] ||
6781                 error "'$cmd' wrong: found $nums, expected $expected"
6782         cmd="$LFS find -size 0 -type f $dir"
6783         nums=$($cmd | wc -l)
6784         [ $nums -eq $expected ] ||
6785                 error "'$cmd' wrong: found $nums, expected $expected"
6786
6787         expected=0
6788         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6789         nums=$($cmd | wc -l)
6790         [ $nums -eq $expected ] ||
6791                 error "'$cmd' wrong: found $nums, expected $expected"
6792         cmd="$LFS find ! -size 0 -type f $dir"
6793         nums=$($cmd | wc -l)
6794         [ $nums -eq $expected ] ||
6795                 error "'$cmd' wrong: found $nums, expected $expected"
6796
6797         echo "test" > $dir/$tfile
6798         echo "test2" > $dir/$tfile.2 && sync
6799         expected=1
6800         cmd="$LFS find -size 5 -type f -lazy $dir"
6801         nums=$($cmd | wc -l)
6802         [ $nums -eq $expected ] ||
6803                 error "'$cmd' wrong: found $nums, expected $expected"
6804         cmd="$LFS find -size 5 -type f $dir"
6805         nums=$($cmd | wc -l)
6806         [ $nums -eq $expected ] ||
6807                 error "'$cmd' wrong: found $nums, expected $expected"
6808
6809         expected=1
6810         cmd="$LFS find -size +5 -type f -lazy $dir"
6811         nums=$($cmd | wc -l)
6812         [ $nums -eq $expected ] ||
6813                 error "'$cmd' wrong: found $nums, expected $expected"
6814         cmd="$LFS find -size +5 -type f $dir"
6815         nums=$($cmd | wc -l)
6816         [ $nums -eq $expected ] ||
6817                 error "'$cmd' wrong: found $nums, expected $expected"
6818
6819         expected=2
6820         cmd="$LFS find -size +0 -type f -lazy $dir"
6821         nums=$($cmd | wc -l)
6822         [ $nums -eq $expected ] ||
6823                 error "'$cmd' wrong: found $nums, expected $expected"
6824         cmd="$LFS find -size +0 -type f $dir"
6825         nums=$($cmd | wc -l)
6826         [ $nums -eq $expected ] ||
6827                 error "'$cmd' wrong: found $nums, expected $expected"
6828
6829         expected=2
6830         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6831         nums=$($cmd | wc -l)
6832         [ $nums -eq $expected ] ||
6833                 error "'$cmd' wrong: found $nums, expected $expected"
6834         cmd="$LFS find ! -size -5 -type f $dir"
6835         nums=$($cmd | wc -l)
6836         [ $nums -eq $expected ] ||
6837                 error "'$cmd' wrong: found $nums, expected $expected"
6838
6839         expected=12
6840         cmd="$LFS find -size -5 -type f -lazy $dir"
6841         nums=$($cmd | wc -l)
6842         [ $nums -eq $expected ] ||
6843                 error "'$cmd' wrong: found $nums, expected $expected"
6844         cmd="$LFS find -size -5 -type f $dir"
6845         nums=$($cmd | wc -l)
6846         [ $nums -eq $expected ] ||
6847                 error "'$cmd' wrong: found $nums, expected $expected"
6848 }
6849 run_test 56r "check lfs find -size works"
6850
6851 test_56ra_sub() {
6852         local expected=$1
6853         local glimpses=$2
6854         local cmd="$3"
6855
6856         cancel_lru_locks $OSC
6857
6858         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6859         local nums=$($cmd | wc -l)
6860
6861         [ $nums -eq $expected ] ||
6862                 error "'$cmd' wrong: found $nums, expected $expected"
6863
6864         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6865
6866         if (( rpcs_before + glimpses != rpcs_after )); then
6867                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6868                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6869
6870                 if [[ $glimpses == 0 ]]; then
6871                         error "'$cmd' should not send glimpse RPCs to OST"
6872                 else
6873                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6874                 fi
6875         fi
6876 }
6877
6878 test_56ra() {
6879         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6880                 skip "MDS < 2.12.58 doesn't return LSOM data"
6881         local dir=$DIR/$tdir
6882         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6883
6884         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6885
6886         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6887         $LCTL set_param -n llite.*.statahead_agl=0
6888         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6889
6890         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6891         # open and close all files to ensure LSOM is updated
6892         cancel_lru_locks $OSC
6893         find $dir -type f | xargs cat > /dev/null
6894
6895         #   expect_found  glimpse_rpcs  command_to_run
6896         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6897         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6898         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6899         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6900
6901         echo "test" > $dir/$tfile
6902         echo "test2" > $dir/$tfile.2 && sync
6903         cancel_lru_locks $OSC
6904         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6905
6906         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6907         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6908         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6909         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6910
6911         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6912         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6913         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6914         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6915         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6916         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6917 }
6918 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6919
6920 test_56rb() {
6921         local dir=$DIR/$tdir
6922         local tmp=$TMP/$tfile.log
6923         local mdt_idx;
6924
6925         test_mkdir -p $dir || error "failed to mkdir $dir"
6926         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6927                 error "failed to setstripe $dir/$tfile"
6928         mdt_idx=$($LFS getdirstripe -i $dir)
6929         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6930
6931         stack_trap "rm -f $tmp" EXIT
6932         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6933         ! grep -q obd_uuid $tmp ||
6934                 error "failed to find --size +100K --ost 0 $dir"
6935         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6936         ! grep -q obd_uuid $tmp ||
6937                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6938 }
6939 run_test 56rb "check lfs find --size --ost/--mdt works"
6940
6941 test_56rc() {
6942         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6943         local dir=$DIR/$tdir
6944         local found
6945
6946         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6947         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6948         (( $MDSCOUNT > 2 )) &&
6949                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6950         mkdir $dir/$tdir-{1..10}
6951         touch $dir/$tfile-{1..10}
6952
6953         found=$($LFS find $dir --mdt-count 2 | wc -l)
6954         expect=11
6955         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6956
6957         found=$($LFS find $dir -T +1 | wc -l)
6958         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6959         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6960
6961         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6962         expect=11
6963         (( $found == $expect )) || error "found $found all_char, expect $expect"
6964
6965         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
6966         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
6967         (( $found == $expect )) || error "found $found all_char, expect $expect"
6968 }
6969 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
6970
6971 test_56s() { # LU-611 #LU-9369
6972         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6973
6974         local dir=$DIR/$tdir
6975         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6976
6977         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6978         for i in $(seq $NUMDIRS); do
6979                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6980         done
6981
6982         local expected=$NUMDIRS
6983         local cmd="$LFS find -c $OSTCOUNT $dir"
6984         local nums=$($cmd | wc -l)
6985
6986         [ $nums -eq $expected ] || {
6987                 $LFS getstripe -R $dir
6988                 error "'$cmd' wrong: found $nums, expected $expected"
6989         }
6990
6991         expected=$((NUMDIRS + onestripe))
6992         cmd="$LFS find -stripe-count +0 -type f $dir"
6993         nums=$($cmd | wc -l)
6994         [ $nums -eq $expected ] || {
6995                 $LFS getstripe -R $dir
6996                 error "'$cmd' wrong: found $nums, expected $expected"
6997         }
6998
6999         expected=$onestripe
7000         cmd="$LFS find -stripe-count 1 -type f $dir"
7001         nums=$($cmd | wc -l)
7002         [ $nums -eq $expected ] || {
7003                 $LFS getstripe -R $dir
7004                 error "'$cmd' wrong: found $nums, expected $expected"
7005         }
7006
7007         cmd="$LFS find -stripe-count -2 -type f $dir"
7008         nums=$($cmd | wc -l)
7009         [ $nums -eq $expected ] || {
7010                 $LFS getstripe -R $dir
7011                 error "'$cmd' wrong: found $nums, expected $expected"
7012         }
7013
7014         expected=0
7015         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7016         nums=$($cmd | wc -l)
7017         [ $nums -eq $expected ] || {
7018                 $LFS getstripe -R $dir
7019                 error "'$cmd' wrong: found $nums, expected $expected"
7020         }
7021 }
7022 run_test 56s "check lfs find -stripe-count works"
7023
7024 test_56t() { # LU-611 #LU-9369
7025         local dir=$DIR/$tdir
7026
7027         setup_56 $dir 0 $NUMDIRS
7028         for i in $(seq $NUMDIRS); do
7029                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7030         done
7031
7032         local expected=$NUMDIRS
7033         local cmd="$LFS find -S 8M $dir"
7034         local nums=$($cmd | wc -l)
7035
7036         [ $nums -eq $expected ] || {
7037                 $LFS getstripe -R $dir
7038                 error "'$cmd' wrong: found $nums, expected $expected"
7039         }
7040         rm -rf $dir
7041
7042         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7043
7044         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7045
7046         expected=$(((NUMDIRS + 1) * NUMFILES))
7047         cmd="$LFS find -stripe-size 512k -type f $dir"
7048         nums=$($cmd | wc -l)
7049         [ $nums -eq $expected ] ||
7050                 error "'$cmd' wrong: found $nums, expected $expected"
7051
7052         cmd="$LFS find -stripe-size +320k -type f $dir"
7053         nums=$($cmd | wc -l)
7054         [ $nums -eq $expected ] ||
7055                 error "'$cmd' wrong: found $nums, expected $expected"
7056
7057         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7058         cmd="$LFS find -stripe-size +200k -type f $dir"
7059         nums=$($cmd | wc -l)
7060         [ $nums -eq $expected ] ||
7061                 error "'$cmd' wrong: found $nums, expected $expected"
7062
7063         cmd="$LFS find -stripe-size -640k -type f $dir"
7064         nums=$($cmd | wc -l)
7065         [ $nums -eq $expected ] ||
7066                 error "'$cmd' wrong: found $nums, expected $expected"
7067
7068         expected=4
7069         cmd="$LFS find -stripe-size 256k -type f $dir"
7070         nums=$($cmd | wc -l)
7071         [ $nums -eq $expected ] ||
7072                 error "'$cmd' wrong: found $nums, expected $expected"
7073
7074         cmd="$LFS find -stripe-size -320k -type f $dir"
7075         nums=$($cmd | wc -l)
7076         [ $nums -eq $expected ] ||
7077                 error "'$cmd' wrong: found $nums, expected $expected"
7078
7079         expected=0
7080         cmd="$LFS find -stripe-size 1024k -type f $dir"
7081         nums=$($cmd | wc -l)
7082         [ $nums -eq $expected ] ||
7083                 error "'$cmd' wrong: found $nums, expected $expected"
7084 }
7085 run_test 56t "check lfs find -stripe-size works"
7086
7087 test_56u() { # LU-611
7088         local dir=$DIR/$tdir
7089
7090         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7091
7092         if [[ $OSTCOUNT -gt 1 ]]; then
7093                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7094                 onestripe=4
7095         else
7096                 onestripe=0
7097         fi
7098
7099         local expected=$(((NUMDIRS + 1) * NUMFILES))
7100         local cmd="$LFS find -stripe-index 0 -type f $dir"
7101         local nums=$($cmd | wc -l)
7102
7103         [ $nums -eq $expected ] ||
7104                 error "'$cmd' wrong: found $nums, expected $expected"
7105
7106         expected=$onestripe
7107         cmd="$LFS find -stripe-index 1 -type f $dir"
7108         nums=$($cmd | wc -l)
7109         [ $nums -eq $expected ] ||
7110                 error "'$cmd' wrong: found $nums, expected $expected"
7111
7112         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7113         nums=$($cmd | wc -l)
7114         [ $nums -eq $expected ] ||
7115                 error "'$cmd' wrong: found $nums, expected $expected"
7116
7117         expected=0
7118         # This should produce an error and not return any files
7119         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7120         nums=$($cmd 2>/dev/null | wc -l)
7121         [ $nums -eq $expected ] ||
7122                 error "'$cmd' wrong: found $nums, expected $expected"
7123
7124         if [[ $OSTCOUNT -gt 1 ]]; then
7125                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7126                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7127                 nums=$($cmd | wc -l)
7128                 [ $nums -eq $expected ] ||
7129                         error "'$cmd' wrong: found $nums, expected $expected"
7130         fi
7131 }
7132 run_test 56u "check lfs find -stripe-index works"
7133
7134 test_56v() {
7135         local mdt_idx=0
7136         local dir=$DIR/$tdir
7137
7138         setup_56 $dir $NUMFILES $NUMDIRS
7139
7140         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7141         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7142
7143         for file in $($LFS find -m $UUID $dir); do
7144                 file_midx=$($LFS getstripe -m $file)
7145                 [ $file_midx -eq $mdt_idx ] ||
7146                         error "lfs find -m $UUID != getstripe -m $file_midx"
7147         done
7148 }
7149 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7150
7151 test_56w() {
7152         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7154
7155         local dir=$DIR/$tdir
7156
7157         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7158
7159         local stripe_size=$($LFS getstripe -S -d $dir) ||
7160                 error "$LFS getstripe -S -d $dir failed"
7161         stripe_size=${stripe_size%% *}
7162
7163         local file_size=$((stripe_size * OSTCOUNT))
7164         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7165         local required_space=$((file_num * file_size))
7166         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7167                            head -n1)
7168         [[ $free_space -le $((required_space / 1024)) ]] &&
7169                 skip_env "need $required_space, have $free_space kbytes"
7170
7171         local dd_bs=65536
7172         local dd_count=$((file_size / dd_bs))
7173
7174         # write data into the files
7175         local i
7176         local j
7177         local file
7178
7179         for i in $(seq $NUMFILES); do
7180                 file=$dir/file$i
7181                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7182                         error "write data into $file failed"
7183         done
7184         for i in $(seq $NUMDIRS); do
7185                 for j in $(seq $NUMFILES); do
7186                         file=$dir/dir$i/file$j
7187                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7188                                 error "write data into $file failed"
7189                 done
7190         done
7191
7192         # $LFS_MIGRATE will fail if hard link migration is unsupported
7193         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7194                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7195                         error "creating links to $dir/dir1/file1 failed"
7196         fi
7197
7198         local expected=-1
7199
7200         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7201
7202         # lfs_migrate file
7203         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7204
7205         echo "$cmd"
7206         eval $cmd || error "$cmd failed"
7207
7208         check_stripe_count $dir/file1 $expected
7209
7210         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7211         then
7212                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7213                 # OST 1 if it is on OST 0. This file is small enough to
7214                 # be on only one stripe.
7215                 file=$dir/migr_1_ost
7216                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7217                         error "write data into $file failed"
7218                 local obdidx=$($LFS getstripe -i $file)
7219                 local oldmd5=$(md5sum $file)
7220                 local newobdidx=0
7221
7222                 [[ $obdidx -eq 0 ]] && newobdidx=1
7223                 cmd="$LFS migrate -i $newobdidx $file"
7224                 echo $cmd
7225                 eval $cmd || error "$cmd failed"
7226
7227                 local realobdix=$($LFS getstripe -i $file)
7228                 local newmd5=$(md5sum $file)
7229
7230                 [[ $newobdidx -ne $realobdix ]] &&
7231                         error "new OST is different (was=$obdidx, "\
7232                               "wanted=$newobdidx, got=$realobdix)"
7233                 [[ "$oldmd5" != "$newmd5" ]] &&
7234                         error "md5sum differ: $oldmd5, $newmd5"
7235         fi
7236
7237         # lfs_migrate dir
7238         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7239         echo "$cmd"
7240         eval $cmd || error "$cmd failed"
7241
7242         for j in $(seq $NUMFILES); do
7243                 check_stripe_count $dir/dir1/file$j $expected
7244         done
7245
7246         # lfs_migrate works with lfs find
7247         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7248              $LFS_MIGRATE -y -c $expected"
7249         echo "$cmd"
7250         eval $cmd || error "$cmd failed"
7251
7252         for i in $(seq 2 $NUMFILES); do
7253                 check_stripe_count $dir/file$i $expected
7254         done
7255         for i in $(seq 2 $NUMDIRS); do
7256                 for j in $(seq $NUMFILES); do
7257                 check_stripe_count $dir/dir$i/file$j $expected
7258                 done
7259         done
7260 }
7261 run_test 56w "check lfs_migrate -c stripe_count works"
7262
7263 test_56wb() {
7264         local file1=$DIR/$tdir/file1
7265         local create_pool=false
7266         local initial_pool=$($LFS getstripe -p $DIR)
7267         local pool_list=()
7268         local pool=""
7269
7270         echo -n "Creating test dir..."
7271         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7272         echo "done."
7273
7274         echo -n "Creating test file..."
7275         touch $file1 || error "cannot create file"
7276         echo "done."
7277
7278         echo -n "Detecting existing pools..."
7279         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7280
7281         if [ ${#pool_list[@]} -gt 0 ]; then
7282                 echo "${pool_list[@]}"
7283                 for thispool in "${pool_list[@]}"; do
7284                         if [[ -z "$initial_pool" ||
7285                               "$initial_pool" != "$thispool" ]]; then
7286                                 pool="$thispool"
7287                                 echo "Using existing pool '$pool'"
7288                                 break
7289                         fi
7290                 done
7291         else
7292                 echo "none detected."
7293         fi
7294         if [ -z "$pool" ]; then
7295                 pool=${POOL:-testpool}
7296                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7297                 echo -n "Creating pool '$pool'..."
7298                 create_pool=true
7299                 pool_add $pool &> /dev/null ||
7300                         error "pool_add failed"
7301                 echo "done."
7302
7303                 echo -n "Adding target to pool..."
7304                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7305                         error "pool_add_targets failed"
7306                 echo "done."
7307         fi
7308
7309         echo -n "Setting pool using -p option..."
7310         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7311                 error "migrate failed rc = $?"
7312         echo "done."
7313
7314         echo -n "Verifying test file is in pool after migrating..."
7315         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7316                 error "file was not migrated to pool $pool"
7317         echo "done."
7318
7319         echo -n "Removing test file from pool '$pool'..."
7320         # "lfs migrate $file" won't remove the file from the pool
7321         # until some striping information is changed.
7322         $LFS migrate -c 1 $file1 &> /dev/null ||
7323                 error "cannot remove from pool"
7324         [ "$($LFS getstripe -p $file1)" ] &&
7325                 error "pool still set"
7326         echo "done."
7327
7328         echo -n "Setting pool using --pool option..."
7329         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7330                 error "migrate failed rc = $?"
7331         echo "done."
7332
7333         # Clean up
7334         rm -f $file1
7335         if $create_pool; then
7336                 destroy_test_pools 2> /dev/null ||
7337                         error "destroy test pools failed"
7338         fi
7339 }
7340 run_test 56wb "check lfs_migrate pool support"
7341
7342 test_56wc() {
7343         local file1="$DIR/$tdir/file1"
7344         local parent_ssize
7345         local parent_scount
7346         local cur_ssize
7347         local cur_scount
7348         local orig_ssize
7349
7350         echo -n "Creating test dir..."
7351         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7352         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7353                 error "cannot set stripe by '-S 1M -c 1'"
7354         echo "done"
7355
7356         echo -n "Setting initial stripe for test file..."
7357         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7358                 error "cannot set stripe"
7359         cur_ssize=$($LFS getstripe -S "$file1")
7360         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7361         echo "done."
7362
7363         # File currently set to -S 512K -c 1
7364
7365         # Ensure -c and -S options are rejected when -R is set
7366         echo -n "Verifying incompatible options are detected..."
7367         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7368                 error "incompatible -c and -R options not detected"
7369         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7370                 error "incompatible -S and -R options not detected"
7371         echo "done."
7372
7373         # Ensure unrecognized options are passed through to 'lfs migrate'
7374         echo -n "Verifying -S option is passed through to lfs migrate..."
7375         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7376                 error "migration failed"
7377         cur_ssize=$($LFS getstripe -S "$file1")
7378         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7379         echo "done."
7380
7381         # File currently set to -S 1M -c 1
7382
7383         # Ensure long options are supported
7384         echo -n "Verifying long options supported..."
7385         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7386                 error "long option without argument not supported"
7387         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7388                 error "long option with argument not supported"
7389         cur_ssize=$($LFS getstripe -S "$file1")
7390         [ $cur_ssize -eq 524288 ] ||
7391                 error "migrate --stripe-size $cur_ssize != 524288"
7392         echo "done."
7393
7394         # File currently set to -S 512K -c 1
7395
7396         if [ "$OSTCOUNT" -gt 1 ]; then
7397                 echo -n "Verifying explicit stripe count can be set..."
7398                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7399                         error "migrate failed"
7400                 cur_scount=$($LFS getstripe -c "$file1")
7401                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7402                 echo "done."
7403         fi
7404
7405         # File currently set to -S 512K -c 1 or -S 512K -c 2
7406
7407         # Ensure parent striping is used if -R is set, and no stripe
7408         # count or size is specified
7409         echo -n "Setting stripe for parent directory..."
7410         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7411                 error "cannot set stripe '-S 2M -c 1'"
7412         echo "done."
7413
7414         echo -n "Verifying restripe option uses parent stripe settings..."
7415         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7416         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7417         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7418                 error "migrate failed"
7419         cur_ssize=$($LFS getstripe -S "$file1")
7420         [ $cur_ssize -eq $parent_ssize ] ||
7421                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7422         cur_scount=$($LFS getstripe -c "$file1")
7423         [ $cur_scount -eq $parent_scount ] ||
7424                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7425         echo "done."
7426
7427         # File currently set to -S 1M -c 1
7428
7429         # Ensure striping is preserved if -R is not set, and no stripe
7430         # count or size is specified
7431         echo -n "Verifying striping size preserved when not specified..."
7432         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7433         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7434                 error "cannot set stripe on parent directory"
7435         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7436                 error "migrate failed"
7437         cur_ssize=$($LFS getstripe -S "$file1")
7438         [ $cur_ssize -eq $orig_ssize ] ||
7439                 error "migrate by default $cur_ssize != $orig_ssize"
7440         echo "done."
7441
7442         # Ensure file name properly detected when final option has no argument
7443         echo -n "Verifying file name properly detected..."
7444         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7445                 error "file name interpreted as option argument"
7446         echo "done."
7447
7448         # Clean up
7449         rm -f "$file1"
7450 }
7451 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7452
7453 test_56wd() {
7454         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7455
7456         local file1=$DIR/$tdir/file1
7457
7458         echo -n "Creating test dir..."
7459         test_mkdir $DIR/$tdir || error "cannot create dir"
7460         echo "done."
7461
7462         echo -n "Creating test file..."
7463         touch $file1
7464         echo "done."
7465
7466         # Ensure 'lfs migrate' will fail by using a non-existent option,
7467         # and make sure rsync is not called to recover
7468         echo -n "Make sure --no-rsync option works..."
7469         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7470                 grep -q 'refusing to fall back to rsync' ||
7471                 error "rsync was called with --no-rsync set"
7472         echo "done."
7473
7474         # Ensure rsync is called without trying 'lfs migrate' first
7475         echo -n "Make sure --rsync option works..."
7476         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7477                 grep -q 'falling back to rsync' &&
7478                 error "lfs migrate was called with --rsync set"
7479         echo "done."
7480
7481         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7482         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7483                 grep -q 'at the same time' ||
7484                 error "--rsync and --no-rsync accepted concurrently"
7485         echo "done."
7486
7487         # Clean up
7488         rm -f $file1
7489 }
7490 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7491
7492 test_56we() {
7493         local td=$DIR/$tdir
7494         local tf=$td/$tfile
7495
7496         test_mkdir $td || error "cannot create $td"
7497         touch $tf || error "cannot touch $tf"
7498
7499         echo -n "Make sure --non-direct|-D works..."
7500         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7501                 grep -q "lfs migrate --non-direct" ||
7502                 error "--non-direct option cannot work correctly"
7503         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7504                 grep -q "lfs migrate -D" ||
7505                 error "-D option cannot work correctly"
7506         echo "done."
7507 }
7508 run_test 56we "check lfs_migrate --non-direct|-D support"
7509
7510 test_56x() {
7511         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7512         check_swap_layouts_support
7513
7514         local dir=$DIR/$tdir
7515         local ref1=/etc/passwd
7516         local file1=$dir/file1
7517
7518         test_mkdir $dir || error "creating dir $dir"
7519         $LFS setstripe -c 2 $file1
7520         cp $ref1 $file1
7521         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7522         stripe=$($LFS getstripe -c $file1)
7523         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7524         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7525
7526         # clean up
7527         rm -f $file1
7528 }
7529 run_test 56x "lfs migration support"
7530
7531 test_56xa() {
7532         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7533         check_swap_layouts_support
7534
7535         local dir=$DIR/$tdir/$testnum
7536
7537         test_mkdir -p $dir
7538
7539         local ref1=/etc/passwd
7540         local file1=$dir/file1
7541
7542         $LFS setstripe -c 2 $file1
7543         cp $ref1 $file1
7544         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7545
7546         local stripe=$($LFS getstripe -c $file1)
7547
7548         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7549         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7550
7551         # clean up
7552         rm -f $file1
7553 }
7554 run_test 56xa "lfs migration --block support"
7555
7556 check_migrate_links() {
7557         local dir="$1"
7558         local file1="$dir/file1"
7559         local begin="$2"
7560         local count="$3"
7561         local runas="$4"
7562         local total_count=$(($begin + $count - 1))
7563         local symlink_count=10
7564         local uniq_count=10
7565
7566         if [ ! -f "$file1" ]; then
7567                 echo -n "creating initial file..."
7568                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7569                         error "cannot setstripe initial file"
7570                 echo "done"
7571
7572                 echo -n "creating symlinks..."
7573                 for s in $(seq 1 $symlink_count); do
7574                         ln -s "$file1" "$dir/slink$s" ||
7575                                 error "cannot create symlinks"
7576                 done
7577                 echo "done"
7578
7579                 echo -n "creating nonlinked files..."
7580                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7581                         error "cannot create nonlinked files"
7582                 echo "done"
7583         fi
7584
7585         # create hard links
7586         if [ ! -f "$dir/file$total_count" ]; then
7587                 echo -n "creating hard links $begin:$total_count..."
7588                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7589                         /dev/null || error "cannot create hard links"
7590                 echo "done"
7591         fi
7592
7593         echo -n "checking number of hard links listed in xattrs..."
7594         local fid=$($LFS getstripe -F "$file1")
7595         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7596
7597         echo "${#paths[*]}"
7598         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7599                         skip "hard link list has unexpected size, skipping test"
7600         fi
7601         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7602                         error "link names should exceed xattrs size"
7603         fi
7604
7605         echo -n "migrating files..."
7606         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7607         local rc=$?
7608         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7609         echo "done"
7610
7611         # make sure all links have been properly migrated
7612         echo -n "verifying files..."
7613         fid=$($LFS getstripe -F "$file1") ||
7614                 error "cannot get fid for file $file1"
7615         for i in $(seq 2 $total_count); do
7616                 local fid2=$($LFS getstripe -F $dir/file$i)
7617
7618                 [ "$fid2" == "$fid" ] ||
7619                         error "migrated hard link has mismatched FID"
7620         done
7621
7622         # make sure hard links were properly detected, and migration was
7623         # performed only once for the entire link set; nonlinked files should
7624         # also be migrated
7625         local actual=$(grep -c 'done' <<< "$migrate_out")
7626         local expected=$(($uniq_count + 1))
7627
7628         [ "$actual" -eq  "$expected" ] ||
7629                 error "hard links individually migrated ($actual != $expected)"
7630
7631         # make sure the correct number of hard links are present
7632         local hardlinks=$(stat -c '%h' "$file1")
7633
7634         [ $hardlinks -eq $total_count ] ||
7635                 error "num hard links $hardlinks != $total_count"
7636         echo "done"
7637
7638         return 0
7639 }
7640
7641 test_56xb() {
7642         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7643                 skip "Need MDS version at least 2.10.55"
7644
7645         local dir="$DIR/$tdir"
7646
7647         test_mkdir "$dir" || error "cannot create dir $dir"
7648
7649         echo "testing lfs migrate mode when all links fit within xattrs"
7650         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7651
7652         echo "testing rsync mode when all links fit within xattrs"
7653         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7654
7655         echo "testing lfs migrate mode when all links do not fit within xattrs"
7656         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7657
7658         echo "testing rsync mode when all links do not fit within xattrs"
7659         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7660
7661         chown -R $RUNAS_ID $dir
7662         echo "testing non-root lfs migrate mode when not all links are in xattr"
7663         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7664
7665         # clean up
7666         rm -rf $dir
7667 }
7668 run_test 56xb "lfs migration hard link support"
7669
7670 test_56xc() {
7671         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7672
7673         local dir="$DIR/$tdir"
7674
7675         test_mkdir "$dir" || error "cannot create dir $dir"
7676
7677         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7678         echo -n "Setting initial stripe for 20MB test file..."
7679         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7680                 error "cannot setstripe 20MB file"
7681         echo "done"
7682         echo -n "Sizing 20MB test file..."
7683         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7684         echo "done"
7685         echo -n "Verifying small file autostripe count is 1..."
7686         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7687                 error "cannot migrate 20MB file"
7688         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7689                 error "cannot get stripe for $dir/20mb"
7690         [ $stripe_count -eq 1 ] ||
7691                 error "unexpected stripe count $stripe_count for 20MB file"
7692         rm -f "$dir/20mb"
7693         echo "done"
7694
7695         # Test 2: File is small enough to fit within the available space on
7696         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7697         # have at least an additional 1KB for each desired stripe for test 3
7698         echo -n "Setting stripe for 1GB test file..."
7699         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7700         echo "done"
7701         echo -n "Sizing 1GB test file..."
7702         # File size is 1GB + 3KB
7703         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7704         echo "done"
7705
7706         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7707         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7708         if (( avail > 524288 * OSTCOUNT )); then
7709                 echo -n "Migrating 1GB file..."
7710                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7711                         error "cannot migrate 1GB file"
7712                 echo "done"
7713                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7714                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7715                         error "cannot getstripe for 1GB file"
7716                 [ $stripe_count -eq 2 ] ||
7717                         error "unexpected stripe count $stripe_count != 2"
7718                 echo "done"
7719         fi
7720
7721         # Test 3: File is too large to fit within the available space on
7722         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7723         if [ $OSTCOUNT -ge 3 ]; then
7724                 # The required available space is calculated as
7725                 # file size (1GB + 3KB) / OST count (3).
7726                 local kb_per_ost=349526
7727
7728                 echo -n "Migrating 1GB file with limit..."
7729                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7730                         error "cannot migrate 1GB file with limit"
7731                 echo "done"
7732
7733                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7734                 echo -n "Verifying 1GB autostripe count with limited space..."
7735                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7736                         error "unexpected stripe count $stripe_count (min 3)"
7737                 echo "done"
7738         fi
7739
7740         # clean up
7741         rm -rf $dir
7742 }
7743 run_test 56xc "lfs migration autostripe"
7744
7745 test_56xd() {
7746         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7747
7748         local dir=$DIR/$tdir
7749         local f_mgrt=$dir/$tfile.mgrt
7750         local f_yaml=$dir/$tfile.yaml
7751         local f_copy=$dir/$tfile.copy
7752         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7753         local layout_copy="-c 2 -S 2M -i 1"
7754         local yamlfile=$dir/yamlfile
7755         local layout_before;
7756         local layout_after;
7757
7758         test_mkdir "$dir" || error "cannot create dir $dir"
7759         $LFS setstripe $layout_yaml $f_yaml ||
7760                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7761         $LFS getstripe --yaml $f_yaml > $yamlfile
7762         $LFS setstripe $layout_copy $f_copy ||
7763                 error "cannot setstripe $f_copy with layout $layout_copy"
7764         touch $f_mgrt
7765         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7766
7767         # 1. test option --yaml
7768         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7769                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7770         layout_before=$(get_layout_param $f_yaml)
7771         layout_after=$(get_layout_param $f_mgrt)
7772         [ "$layout_after" == "$layout_before" ] ||
7773                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7774
7775         # 2. test option --copy
7776         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7777                 error "cannot migrate $f_mgrt with --copy $f_copy"
7778         layout_before=$(get_layout_param $f_copy)
7779         layout_after=$(get_layout_param $f_mgrt)
7780         [ "$layout_after" == "$layout_before" ] ||
7781                 error "lfs_migrate --copy: $layout_after != $layout_before"
7782 }
7783 run_test 56xd "check lfs_migrate --yaml and --copy support"
7784
7785 test_56xe() {
7786         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7787
7788         local dir=$DIR/$tdir
7789         local f_comp=$dir/$tfile
7790         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7791         local layout_before=""
7792         local layout_after=""
7793
7794         test_mkdir "$dir" || error "cannot create dir $dir"
7795         $LFS setstripe $layout $f_comp ||
7796                 error "cannot setstripe $f_comp with layout $layout"
7797         layout_before=$(get_layout_param $f_comp)
7798         dd if=/dev/zero of=$f_comp bs=1M count=4
7799
7800         # 1. migrate a comp layout file by lfs_migrate
7801         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7802         layout_after=$(get_layout_param $f_comp)
7803         [ "$layout_before" == "$layout_after" ] ||
7804                 error "lfs_migrate: $layout_before != $layout_after"
7805
7806         # 2. migrate a comp layout file by lfs migrate
7807         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7808         layout_after=$(get_layout_param $f_comp)
7809         [ "$layout_before" == "$layout_after" ] ||
7810                 error "lfs migrate: $layout_before != $layout_after"
7811 }
7812 run_test 56xe "migrate a composite layout file"
7813
7814 test_56xf() {
7815         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7816
7817         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7818                 skip "Need server version at least 2.13.53"
7819
7820         local dir=$DIR/$tdir
7821         local f_comp=$dir/$tfile
7822         local layout="-E 1M -c1 -E -1 -c2"
7823         local fid_before=""
7824         local fid_after=""
7825
7826         test_mkdir "$dir" || error "cannot create dir $dir"
7827         $LFS setstripe $layout $f_comp ||
7828                 error "cannot setstripe $f_comp with layout $layout"
7829         fid_before=$($LFS getstripe --fid $f_comp)
7830         dd if=/dev/zero of=$f_comp bs=1M count=4
7831
7832         # 1. migrate a comp layout file to a comp layout
7833         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7834         fid_after=$($LFS getstripe --fid $f_comp)
7835         [ "$fid_before" == "$fid_after" ] ||
7836                 error "comp-to-comp migrate: $fid_before != $fid_after"
7837
7838         # 2. migrate a comp layout file to a plain layout
7839         $LFS migrate -c2 $f_comp ||
7840                 error "cannot migrate $f_comp by lfs migrate"
7841         fid_after=$($LFS getstripe --fid $f_comp)
7842         [ "$fid_before" == "$fid_after" ] ||
7843                 error "comp-to-plain migrate: $fid_before != $fid_after"
7844
7845         # 3. migrate a plain layout file to a comp layout
7846         $LFS migrate $layout $f_comp ||
7847                 error "cannot migrate $f_comp by lfs migrate"
7848         fid_after=$($LFS getstripe --fid $f_comp)
7849         [ "$fid_before" == "$fid_after" ] ||
7850                 error "plain-to-comp migrate: $fid_before != $fid_after"
7851 }
7852 run_test 56xf "FID is not lost during migration of a composite layout file"
7853
7854 check_file_ost_range() {
7855         local file="$1"
7856         shift
7857         local range="$*"
7858         local -a file_range
7859         local idx
7860
7861         file_range=($($LFS getstripe -y "$file" |
7862                 awk '/l_ost_idx:/ { print $NF }'))
7863
7864         if [[ "${#file_range[@]}" = 0 ]]; then
7865                 echo "No osts found for $file"
7866                 return 1
7867         fi
7868
7869         for idx in "${file_range[@]}"; do
7870                 [[ " $range " =~ " $idx " ]] ||
7871                         return 1
7872         done
7873
7874         return 0
7875 }
7876
7877 sub_test_56xg() {
7878         local stripe_opt="$1"
7879         local pool="$2"
7880         shift 2
7881         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7882
7883         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7884                 error "Fail to migrate $tfile on $pool"
7885         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7886                 error "$tfile is not in pool $pool"
7887         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7888                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7889 }
7890
7891 test_56xg() {
7892         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7893         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7894         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7895                 skip "Need MDS version newer than 2.14.52"
7896
7897         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7898         local -a pool_ranges=("0 0" "1 1" "0 1")
7899
7900         # init pools
7901         for i in "${!pool_names[@]}"; do
7902                 pool_add ${pool_names[$i]} ||
7903                         error "pool_add failed (pool: ${pool_names[$i]})"
7904                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7905                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7906         done
7907
7908         # init the file to migrate
7909         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7910                 error "Unable to create $tfile on OST1"
7911         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7912                 error "Unable to write on $tfile"
7913
7914         echo "1. migrate $tfile on pool ${pool_names[0]}"
7915         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7916
7917         echo "2. migrate $tfile on pool ${pool_names[2]}"
7918         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7919
7920         echo "3. migrate $tfile on pool ${pool_names[1]}"
7921         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7922
7923         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7924         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7925         echo
7926
7927         # Clean pools
7928         destroy_test_pools ||
7929                 error "pool_destroy failed"
7930 }
7931 run_test 56xg "lfs migrate pool support"
7932
7933 test_56y() {
7934         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7935                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7936
7937         local res=""
7938         local dir=$DIR/$tdir
7939         local f1=$dir/file1
7940         local f2=$dir/file2
7941
7942         test_mkdir -p $dir || error "creating dir $dir"
7943         touch $f1 || error "creating std file $f1"
7944         $MULTIOP $f2 H2c || error "creating released file $f2"
7945
7946         # a directory can be raid0, so ask only for files
7947         res=$($LFS find $dir -L raid0 -type f | wc -l)
7948         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7949
7950         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7951         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7952
7953         # only files can be released, so no need to force file search
7954         res=$($LFS find $dir -L released)
7955         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7956
7957         res=$($LFS find $dir -type f \! -L released)
7958         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7959 }
7960 run_test 56y "lfs find -L raid0|released"
7961
7962 test_56z() { # LU-4824
7963         # This checks to make sure 'lfs find' continues after errors
7964         # There are two classes of errors that should be caught:
7965         # - If multiple paths are provided, all should be searched even if one
7966         #   errors out
7967         # - If errors are encountered during the search, it should not terminate
7968         #   early
7969         local dir=$DIR/$tdir
7970         local i
7971
7972         test_mkdir $dir
7973         for i in d{0..9}; do
7974                 test_mkdir $dir/$i
7975                 touch $dir/$i/$tfile
7976         done
7977         $LFS find $DIR/non_existent_dir $dir &&
7978                 error "$LFS find did not return an error"
7979         # Make a directory unsearchable. This should NOT be the last entry in
7980         # directory order.  Arbitrarily pick the 6th entry
7981         chmod 700 $($LFS find $dir -type d | sed '6!d')
7982
7983         $RUNAS $LFS find $DIR/non_existent $dir
7984         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7985
7986         # The user should be able to see 10 directories and 9 files
7987         (( count == 19 )) ||
7988                 error "$LFS find found $count != 19 entries after error"
7989 }
7990 run_test 56z "lfs find should continue after an error"
7991
7992 test_56aa() { # LU-5937
7993         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7994
7995         local dir=$DIR/$tdir
7996
7997         mkdir $dir
7998         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7999
8000         createmany -o $dir/striped_dir/${tfile}- 1024
8001         local dirs=$($LFS find --size +8k $dir/)
8002
8003         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8004 }
8005 run_test 56aa "lfs find --size under striped dir"
8006
8007 test_56ab() { # LU-10705
8008         test_mkdir $DIR/$tdir
8009         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8010         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8011         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8012         # Flush writes to ensure valid blocks.  Need to be more thorough for
8013         # ZFS, since blocks are not allocated/returned to client immediately.
8014         sync_all_data
8015         wait_zfs_commit ost1 2
8016         cancel_lru_locks osc
8017         ls -ls $DIR/$tdir
8018
8019         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8020
8021         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8022
8023         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8024         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8025
8026         rm -f $DIR/$tdir/$tfile.[123]
8027 }
8028 run_test 56ab "lfs find --blocks"
8029
8030 # LU-11188
8031 test_56aca() {
8032         local dir="$DIR/$tdir"
8033         local perms=(001 002 003 004 005 006 007
8034                      010 020 030 040 050 060 070
8035                      100 200 300 400 500 600 700
8036                      111 222 333 444 555 666 777)
8037         local perm_minus=(8 8 4 8 4 4 2
8038                           8 8 4 8 4 4 2
8039                           8 8 4 8 4 4 2
8040                           4 4 2 4 2 2 1)
8041         local perm_slash=(8  8 12  8 12 12 14
8042                           8  8 12  8 12 12 14
8043                           8  8 12  8 12 12 14
8044                          16 16 24 16 24 24 28)
8045
8046         test_mkdir "$dir"
8047         for perm in ${perms[*]}; do
8048                 touch "$dir/$tfile.$perm"
8049                 chmod $perm "$dir/$tfile.$perm"
8050         done
8051
8052         for ((i = 0; i < ${#perms[*]}; i++)); do
8053                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8054                 (( $num == 1 )) ||
8055                         error "lfs find -perm ${perms[i]}:"\
8056                               "$num != 1"
8057
8058                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8059                 (( $num == ${perm_minus[i]} )) ||
8060                         error "lfs find -perm -${perms[i]}:"\
8061                               "$num != ${perm_minus[i]}"
8062
8063                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8064                 (( $num == ${perm_slash[i]} )) ||
8065                         error "lfs find -perm /${perms[i]}:"\
8066                               "$num != ${perm_slash[i]}"
8067         done
8068 }
8069 run_test 56aca "check lfs find -perm with octal representation"
8070
8071 test_56acb() {
8072         local dir=$DIR/$tdir
8073         # p is the permission of write and execute for user, group and other
8074         # without the umask. It is used to test +wx.
8075         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8076         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8077         local symbolic=(+t  a+t u+t g+t o+t
8078                         g+s u+s o+s +s o+sr
8079                         o=r,ug+o,u+w
8080                         u+ g+ o+ a+ ugo+
8081                         u- g- o- a- ugo-
8082                         u= g= o= a= ugo=
8083                         o=r,ug+o,u+w u=r,a+u,u+w
8084                         g=r,ugo=g,u+w u+x,+X +X
8085                         u+x,u+X u+X u+x,g+X o+r,+X
8086                         u+x,go+X +wx +rwx)
8087
8088         test_mkdir $dir
8089         for perm in ${perms[*]}; do
8090                 touch "$dir/$tfile.$perm"
8091                 chmod $perm "$dir/$tfile.$perm"
8092         done
8093
8094         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8095                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8096
8097                 (( $num == 1 )) ||
8098                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8099         done
8100 }
8101 run_test 56acb "check lfs find -perm with symbolic representation"
8102
8103 test_56acc() {
8104         local dir=$DIR/$tdir
8105         local tests="17777 787 789 abcd
8106                 ug=uu ug=a ug=gu uo=ou urw
8107                 u+xg+x a=r,u+x,"
8108
8109         test_mkdir $dir
8110         for err in $tests; do
8111                 if $LFS find $dir -perm $err 2>/dev/null; then
8112                         error "lfs find -perm $err: parsing should have failed"
8113                 fi
8114         done
8115 }
8116 run_test 56acc "check parsing error for lfs find -perm"
8117
8118 test_56ba() {
8119         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8120                 skip "Need MDS version at least 2.10.50"
8121
8122         # Create composite files with one component
8123         local dir=$DIR/$tdir
8124
8125         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8126         # Create composite files with three components
8127         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8128         # Create non-composite files
8129         createmany -o $dir/${tfile}- 10
8130
8131         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8132
8133         [[ $nfiles == 10 ]] ||
8134                 error "lfs find -E 1M found $nfiles != 10 files"
8135
8136         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8137         [[ $nfiles == 25 ]] ||
8138                 error "lfs find ! -E 1M found $nfiles != 25 files"
8139
8140         # All files have a component that starts at 0
8141         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8142         [[ $nfiles == 35 ]] ||
8143                 error "lfs find --component-start 0 - $nfiles != 35 files"
8144
8145         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8146         [[ $nfiles == 15 ]] ||
8147                 error "lfs find --component-start 2M - $nfiles != 15 files"
8148
8149         # All files created here have a componenet that does not starts at 2M
8150         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8151         [[ $nfiles == 35 ]] ||
8152                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8153
8154         # Find files with a specified number of components
8155         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8156         [[ $nfiles == 15 ]] ||
8157                 error "lfs find --component-count 3 - $nfiles != 15 files"
8158
8159         # Remember non-composite files have a component count of zero
8160         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8161         [[ $nfiles == 10 ]] ||
8162                 error "lfs find --component-count 0 - $nfiles != 10 files"
8163
8164         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8165         [[ $nfiles == 20 ]] ||
8166                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8167
8168         # All files have a flag called "init"
8169         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8170         [[ $nfiles == 35 ]] ||
8171                 error "lfs find --component-flags init - $nfiles != 35 files"
8172
8173         # Multi-component files will have a component not initialized
8174         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8175         [[ $nfiles == 15 ]] ||
8176                 error "lfs find !--component-flags init - $nfiles != 15 files"
8177
8178         rm -rf $dir
8179
8180 }
8181 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8182
8183 test_56ca() {
8184         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8185                 skip "Need MDS version at least 2.10.57"
8186
8187         local td=$DIR/$tdir
8188         local tf=$td/$tfile
8189         local dir
8190         local nfiles
8191         local cmd
8192         local i
8193         local j
8194
8195         # create mirrored directories and mirrored files
8196         mkdir $td || error "mkdir $td failed"
8197         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8198         createmany -o $tf- 10 || error "create $tf- failed"
8199
8200         for i in $(seq 2); do
8201                 dir=$td/dir$i
8202                 mkdir $dir || error "mkdir $dir failed"
8203                 $LFS mirror create -N$((3 + i)) $dir ||
8204                         error "create mirrored dir $dir failed"
8205                 createmany -o $dir/$tfile- 10 ||
8206                         error "create $dir/$tfile- failed"
8207         done
8208
8209         # change the states of some mirrored files
8210         echo foo > $tf-6
8211         for i in $(seq 2); do
8212                 dir=$td/dir$i
8213                 for j in $(seq 4 9); do
8214                         echo foo > $dir/$tfile-$j
8215                 done
8216         done
8217
8218         # find mirrored files with specific mirror count
8219         cmd="$LFS find --mirror-count 3 --type f $td"
8220         nfiles=$($cmd | wc -l)
8221         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8222
8223         cmd="$LFS find ! --mirror-count 3 --type f $td"
8224         nfiles=$($cmd | wc -l)
8225         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8226
8227         cmd="$LFS find --mirror-count +2 --type f $td"
8228         nfiles=$($cmd | wc -l)
8229         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8230
8231         cmd="$LFS find --mirror-count -6 --type f $td"
8232         nfiles=$($cmd | wc -l)
8233         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8234
8235         # find mirrored files with specific file state
8236         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8237         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8238
8239         cmd="$LFS find --mirror-state=ro --type f $td"
8240         nfiles=$($cmd | wc -l)
8241         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8242
8243         cmd="$LFS find ! --mirror-state=ro --type f $td"
8244         nfiles=$($cmd | wc -l)
8245         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8246
8247         cmd="$LFS find --mirror-state=wp --type f $td"
8248         nfiles=$($cmd | wc -l)
8249         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8250
8251         cmd="$LFS find ! --mirror-state=sp --type f $td"
8252         nfiles=$($cmd | wc -l)
8253         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8254 }
8255 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8256
8257 test_56da() { # LU-14179
8258         local path=$DIR/$tdir
8259
8260         test_mkdir $path
8261         cd $path
8262
8263         local longdir=$(str_repeat 'a' 255)
8264
8265         for i in {1..15}; do
8266                 path=$path/$longdir
8267                 test_mkdir $longdir
8268                 cd $longdir
8269         done
8270
8271         local len=${#path}
8272         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8273
8274         test_mkdir $lastdir
8275         cd $lastdir
8276         # PATH_MAX-1
8277         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8278
8279         # NAME_MAX
8280         touch $(str_repeat 'f' 255)
8281
8282         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8283                 error "lfs find reported an error"
8284
8285         rm -rf $DIR/$tdir
8286 }
8287 run_test 56da "test lfs find with long paths"
8288
8289 test_56ea() { #LU-10378
8290         local path=$DIR/$tdir
8291         local pool=$TESTNAME
8292
8293         # Create ost pool
8294         pool_add $pool || error "pool_add $pool failed"
8295         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8296                 error "adding targets to $pool failed"
8297
8298         # Set default pool on directory before creating file
8299         mkdir $path || error "mkdir $path failed"
8300         $LFS setstripe -p $pool $path ||
8301                 error "set OST pool on $pool failed"
8302         touch $path/$tfile || error "touch $path/$tfile failed"
8303
8304         # Compare basic file attributes from -printf and stat
8305         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8306         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8307
8308         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8309                 error "Attrs from lfs find and stat don't match"
8310
8311         # Compare Lustre attributes from lfs find and lfs getstripe
8312         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8313         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8314         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8315         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8316         local fpool=$($LFS getstripe --pool $path/$tfile)
8317         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8318
8319         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8320                 error "Attrs from lfs find and lfs getstripe don't match"
8321
8322         # Verify behavior for unknown escape/format sequences
8323         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8324
8325         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8326                 error "Escape/format codes don't match"
8327 }
8328 run_test 56ea "test lfs find -printf option"
8329
8330 test_57a() {
8331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8332         # note test will not do anything if MDS is not local
8333         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8334                 skip_env "ldiskfs only test"
8335         fi
8336         remote_mds_nodsh && skip "remote MDS with nodsh"
8337
8338         local MNTDEV="osd*.*MDT*.mntdev"
8339         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8340         [ -z "$DEV" ] && error "can't access $MNTDEV"
8341         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8342                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8343                         error "can't access $DEV"
8344                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8345                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8346                 rm $TMP/t57a.dump
8347         done
8348 }
8349 run_test 57a "verify MDS filesystem created with large inodes =="
8350
8351 test_57b() {
8352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8353         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8354                 skip_env "ldiskfs only test"
8355         fi
8356         remote_mds_nodsh && skip "remote MDS with nodsh"
8357
8358         local dir=$DIR/$tdir
8359         local filecount=100
8360         local file1=$dir/f1
8361         local fileN=$dir/f$filecount
8362
8363         rm -rf $dir || error "removing $dir"
8364         test_mkdir -c1 $dir
8365         local mdtidx=$($LFS getstripe -m $dir)
8366         local mdtname=MDT$(printf %04x $mdtidx)
8367         local facet=mds$((mdtidx + 1))
8368
8369         echo "mcreating $filecount files"
8370         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8371
8372         # verify that files do not have EAs yet
8373         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8374                 error "$file1 has an EA"
8375         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8376                 error "$fileN has an EA"
8377
8378         sync
8379         sleep 1
8380         df $dir  #make sure we get new statfs data
8381         local mdsfree=$(do_facet $facet \
8382                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8383         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8384         local file
8385
8386         echo "opening files to create objects/EAs"
8387         for file in $(seq -f $dir/f%g 1 $filecount); do
8388                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8389                         error "opening $file"
8390         done
8391
8392         # verify that files have EAs now
8393         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8394         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8395
8396         sleep 1  #make sure we get new statfs data
8397         df $dir
8398         local mdsfree2=$(do_facet $facet \
8399                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8400         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8401
8402         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8403                 if [ "$mdsfree" != "$mdsfree2" ]; then
8404                         error "MDC before $mdcfree != after $mdcfree2"
8405                 else
8406                         echo "MDC before $mdcfree != after $mdcfree2"
8407                         echo "unable to confirm if MDS has large inodes"
8408                 fi
8409         fi
8410         rm -rf $dir
8411 }
8412 run_test 57b "default LOV EAs are stored inside large inodes ==="
8413
8414 test_58() {
8415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8416         [ -z "$(which wiretest 2>/dev/null)" ] &&
8417                         skip_env "could not find wiretest"
8418
8419         wiretest
8420 }
8421 run_test 58 "verify cross-platform wire constants =============="
8422
8423 test_59() {
8424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8425
8426         echo "touch 130 files"
8427         createmany -o $DIR/f59- 130
8428         echo "rm 130 files"
8429         unlinkmany $DIR/f59- 130
8430         sync
8431         # wait for commitment of removal
8432         wait_delete_completed
8433 }
8434 run_test 59 "verify cancellation of llog records async ========="
8435
8436 TEST60_HEAD="test_60 run $RANDOM"
8437 test_60a() {
8438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8439         remote_mgs_nodsh && skip "remote MGS with nodsh"
8440         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8441                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8442                         skip_env "missing subtest run-llog.sh"
8443
8444         log "$TEST60_HEAD - from kernel mode"
8445         do_facet mgs "$LCTL dk > /dev/null"
8446         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8447         do_facet mgs $LCTL dk > $TMP/$tfile
8448
8449         # LU-6388: test llog_reader
8450         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8451         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8452         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8453                         skip_env "missing llog_reader"
8454         local fstype=$(facet_fstype mgs)
8455         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8456                 skip_env "Only for ldiskfs or zfs type mgs"
8457
8458         local mntpt=$(facet_mntpt mgs)
8459         local mgsdev=$(mgsdevname 1)
8460         local fid_list
8461         local fid
8462         local rec_list
8463         local rec
8464         local rec_type
8465         local obj_file
8466         local path
8467         local seq
8468         local oid
8469         local pass=true
8470
8471         #get fid and record list
8472         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8473                 tail -n 4))
8474         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8475                 tail -n 4))
8476         #remount mgs as ldiskfs or zfs type
8477         stop mgs || error "stop mgs failed"
8478         mount_fstype mgs || error "remount mgs failed"
8479         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8480                 fid=${fid_list[i]}
8481                 rec=${rec_list[i]}
8482                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8483                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8484                 oid=$((16#$oid))
8485
8486                 case $fstype in
8487                         ldiskfs )
8488                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8489                         zfs )
8490                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8491                 esac
8492                 echo "obj_file is $obj_file"
8493                 do_facet mgs $llog_reader $obj_file
8494
8495                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8496                         awk '{ print $3 }' | sed -e "s/^type=//g")
8497                 if [ $rec_type != $rec ]; then
8498                         echo "FAILED test_60a wrong record type $rec_type," \
8499                               "should be $rec"
8500                         pass=false
8501                         break
8502                 fi
8503
8504                 #check obj path if record type is LLOG_LOGID_MAGIC
8505                 if [ "$rec" == "1064553b" ]; then
8506                         path=$(do_facet mgs $llog_reader $obj_file |
8507                                 grep "path=" | awk '{ print $NF }' |
8508                                 sed -e "s/^path=//g")
8509                         if [ $obj_file != $mntpt/$path ]; then
8510                                 echo "FAILED test_60a wrong obj path" \
8511                                       "$montpt/$path, should be $obj_file"
8512                                 pass=false
8513                                 break
8514                         fi
8515                 fi
8516         done
8517         rm -f $TMP/$tfile
8518         #restart mgs before "error", otherwise it will block the next test
8519         stop mgs || error "stop mgs failed"
8520         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8521         $pass || error "test failed, see FAILED test_60a messages for specifics"
8522 }
8523 run_test 60a "llog_test run from kernel module and test llog_reader"
8524
8525 test_60b() { # bug 6411
8526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8527
8528         dmesg > $DIR/$tfile
8529         LLOG_COUNT=$(do_facet mgs dmesg |
8530                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8531                           /llog_[a-z]*.c:[0-9]/ {
8532                                 if (marker)
8533                                         from_marker++
8534                                 from_begin++
8535                           }
8536                           END {
8537                                 if (marker)
8538                                         print from_marker
8539                                 else
8540                                         print from_begin
8541                           }")
8542
8543         [[ $LLOG_COUNT -gt 120 ]] &&
8544                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8545 }
8546 run_test 60b "limit repeated messages from CERROR/CWARN"
8547
8548 test_60c() {
8549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8550
8551         echo "create 5000 files"
8552         createmany -o $DIR/f60c- 5000
8553 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8554         lctl set_param fail_loc=0x80000137
8555         unlinkmany $DIR/f60c- 5000
8556         lctl set_param fail_loc=0
8557 }
8558 run_test 60c "unlink file when mds full"
8559
8560 test_60d() {
8561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8562
8563         SAVEPRINTK=$(lctl get_param -n printk)
8564         # verify "lctl mark" is even working"
8565         MESSAGE="test message ID $RANDOM $$"
8566         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8567         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8568
8569         lctl set_param printk=0 || error "set lnet.printk failed"
8570         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8571         MESSAGE="new test message ID $RANDOM $$"
8572         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8573         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8574         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8575
8576         lctl set_param -n printk="$SAVEPRINTK"
8577 }
8578 run_test 60d "test printk console message masking"
8579
8580 test_60e() {
8581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8582         remote_mds_nodsh && skip "remote MDS with nodsh"
8583
8584         touch $DIR/$tfile
8585 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8586         do_facet mds1 lctl set_param fail_loc=0x15b
8587         rm $DIR/$tfile
8588 }
8589 run_test 60e "no space while new llog is being created"
8590
8591 test_60f() {
8592         local old_path=$($LCTL get_param -n debug_path)
8593
8594         stack_trap "$LCTL set_param debug_path=$old_path"
8595         stack_trap "rm -f $TMP/$tfile*"
8596         rm -f $TMP/$tfile* 2> /dev/null
8597         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8598         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8599         test_mkdir $DIR/$tdir
8600         # retry in case the open is cached and not released
8601         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8602                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8603                 sleep 0.1
8604         done
8605         ls $TMP/$tfile*
8606         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8607 }
8608 run_test 60f "change debug_path works"
8609
8610 test_60g() {
8611         local pid
8612         local i
8613
8614         test_mkdir -c $MDSCOUNT $DIR/$tdir
8615
8616         (
8617                 local index=0
8618                 while true; do
8619                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8620                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8621                                 2>/dev/null
8622                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8623                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8624                         index=$((index + 1))
8625                 done
8626         ) &
8627
8628         pid=$!
8629
8630         for i in {0..100}; do
8631                 # define OBD_FAIL_OSD_TXN_START    0x19a
8632                 local index=$((i % MDSCOUNT + 1))
8633
8634                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8635                         > /dev/null
8636                 sleep 0.01
8637         done
8638
8639         kill -9 $pid
8640
8641         for i in $(seq $MDSCOUNT); do
8642                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8643         done
8644
8645         mkdir $DIR/$tdir/new || error "mkdir failed"
8646         rmdir $DIR/$tdir/new || error "rmdir failed"
8647
8648         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8649                 -t namespace
8650         for i in $(seq $MDSCOUNT); do
8651                 wait_update_facet mds$i "$LCTL get_param -n \
8652                         mdd.$(facet_svc mds$i).lfsck_namespace |
8653                         awk '/^status/ { print \\\$2 }'" "completed"
8654         done
8655
8656         ls -R $DIR/$tdir
8657         rm -rf $DIR/$tdir || error "rmdir failed"
8658 }
8659 run_test 60g "transaction abort won't cause MDT hung"
8660
8661 test_60h() {
8662         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8663                 skip "Need MDS version at least 2.12.52"
8664         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8665
8666         local f
8667
8668         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8669         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8670         for fail_loc in 0x80000188 0x80000189; do
8671                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8672                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8673                         error "mkdir $dir-$fail_loc failed"
8674                 for i in {0..10}; do
8675                         # create may fail on missing stripe
8676                         echo $i > $DIR/$tdir-$fail_loc/$i
8677                 done
8678                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8679                         error "getdirstripe $tdir-$fail_loc failed"
8680                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8681                         error "migrate $tdir-$fail_loc failed"
8682                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8683                         error "getdirstripe $tdir-$fail_loc failed"
8684                 pushd $DIR/$tdir-$fail_loc
8685                 for f in *; do
8686                         echo $f | cmp $f - || error "$f data mismatch"
8687                 done
8688                 popd
8689                 rm -rf $DIR/$tdir-$fail_loc
8690         done
8691 }
8692 run_test 60h "striped directory with missing stripes can be accessed"
8693
8694 function t60i_load() {
8695         mkdir $DIR/$tdir
8696         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8697         $LCTL set_param fail_loc=0x131c fail_val=1
8698         for ((i=0; i<5000; i++)); do
8699                 touch $DIR/$tdir/f$i
8700         done
8701 }
8702
8703 test_60i() {
8704         changelog_register || error "changelog_register failed"
8705         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8706         changelog_users $SINGLEMDS | grep -q $cl_user ||
8707                 error "User $cl_user not found in changelog_users"
8708         changelog_chmask "ALL"
8709         t60i_load &
8710         local PID=$!
8711         for((i=0; i<100; i++)); do
8712                 changelog_dump >/dev/null ||
8713                         error "can't read changelog"
8714         done
8715         kill $PID
8716         wait $PID
8717         changelog_deregister || error "changelog_deregister failed"
8718         $LCTL set_param fail_loc=0
8719 }
8720 run_test 60i "llog: new record vs reader race"
8721
8722 test_61a() {
8723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8724
8725         f="$DIR/f61"
8726         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8727         cancel_lru_locks osc
8728         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8729         sync
8730 }
8731 run_test 61a "mmap() writes don't make sync hang ================"
8732
8733 test_61b() {
8734         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8735 }
8736 run_test 61b "mmap() of unstriped file is successful"
8737
8738 # bug 2330 - insufficient obd_match error checking causes LBUG
8739 test_62() {
8740         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8741
8742         f="$DIR/f62"
8743         echo foo > $f
8744         cancel_lru_locks osc
8745         lctl set_param fail_loc=0x405
8746         cat $f && error "cat succeeded, expect -EIO"
8747         lctl set_param fail_loc=0
8748 }
8749 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8750 # match every page all of the time.
8751 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8752
8753 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8754 # Though this test is irrelevant anymore, it helped to reveal some
8755 # other grant bugs (LU-4482), let's keep it.
8756 test_63a() {   # was test_63
8757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8758
8759         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8760
8761         for i in `seq 10` ; do
8762                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8763                 sleep 5
8764                 kill $!
8765                 sleep 1
8766         done
8767
8768         rm -f $DIR/f63 || true
8769 }
8770 run_test 63a "Verify oig_wait interruption does not crash ======="
8771
8772 # bug 2248 - async write errors didn't return to application on sync
8773 # bug 3677 - async write errors left page locked
8774 test_63b() {
8775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8776
8777         debugsave
8778         lctl set_param debug=-1
8779
8780         # ensure we have a grant to do async writes
8781         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8782         rm $DIR/$tfile
8783
8784         sync    # sync lest earlier test intercept the fail_loc
8785
8786         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8787         lctl set_param fail_loc=0x80000406
8788         $MULTIOP $DIR/$tfile Owy && \
8789                 error "sync didn't return ENOMEM"
8790         sync; sleep 2; sync     # do a real sync this time to flush page
8791         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8792                 error "locked page left in cache after async error" || true
8793         debugrestore
8794 }
8795 run_test 63b "async write errors should be returned to fsync ==="
8796
8797 test_64a () {
8798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8799
8800         lfs df $DIR
8801         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8802 }
8803 run_test 64a "verify filter grant calculations (in kernel) ====="
8804
8805 test_64b () {
8806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8807
8808         bash oos.sh $MOUNT || error "oos.sh failed: $?"
8809 }
8810 run_test 64b "check out-of-space detection on client"
8811
8812 test_64c() {
8813         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8814 }
8815 run_test 64c "verify grant shrink"
8816
8817 import_param() {
8818         local tgt=$1
8819         local param=$2
8820
8821         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8822 }
8823
8824 # this does exactly what osc_request.c:osc_announce_cached() does in
8825 # order to calculate max amount of grants to ask from server
8826 want_grant() {
8827         local tgt=$1
8828
8829         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8830         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8831
8832         ((rpc_in_flight++));
8833         nrpages=$((nrpages * rpc_in_flight))
8834
8835         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8836
8837         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8838
8839         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8840         local undirty=$((nrpages * PAGE_SIZE))
8841
8842         local max_extent_pages
8843         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8844         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8845         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8846         local grant_extent_tax
8847         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8848
8849         undirty=$((undirty + nrextents * grant_extent_tax))
8850
8851         echo $undirty
8852 }
8853
8854 # this is size of unit for grant allocation. It should be equal to
8855 # what tgt_grant.c:tgt_grant_chunk() calculates
8856 grant_chunk() {
8857         local tgt=$1
8858         local max_brw_size
8859         local grant_extent_tax
8860
8861         max_brw_size=$(import_param $tgt max_brw_size)
8862
8863         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8864
8865         echo $(((max_brw_size + grant_extent_tax) * 2))
8866 }
8867
8868 test_64d() {
8869         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8870                 skip "OST < 2.10.55 doesn't limit grants enough"
8871
8872         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8873
8874         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8875                 skip "no grant_param connect flag"
8876
8877         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8878
8879         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8880         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8881
8882
8883         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8884         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8885
8886         $LFS setstripe $DIR/$tfile -i 0 -c 1
8887         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8888         ddpid=$!
8889
8890         while kill -0 $ddpid; do
8891                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8892
8893                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8894                         kill $ddpid
8895                         error "cur_grant $cur_grant > $max_cur_granted"
8896                 fi
8897
8898                 sleep 1
8899         done
8900 }
8901 run_test 64d "check grant limit exceed"
8902
8903 check_grants() {
8904         local tgt=$1
8905         local expected=$2
8906         local msg=$3
8907         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8908
8909         ((cur_grants == expected)) ||
8910                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8911 }
8912
8913 round_up_p2() {
8914         echo $((($1 + $2 - 1) & ~($2 - 1)))
8915 }
8916
8917 test_64e() {
8918         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8919         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8920                 skip "Need OSS version at least 2.11.56"
8921
8922         # Remount client to reset grant
8923         remount_client $MOUNT || error "failed to remount client"
8924         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8925
8926         local init_grants=$(import_param $osc_tgt initial_grant)
8927
8928         check_grants $osc_tgt $init_grants "init grants"
8929
8930         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8931         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8932         local gbs=$(import_param $osc_tgt grant_block_size)
8933
8934         # write random number of bytes from max_brw_size / 4 to max_brw_size
8935         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8936         # align for direct io
8937         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8938         # round to grant consumption unit
8939         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8940
8941         local grants=$((wb_round_up + extent_tax))
8942
8943         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8944
8945         # define OBD_FAIL_TGT_NO_GRANT 0x725
8946         # make the server not grant more back
8947         do_facet ost1 $LCTL set_param fail_loc=0x725
8948         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8949
8950         do_facet ost1 $LCTL set_param fail_loc=0
8951
8952         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8953
8954         rm -f $DIR/$tfile || error "rm failed"
8955
8956         # Remount client to reset grant
8957         remount_client $MOUNT || error "failed to remount client"
8958         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8959
8960         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8961
8962         # define OBD_FAIL_TGT_NO_GRANT 0x725
8963         # make the server not grant more back
8964         do_facet ost1 $LCTL set_param fail_loc=0x725
8965         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8966         do_facet ost1 $LCTL set_param fail_loc=0
8967
8968         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8969 }
8970 run_test 64e "check grant consumption (no grant allocation)"
8971
8972 test_64f() {
8973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8974
8975         # Remount client to reset grant
8976         remount_client $MOUNT || error "failed to remount client"
8977         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8978
8979         local init_grants=$(import_param $osc_tgt initial_grant)
8980         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8981         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8982         local gbs=$(import_param $osc_tgt grant_block_size)
8983         local chunk=$(grant_chunk $osc_tgt)
8984
8985         # write random number of bytes from max_brw_size / 4 to max_brw_size
8986         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8987         # align for direct io
8988         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8989         # round to grant consumption unit
8990         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8991
8992         local grants=$((wb_round_up + extent_tax))
8993
8994         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8995         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8996                 error "error writing to $DIR/$tfile"
8997
8998         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8999                 "direct io with grant allocation"
9000
9001         rm -f $DIR/$tfile || error "rm failed"
9002
9003         # Remount client to reset grant
9004         remount_client $MOUNT || error "failed to remount client"
9005         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9006
9007         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9008
9009         local cmd="oO_WRONLY:w${write_bytes}_yc"
9010
9011         $MULTIOP $DIR/$tfile $cmd &
9012         MULTIPID=$!
9013         sleep 1
9014
9015         check_grants $osc_tgt $((init_grants - grants)) \
9016                 "buffered io, not write rpc"
9017
9018         kill -USR1 $MULTIPID
9019         wait
9020
9021         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9022                 "buffered io, one RPC"
9023 }
9024 run_test 64f "check grant consumption (with grant allocation)"
9025
9026 test_64g() {
9027         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9028                 skip "Need MDS version at least 2.14.56"
9029
9030         local mdts=$(comma_list $(mdts_nodes))
9031
9032         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9033                         tr '\n' ' ')
9034         stack_trap "$LCTL set_param $old"
9035
9036         # generate dirty pages and increase dirty granted on MDT
9037         stack_trap "rm -f $DIR/$tfile-*"
9038         for (( i = 0; i < 10; i++)); do
9039                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9040                         error "can't set stripe"
9041                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9042                         error "can't dd"
9043                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9044                         $LFS getstripe $DIR/$tfile-$i
9045                         error "not DoM file"
9046                 }
9047         done
9048
9049         # flush dirty pages
9050         sync
9051
9052         # wait until grant shrink reset grant dirty on MDTs
9053         for ((i = 0; i < 120; i++)); do
9054                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9055                         awk '{sum=sum+$1} END {print sum}')
9056                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9057                 echo "$grant_dirty grants, $vm_dirty pages"
9058                 (( grant_dirty + vm_dirty == 0 )) && break
9059                 (( i == 3 )) && sync &&
9060                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9061                 sleep 1
9062         done
9063
9064         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9065                 awk '{sum=sum+$1} END {print sum}')
9066         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9067 }
9068 run_test 64g "grant shrink on MDT"
9069
9070 test_64h() {
9071         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9072                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9073
9074         local instance=$($LFS getname -i $DIR)
9075         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9076         local num_exps=$(do_facet ost1 \
9077             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9078         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9079         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9080         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9081
9082         # 10MiB is for file to be written, max_brw_size * 16 *
9083         # num_exps is space reserve so that tgt_grant_shrink() decided
9084         # to not shrink
9085         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9086         (( avail * 1024 < expect )) &&
9087                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9088
9089         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9090         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9091         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9092         $LCTL set_param osc.*OST0000*.grant_shrink=1
9093         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9094
9095         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9096         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9097
9098         # drop cache so that coming read would do rpc
9099         cancel_lru_locks osc
9100
9101         # shrink interval is set to 10, pause for 7 seconds so that
9102         # grant thread did not wake up yet but coming read entered
9103         # shrink mode for rpc (osc_should_shrink_grant())
9104         sleep 7
9105
9106         declare -a cur_grant_bytes
9107         declare -a tot_granted
9108         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9109         tot_granted[0]=$(do_facet ost1 \
9110             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9111
9112         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9113
9114         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9115         tot_granted[1]=$(do_facet ost1 \
9116             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9117
9118         # grant change should be equal on both sides
9119         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9120                 tot_granted[0] - tot_granted[1])) ||
9121                 error "grant change mismatch, "                                \
9122                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9123                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9124 }
9125 run_test 64h "grant shrink on read"
9126
9127 test_64i() {
9128         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9129                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9130
9131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9132         remote_ost_nodsh && skip "remote OSTs with nodsh"
9133
9134         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9135
9136         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9137
9138         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9139         local instance=$($LFS getname -i $DIR)
9140
9141         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9142         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9143
9144         # shrink grants and simulate rpc loss
9145         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9146         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9147         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9148
9149         fail ost1
9150
9151         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9152
9153         local testid=$(echo $TESTNAME | tr '_' ' ')
9154
9155         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9156                 grep "GRANT, real grant" &&
9157                 error "client has more grants then it owns" || true
9158 }
9159 run_test 64i "shrink on reconnect"
9160
9161 # bug 1414 - set/get directories' stripe info
9162 test_65a() {
9163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9164
9165         test_mkdir $DIR/$tdir
9166         touch $DIR/$tdir/f1
9167         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9168 }
9169 run_test 65a "directory with no stripe info"
9170
9171 test_65b() {
9172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9173
9174         test_mkdir $DIR/$tdir
9175         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9176
9177         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9178                                                 error "setstripe"
9179         touch $DIR/$tdir/f2
9180         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9181 }
9182 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9183
9184 test_65c() {
9185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9186         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9187
9188         test_mkdir $DIR/$tdir
9189         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9190
9191         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9192                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9193         touch $DIR/$tdir/f3
9194         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9195 }
9196 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9197
9198 test_65d() {
9199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9200
9201         test_mkdir $DIR/$tdir
9202         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9203         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9204
9205         if [[ $STRIPECOUNT -le 0 ]]; then
9206                 sc=1
9207         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9208                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9209                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9210         else
9211                 sc=$(($STRIPECOUNT - 1))
9212         fi
9213         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9214         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9215         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9216                 error "lverify failed"
9217 }
9218 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9219
9220 test_65e() {
9221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9222
9223         test_mkdir $DIR/$tdir
9224
9225         $LFS setstripe $DIR/$tdir || error "setstripe"
9226         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9227                                         error "no stripe info failed"
9228         touch $DIR/$tdir/f6
9229         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9230 }
9231 run_test 65e "directory setstripe defaults"
9232
9233 test_65f() {
9234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9235
9236         test_mkdir $DIR/${tdir}f
9237         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9238                 error "setstripe succeeded" || true
9239 }
9240 run_test 65f "dir setstripe permission (should return error) ==="
9241
9242 test_65g() {
9243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9244
9245         test_mkdir $DIR/$tdir
9246         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9247
9248         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9249                 error "setstripe -S failed"
9250         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9251         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9252                 error "delete default stripe failed"
9253 }
9254 run_test 65g "directory setstripe -d"
9255
9256 test_65h() {
9257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9258
9259         test_mkdir $DIR/$tdir
9260         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9261
9262         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9263                 error "setstripe -S failed"
9264         test_mkdir $DIR/$tdir/dd1
9265         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9266                 error "stripe info inherit failed"
9267 }
9268 run_test 65h "directory stripe info inherit ===================="
9269
9270 test_65i() {
9271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9272
9273         save_layout_restore_at_exit $MOUNT
9274
9275         # bug6367: set non-default striping on root directory
9276         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9277
9278         # bug12836: getstripe on -1 default directory striping
9279         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9280
9281         # bug12836: getstripe -v on -1 default directory striping
9282         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9283
9284         # bug12836: new find on -1 default directory striping
9285         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9286 }
9287 run_test 65i "various tests to set root directory striping"
9288
9289 test_65j() { # bug6367
9290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9291
9292         sync; sleep 1
9293
9294         # if we aren't already remounting for each test, do so for this test
9295         if [ "$I_MOUNTED" = "yes" ]; then
9296                 cleanup || error "failed to unmount"
9297                 setup
9298         fi
9299
9300         save_layout_restore_at_exit $MOUNT
9301
9302         $LFS setstripe -d $MOUNT || error "setstripe failed"
9303 }
9304 run_test 65j "set default striping on root directory (bug 6367)="
9305
9306 cleanup_65k() {
9307         rm -rf $DIR/$tdir
9308         wait_delete_completed
9309         do_facet $SINGLEMDS "lctl set_param -n \
9310                 osp.$ost*MDT0000.max_create_count=$max_count"
9311         do_facet $SINGLEMDS "lctl set_param -n \
9312                 osp.$ost*MDT0000.create_count=$count"
9313         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9314         echo $INACTIVE_OSC "is Activate"
9315
9316         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9317 }
9318
9319 test_65k() { # bug11679
9320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9321         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9322         remote_mds_nodsh && skip "remote MDS with nodsh"
9323
9324         local disable_precreate=true
9325         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9326                 disable_precreate=false
9327
9328         echo "Check OST status: "
9329         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9330                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9331
9332         for OSC in $MDS_OSCS; do
9333                 echo $OSC "is active"
9334                 do_facet $SINGLEMDS lctl --device %$OSC activate
9335         done
9336
9337         for INACTIVE_OSC in $MDS_OSCS; do
9338                 local ost=$(osc_to_ost $INACTIVE_OSC)
9339                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9340                                lov.*md*.target_obd |
9341                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9342
9343                 mkdir -p $DIR/$tdir
9344                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9345                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9346
9347                 echo "Deactivate: " $INACTIVE_OSC
9348                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9349
9350                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9351                               osp.$ost*MDT0000.create_count")
9352                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9353                                   osp.$ost*MDT0000.max_create_count")
9354                 $disable_precreate &&
9355                         do_facet $SINGLEMDS "lctl set_param -n \
9356                                 osp.$ost*MDT0000.max_create_count=0"
9357
9358                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9359                         [ -f $DIR/$tdir/$idx ] && continue
9360                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9361                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9362                                 { cleanup_65k;
9363                                   error "setstripe $idx should succeed"; }
9364                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9365                 done
9366                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9367                 rmdir $DIR/$tdir
9368
9369                 do_facet $SINGLEMDS "lctl set_param -n \
9370                         osp.$ost*MDT0000.max_create_count=$max_count"
9371                 do_facet $SINGLEMDS "lctl set_param -n \
9372                         osp.$ost*MDT0000.create_count=$count"
9373                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9374                 echo $INACTIVE_OSC "is Activate"
9375
9376                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9377         done
9378 }
9379 run_test 65k "validate manual striping works properly with deactivated OSCs"
9380
9381 test_65l() { # bug 12836
9382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9383
9384         test_mkdir -p $DIR/$tdir/test_dir
9385         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9386         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9387 }
9388 run_test 65l "lfs find on -1 stripe dir ========================"
9389
9390 test_65m() {
9391         local layout=$(save_layout $MOUNT)
9392         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9393                 restore_layout $MOUNT $layout
9394                 error "setstripe should fail by non-root users"
9395         }
9396         true
9397 }
9398 run_test 65m "normal user can't set filesystem default stripe"
9399
9400 test_65n() {
9401         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9402         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9403                 skip "Need MDS version at least 2.12.50"
9404         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9405
9406         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9407         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9408         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9409
9410         save_layout_restore_at_exit $MOUNT
9411
9412         # new subdirectory under root directory should not inherit
9413         # the default layout from root
9414         local dir1=$MOUNT/$tdir-1
9415         mkdir $dir1 || error "mkdir $dir1 failed"
9416         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9417                 error "$dir1 shouldn't have LOV EA"
9418
9419         # delete the default layout on root directory
9420         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9421
9422         local dir2=$MOUNT/$tdir-2
9423         mkdir $dir2 || error "mkdir $dir2 failed"
9424         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9425                 error "$dir2 shouldn't have LOV EA"
9426
9427         # set a new striping pattern on root directory
9428         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9429         local new_def_stripe_size=$((def_stripe_size * 2))
9430         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9431                 error "set stripe size on $MOUNT failed"
9432
9433         # new file created in $dir2 should inherit the new stripe size from
9434         # the filesystem default
9435         local file2=$dir2/$tfile-2
9436         touch $file2 || error "touch $file2 failed"
9437
9438         local file2_stripe_size=$($LFS getstripe -S $file2)
9439         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9440         {
9441                 echo "file2_stripe_size: '$file2_stripe_size'"
9442                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9443                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9444         }
9445
9446         local dir3=$MOUNT/$tdir-3
9447         mkdir $dir3 || error "mkdir $dir3 failed"
9448         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9449         # the root layout, which is the actual default layout that will be used
9450         # when new files are created in $dir3.
9451         local dir3_layout=$(get_layout_param $dir3)
9452         local root_dir_layout=$(get_layout_param $MOUNT)
9453         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9454         {
9455                 echo "dir3_layout: '$dir3_layout'"
9456                 echo "root_dir_layout: '$root_dir_layout'"
9457                 error "$dir3 should show the default layout from $MOUNT"
9458         }
9459
9460         # set OST pool on root directory
9461         local pool=$TESTNAME
9462         pool_add $pool || error "add $pool failed"
9463         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9464                 error "add targets to $pool failed"
9465
9466         $LFS setstripe -p $pool $MOUNT ||
9467                 error "set OST pool on $MOUNT failed"
9468
9469         # new file created in $dir3 should inherit the pool from
9470         # the filesystem default
9471         local file3=$dir3/$tfile-3
9472         touch $file3 || error "touch $file3 failed"
9473
9474         local file3_pool=$($LFS getstripe -p $file3)
9475         [[ "$file3_pool" = "$pool" ]] ||
9476                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9477
9478         local dir4=$MOUNT/$tdir-4
9479         mkdir $dir4 || error "mkdir $dir4 failed"
9480         local dir4_layout=$(get_layout_param $dir4)
9481         root_dir_layout=$(get_layout_param $MOUNT)
9482         echo "$LFS getstripe -d $dir4"
9483         $LFS getstripe -d $dir4
9484         echo "$LFS getstripe -d $MOUNT"
9485         $LFS getstripe -d $MOUNT
9486         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9487         {
9488                 echo "dir4_layout: '$dir4_layout'"
9489                 echo "root_dir_layout: '$root_dir_layout'"
9490                 error "$dir4 should show the default layout from $MOUNT"
9491         }
9492
9493         # new file created in $dir4 should inherit the pool from
9494         # the filesystem default
9495         local file4=$dir4/$tfile-4
9496         touch $file4 || error "touch $file4 failed"
9497
9498         local file4_pool=$($LFS getstripe -p $file4)
9499         [[ "$file4_pool" = "$pool" ]] ||
9500                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9501
9502         # new subdirectory under non-root directory should inherit
9503         # the default layout from its parent directory
9504         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9505                 error "set directory layout on $dir4 failed"
9506
9507         local dir5=$dir4/$tdir-5
9508         mkdir $dir5 || error "mkdir $dir5 failed"
9509
9510         dir4_layout=$(get_layout_param $dir4)
9511         local dir5_layout=$(get_layout_param $dir5)
9512         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9513         {
9514                 echo "dir4_layout: '$dir4_layout'"
9515                 echo "dir5_layout: '$dir5_layout'"
9516                 error "$dir5 should inherit the default layout from $dir4"
9517         }
9518
9519         # though subdir under ROOT doesn't inherit default layout, but
9520         # its sub dir/file should be created with default layout.
9521         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9522         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9523                 skip "Need MDS version at least 2.12.59"
9524
9525         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9526         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9527         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9528
9529         if [ $default_lmv_hash == "none" ]; then
9530                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9531         else
9532                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9533                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9534         fi
9535
9536         $LFS setdirstripe -D -c 2 $MOUNT ||
9537                 error "setdirstripe -D -c 2 failed"
9538         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9539         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9540         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9541
9542         # $dir4 layout includes pool
9543         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9544         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9545                 error "pool lost on setstripe"
9546         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9547         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9548                 error "pool lost on compound layout setstripe"
9549 }
9550 run_test 65n "don't inherit default layout from root for new subdirectories"
9551
9552 # bug 2543 - update blocks count on client
9553 test_66() {
9554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9555
9556         COUNT=${COUNT:-8}
9557         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9558         sync; sync_all_data; sync; sync_all_data
9559         cancel_lru_locks osc
9560         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9561         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9562 }
9563 run_test 66 "update inode blocks count on client ==============="
9564
9565 meminfo() {
9566         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9567 }
9568
9569 swap_used() {
9570         swapon -s | awk '($1 == "'$1'") { print $4 }'
9571 }
9572
9573 # bug5265, obdfilter oa2dentry return -ENOENT
9574 # #define OBD_FAIL_SRV_ENOENT 0x217
9575 test_69() {
9576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9577         remote_ost_nodsh && skip "remote OST with nodsh"
9578
9579         f="$DIR/$tfile"
9580         $LFS setstripe -c 1 -i 0 $f
9581
9582         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9583
9584         do_facet ost1 lctl set_param fail_loc=0x217
9585         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9586         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9587
9588         do_facet ost1 lctl set_param fail_loc=0
9589         $DIRECTIO write $f 0 2 || error "write error"
9590
9591         cancel_lru_locks osc
9592         $DIRECTIO read $f 0 1 || error "read error"
9593
9594         do_facet ost1 lctl set_param fail_loc=0x217
9595         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9596
9597         do_facet ost1 lctl set_param fail_loc=0
9598         rm -f $f
9599 }
9600 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9601
9602 test_71() {
9603         test_mkdir $DIR/$tdir
9604         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9605         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9606 }
9607 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9608
9609 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9611         [ "$RUNAS_ID" = "$UID" ] &&
9612                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9613         # Check that testing environment is properly set up. Skip if not
9614         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9615                 skip_env "User $RUNAS_ID does not exist - skipping"
9616
9617         touch $DIR/$tfile
9618         chmod 777 $DIR/$tfile
9619         chmod ug+s $DIR/$tfile
9620         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9621                 error "$RUNAS dd $DIR/$tfile failed"
9622         # See if we are still setuid/sgid
9623         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9624                 error "S/gid is not dropped on write"
9625         # Now test that MDS is updated too
9626         cancel_lru_locks mdc
9627         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9628                 error "S/gid is not dropped on MDS"
9629         rm -f $DIR/$tfile
9630 }
9631 run_test 72a "Test that remove suid works properly (bug5695) ===="
9632
9633 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9634         local perm
9635
9636         [ "$RUNAS_ID" = "$UID" ] &&
9637                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9638         [ "$RUNAS_ID" -eq 0 ] &&
9639                 skip_env "RUNAS_ID = 0 -- skipping"
9640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9641         # Check that testing environment is properly set up. Skip if not
9642         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9643                 skip_env "User $RUNAS_ID does not exist - skipping"
9644
9645         touch $DIR/${tfile}-f{g,u}
9646         test_mkdir $DIR/${tfile}-dg
9647         test_mkdir $DIR/${tfile}-du
9648         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9649         chmod g+s $DIR/${tfile}-{f,d}g
9650         chmod u+s $DIR/${tfile}-{f,d}u
9651         for perm in 777 2777 4777; do
9652                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9653                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9654                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9655                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9656         done
9657         true
9658 }
9659 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9660
9661 # bug 3462 - multiple simultaneous MDC requests
9662 test_73() {
9663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9664
9665         test_mkdir $DIR/d73-1
9666         test_mkdir $DIR/d73-2
9667         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9668         pid1=$!
9669
9670         lctl set_param fail_loc=0x80000129
9671         $MULTIOP $DIR/d73-1/f73-2 Oc &
9672         sleep 1
9673         lctl set_param fail_loc=0
9674
9675         $MULTIOP $DIR/d73-2/f73-3 Oc &
9676         pid3=$!
9677
9678         kill -USR1 $pid1
9679         wait $pid1 || return 1
9680
9681         sleep 25
9682
9683         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9684         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9685         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9686
9687         rm -rf $DIR/d73-*
9688 }
9689 run_test 73 "multiple MDC requests (should not deadlock)"
9690
9691 test_74a() { # bug 6149, 6184
9692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9693
9694         touch $DIR/f74a
9695         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9696         #
9697         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9698         # will spin in a tight reconnection loop
9699         $LCTL set_param fail_loc=0x8000030e
9700         # get any lock that won't be difficult - lookup works.
9701         ls $DIR/f74a
9702         $LCTL set_param fail_loc=0
9703         rm -f $DIR/f74a
9704         true
9705 }
9706 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9707
9708 test_74b() { # bug 13310
9709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9710
9711         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9712         #
9713         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9714         # will spin in a tight reconnection loop
9715         $LCTL set_param fail_loc=0x8000030e
9716         # get a "difficult" lock
9717         touch $DIR/f74b
9718         $LCTL set_param fail_loc=0
9719         rm -f $DIR/f74b
9720         true
9721 }
9722 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9723
9724 test_74c() {
9725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9726
9727         #define OBD_FAIL_LDLM_NEW_LOCK
9728         $LCTL set_param fail_loc=0x319
9729         touch $DIR/$tfile && error "touch successful"
9730         $LCTL set_param fail_loc=0
9731         true
9732 }
9733 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9734
9735 slab_lic=/sys/kernel/slab/lustre_inode_cache
9736 num_objects() {
9737         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9738         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9739                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9740 }
9741
9742 test_76a() { # Now for b=20433, added originally in b=1443
9743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9744
9745         cancel_lru_locks osc
9746         # there may be some slab objects cached per core
9747         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9748         local before=$(num_objects)
9749         local count=$((512 * cpus))
9750         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9751         local margin=$((count / 10))
9752         if [[ -f $slab_lic/aliases ]]; then
9753                 local aliases=$(cat $slab_lic/aliases)
9754                 (( aliases > 0 )) && margin=$((margin * aliases))
9755         fi
9756
9757         echo "before slab objects: $before"
9758         for i in $(seq $count); do
9759                 touch $DIR/$tfile
9760                 rm -f $DIR/$tfile
9761         done
9762         cancel_lru_locks osc
9763         local after=$(num_objects)
9764         echo "created: $count, after slab objects: $after"
9765         # shared slab counts are not very accurate, allow significant margin
9766         # the main goal is that the cache growth is not permanently > $count
9767         while (( after > before + margin )); do
9768                 sleep 1
9769                 after=$(num_objects)
9770                 wait=$((wait + 1))
9771                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9772                 if (( wait > 60 )); then
9773                         error "inode slab grew from $before+$margin to $after"
9774                 fi
9775         done
9776 }
9777 run_test 76a "confirm clients recycle inodes properly ===="
9778
9779 test_76b() {
9780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9781         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9782
9783         local count=512
9784         local before=$(num_objects)
9785
9786         for i in $(seq $count); do
9787                 mkdir $DIR/$tdir
9788                 rmdir $DIR/$tdir
9789         done
9790
9791         local after=$(num_objects)
9792         local wait=0
9793
9794         while (( after > before )); do
9795                 sleep 1
9796                 after=$(num_objects)
9797                 wait=$((wait + 1))
9798                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9799                 if (( wait > 60 )); then
9800                         error "inode slab grew from $before to $after"
9801                 fi
9802         done
9803
9804         echo "slab objects before: $before, after: $after"
9805 }
9806 run_test 76b "confirm clients recycle directory inodes properly ===="
9807
9808 export ORIG_CSUM=""
9809 set_checksums()
9810 {
9811         # Note: in sptlrpc modes which enable its own bulk checksum, the
9812         # original crc32_le bulk checksum will be automatically disabled,
9813         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9814         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9815         # In this case set_checksums() will not be no-op, because sptlrpc
9816         # bulk checksum will be enabled all through the test.
9817
9818         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9819         lctl set_param -n osc.*.checksums $1
9820         return 0
9821 }
9822
9823 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9824                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9825 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9826                              tr -d [] | head -n1)}
9827 set_checksum_type()
9828 {
9829         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9830         rc=$?
9831         log "set checksum type to $1, rc = $rc"
9832         return $rc
9833 }
9834
9835 get_osc_checksum_type()
9836 {
9837         # arugment 1: OST name, like OST0000
9838         ost=$1
9839         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9840                         sed 's/.*\[\(.*\)\].*/\1/g')
9841         rc=$?
9842         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9843         echo $checksum_type
9844 }
9845
9846 F77_TMP=$TMP/f77-temp
9847 F77SZ=8
9848 setup_f77() {
9849         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9850                 error "error writing to $F77_TMP"
9851 }
9852
9853 test_77a() { # bug 10889
9854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9855         $GSS && skip_env "could not run with gss"
9856
9857         [ ! -f $F77_TMP ] && setup_f77
9858         set_checksums 1
9859         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9860         set_checksums 0
9861         rm -f $DIR/$tfile
9862 }
9863 run_test 77a "normal checksum read/write operation"
9864
9865 test_77b() { # bug 10889
9866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9867         $GSS && skip_env "could not run with gss"
9868
9869         [ ! -f $F77_TMP ] && setup_f77
9870         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9871         $LCTL set_param fail_loc=0x80000409
9872         set_checksums 1
9873
9874         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9875                 error "dd error: $?"
9876         $LCTL set_param fail_loc=0
9877
9878         for algo in $CKSUM_TYPES; do
9879                 cancel_lru_locks osc
9880                 set_checksum_type $algo
9881                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9882                 $LCTL set_param fail_loc=0x80000408
9883                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9884                 $LCTL set_param fail_loc=0
9885         done
9886         set_checksums 0
9887         set_checksum_type $ORIG_CSUM_TYPE
9888         rm -f $DIR/$tfile
9889 }
9890 run_test 77b "checksum error on client write, read"
9891
9892 cleanup_77c() {
9893         trap 0
9894         set_checksums 0
9895         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9896         $check_ost &&
9897                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9898         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9899         $check_ost && [ -n "$ost_file_prefix" ] &&
9900                 do_facet ost1 rm -f ${ost_file_prefix}\*
9901 }
9902
9903 test_77c() {
9904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9905         $GSS && skip_env "could not run with gss"
9906         remote_ost_nodsh && skip "remote OST with nodsh"
9907
9908         local bad1
9909         local osc_file_prefix
9910         local osc_file
9911         local check_ost=false
9912         local ost_file_prefix
9913         local ost_file
9914         local orig_cksum
9915         local dump_cksum
9916         local fid
9917
9918         # ensure corruption will occur on first OSS/OST
9919         $LFS setstripe -i 0 $DIR/$tfile
9920
9921         [ ! -f $F77_TMP ] && setup_f77
9922         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9923                 error "dd write error: $?"
9924         fid=$($LFS path2fid $DIR/$tfile)
9925
9926         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9927         then
9928                 check_ost=true
9929                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9930                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9931         else
9932                 echo "OSS do not support bulk pages dump upon error"
9933         fi
9934
9935         osc_file_prefix=$($LCTL get_param -n debug_path)
9936         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9937
9938         trap cleanup_77c EXIT
9939
9940         set_checksums 1
9941         # enable bulk pages dump upon error on Client
9942         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9943         # enable bulk pages dump upon error on OSS
9944         $check_ost &&
9945                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9946
9947         # flush Client cache to allow next read to reach OSS
9948         cancel_lru_locks osc
9949
9950         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9951         $LCTL set_param fail_loc=0x80000408
9952         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9953         $LCTL set_param fail_loc=0
9954
9955         rm -f $DIR/$tfile
9956
9957         # check cksum dump on Client
9958         osc_file=$(ls ${osc_file_prefix}*)
9959         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9960         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9961         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9962         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9963         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9964                      cksum)
9965         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9966         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9967                 error "dump content does not match on Client"
9968
9969         $check_ost || skip "No need to check cksum dump on OSS"
9970
9971         # check cksum dump on OSS
9972         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9973         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9974         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9975         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9976         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9977                 error "dump content does not match on OSS"
9978
9979         cleanup_77c
9980 }
9981 run_test 77c "checksum error on client read with debug"
9982
9983 test_77d() { # bug 10889
9984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9985         $GSS && skip_env "could not run with gss"
9986
9987         stack_trap "rm -f $DIR/$tfile"
9988         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9989         $LCTL set_param fail_loc=0x80000409
9990         set_checksums 1
9991         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9992                 error "direct write: rc=$?"
9993         $LCTL set_param fail_loc=0
9994         set_checksums 0
9995
9996         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9997         $LCTL set_param fail_loc=0x80000408
9998         set_checksums 1
9999         cancel_lru_locks osc
10000         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10001                 error "direct read: rc=$?"
10002         $LCTL set_param fail_loc=0
10003         set_checksums 0
10004 }
10005 run_test 77d "checksum error on OST direct write, read"
10006
10007 test_77f() { # bug 10889
10008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10009         $GSS && skip_env "could not run with gss"
10010
10011         set_checksums 1
10012         stack_trap "rm -f $DIR/$tfile"
10013         for algo in $CKSUM_TYPES; do
10014                 cancel_lru_locks osc
10015                 set_checksum_type $algo
10016                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10017                 $LCTL set_param fail_loc=0x409
10018                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10019                         error "direct write succeeded"
10020                 $LCTL set_param fail_loc=0
10021         done
10022         set_checksum_type $ORIG_CSUM_TYPE
10023         set_checksums 0
10024 }
10025 run_test 77f "repeat checksum error on write (expect error)"
10026
10027 test_77g() { # bug 10889
10028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10029         $GSS && skip_env "could not run with gss"
10030         remote_ost_nodsh && skip "remote OST with nodsh"
10031
10032         [ ! -f $F77_TMP ] && setup_f77
10033
10034         local file=$DIR/$tfile
10035         stack_trap "rm -f $file" EXIT
10036
10037         $LFS setstripe -c 1 -i 0 $file
10038         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10039         do_facet ost1 lctl set_param fail_loc=0x8000021a
10040         set_checksums 1
10041         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10042                 error "write error: rc=$?"
10043         do_facet ost1 lctl set_param fail_loc=0
10044         set_checksums 0
10045
10046         cancel_lru_locks osc
10047         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10048         do_facet ost1 lctl set_param fail_loc=0x8000021b
10049         set_checksums 1
10050         cmp $F77_TMP $file || error "file compare failed"
10051         do_facet ost1 lctl set_param fail_loc=0
10052         set_checksums 0
10053 }
10054 run_test 77g "checksum error on OST write, read"
10055
10056 test_77k() { # LU-10906
10057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10058         $GSS && skip_env "could not run with gss"
10059
10060         local cksum_param="osc.$FSNAME*.checksums"
10061         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10062         local checksum
10063         local i
10064
10065         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10066         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10067         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10068
10069         for i in 0 1; do
10070                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10071                         error "failed to set checksum=$i on MGS"
10072                 wait_update $HOSTNAME "$get_checksum" $i
10073                 #remount
10074                 echo "remount client, checksum should be $i"
10075                 remount_client $MOUNT || error "failed to remount client"
10076                 checksum=$(eval $get_checksum)
10077                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10078         done
10079         # remove persistent param to avoid races with checksum mountopt below
10080         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10081                 error "failed to delete checksum on MGS"
10082
10083         for opt in "checksum" "nochecksum"; do
10084                 #remount with mount option
10085                 echo "remount client with option $opt, checksum should be $i"
10086                 umount_client $MOUNT || error "failed to umount client"
10087                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10088                         error "failed to mount client with option '$opt'"
10089                 checksum=$(eval $get_checksum)
10090                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10091                 i=$((i - 1))
10092         done
10093
10094         remount_client $MOUNT || error "failed to remount client"
10095 }
10096 run_test 77k "enable/disable checksum correctly"
10097
10098 test_77l() {
10099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10100         $GSS && skip_env "could not run with gss"
10101
10102         set_checksums 1
10103         stack_trap "set_checksums $ORIG_CSUM" EXIT
10104         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10105
10106         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10107
10108         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10109         for algo in $CKSUM_TYPES; do
10110                 set_checksum_type $algo || error "fail to set checksum type $algo"
10111                 osc_algo=$(get_osc_checksum_type OST0000)
10112                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10113
10114                 # no locks, no reqs to let the connection idle
10115                 cancel_lru_locks osc
10116                 lru_resize_disable osc
10117                 wait_osc_import_state client ost1 IDLE
10118
10119                 # ensure ost1 is connected
10120                 stat $DIR/$tfile >/dev/null || error "can't stat"
10121                 wait_osc_import_state client ost1 FULL
10122
10123                 osc_algo=$(get_osc_checksum_type OST0000)
10124                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10125         done
10126         return 0
10127 }
10128 run_test 77l "preferred checksum type is remembered after reconnected"
10129
10130 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10131 rm -f $F77_TMP
10132 unset F77_TMP
10133
10134 test_77m() {
10135         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10136                 skip "Need at least version 2.14.52"
10137         local param=checksum_speed
10138
10139         $LCTL get_param $param || error "reading $param failed"
10140
10141         csum_speeds=$($LCTL get_param -n $param)
10142
10143         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10144                 error "known checksum types are missing"
10145 }
10146 run_test 77m "Verify checksum_speed is correctly read"
10147
10148 check_filefrag_77n() {
10149         local nr_ext=0
10150         local starts=()
10151         local ends=()
10152
10153         while read extidx a b start end rest; do
10154                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10155                         nr_ext=$(( $nr_ext + 1 ))
10156                         starts+=( ${start%..} )
10157                         ends+=( ${end%:} )
10158                 fi
10159         done < <( filefrag -sv $1 )
10160
10161         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10162         return 1
10163 }
10164
10165 test_77n() {
10166         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10167
10168         touch $DIR/$tfile
10169         $TRUNCATE $DIR/$tfile 0
10170         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10171         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10172         check_filefrag_77n $DIR/$tfile ||
10173                 skip "$tfile blocks not contiguous around hole"
10174
10175         set_checksums 1
10176         stack_trap "set_checksums $ORIG_CSUM" EXIT
10177         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10178         stack_trap "rm -f $DIR/$tfile"
10179
10180         for algo in $CKSUM_TYPES; do
10181                 if [[ "$algo" =~ ^t10 ]]; then
10182                         set_checksum_type $algo ||
10183                                 error "fail to set checksum type $algo"
10184                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10185                                 error "fail to read $tfile with $algo"
10186                 fi
10187         done
10188         rm -f $DIR/$tfile
10189         return 0
10190 }
10191 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10192
10193 test_77o() {
10194         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10195                 skip "Need MDS version at least 2.14.55"
10196         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10197                 skip "Need OST version at least 2.14.55"
10198         local ofd=obdfilter
10199         local mdt=mdt
10200
10201         # print OST checksum_type
10202         echo "$ofd.$FSNAME-*.checksum_type:"
10203         do_nodes $(comma_list $(osts_nodes)) \
10204                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10205
10206         # print MDT checksum_type
10207         echo "$mdt.$FSNAME-*.checksum_type:"
10208         do_nodes $(comma_list $(mdts_nodes)) \
10209                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10210
10211         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10212                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10213
10214         (( $o_count == $OSTCOUNT )) ||
10215                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10216
10217         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10218                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10219
10220         (( $m_count == $MDSCOUNT )) ||
10221                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10222 }
10223 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10224
10225 cleanup_test_78() {
10226         trap 0
10227         rm -f $DIR/$tfile
10228 }
10229
10230 test_78() { # bug 10901
10231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10232         remote_ost || skip_env "local OST"
10233
10234         NSEQ=5
10235         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10236         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10237         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10238         echo "MemTotal: $MEMTOTAL"
10239
10240         # reserve 256MB of memory for the kernel and other running processes,
10241         # and then take 1/2 of the remaining memory for the read/write buffers.
10242         if [ $MEMTOTAL -gt 512 ] ;then
10243                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10244         else
10245                 # for those poor memory-starved high-end clusters...
10246                 MEMTOTAL=$((MEMTOTAL / 2))
10247         fi
10248         echo "Mem to use for directio: $MEMTOTAL"
10249
10250         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10251         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10252         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10253         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10254                 head -n1)
10255         echo "Smallest OST: $SMALLESTOST"
10256         [[ $SMALLESTOST -lt 10240 ]] &&
10257                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10258
10259         trap cleanup_test_78 EXIT
10260
10261         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10262                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10263
10264         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10265         echo "File size: $F78SIZE"
10266         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10267         for i in $(seq 1 $NSEQ); do
10268                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10269                 echo directIO rdwr round $i of $NSEQ
10270                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10271         done
10272
10273         cleanup_test_78
10274 }
10275 run_test 78 "handle large O_DIRECT writes correctly ============"
10276
10277 test_79() { # bug 12743
10278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10279
10280         wait_delete_completed
10281
10282         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10283         BKFREE=$(calc_osc_kbytes kbytesfree)
10284         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10285
10286         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10287         DFTOTAL=`echo $STRING | cut -d, -f1`
10288         DFUSED=`echo $STRING  | cut -d, -f2`
10289         DFAVAIL=`echo $STRING | cut -d, -f3`
10290         DFFREE=$(($DFTOTAL - $DFUSED))
10291
10292         ALLOWANCE=$((64 * $OSTCOUNT))
10293
10294         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10295            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10296                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10297         fi
10298         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10299            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10300                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10301         fi
10302         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10303            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10304                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10305         fi
10306 }
10307 run_test 79 "df report consistency check ======================="
10308
10309 test_80() { # bug 10718
10310         remote_ost_nodsh && skip "remote OST with nodsh"
10311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10312
10313         # relax strong synchronous semantics for slow backends like ZFS
10314         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10315                 local soc="obdfilter.*.sync_lock_cancel"
10316                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10317
10318                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10319                 if [ -z "$save" ]; then
10320                         soc="obdfilter.*.sync_on_lock_cancel"
10321                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10322                 fi
10323
10324                 if [ "$save" != "never" ]; then
10325                         local hosts=$(comma_list $(osts_nodes))
10326
10327                         do_nodes $hosts $LCTL set_param $soc=never
10328                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10329                 fi
10330         fi
10331
10332         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10333         sync; sleep 1; sync
10334         local before=$(date +%s)
10335         cancel_lru_locks osc
10336         local after=$(date +%s)
10337         local diff=$((after - before))
10338         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10339
10340         rm -f $DIR/$tfile
10341 }
10342 run_test 80 "Page eviction is equally fast at high offsets too"
10343
10344 test_81a() { # LU-456
10345         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10346         remote_ost_nodsh && skip "remote OST with nodsh"
10347
10348         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10349         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10350         do_facet ost1 lctl set_param fail_loc=0x80000228
10351
10352         # write should trigger a retry and success
10353         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10354         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10355         RC=$?
10356         if [ $RC -ne 0 ] ; then
10357                 error "write should success, but failed for $RC"
10358         fi
10359 }
10360 run_test 81a "OST should retry write when get -ENOSPC ==============="
10361
10362 test_81b() { # LU-456
10363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10364         remote_ost_nodsh && skip "remote OST with nodsh"
10365
10366         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10367         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10368         do_facet ost1 lctl set_param fail_loc=0x228
10369
10370         # write should retry several times and return -ENOSPC finally
10371         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10372         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10373         RC=$?
10374         ENOSPC=28
10375         if [ $RC -ne $ENOSPC ] ; then
10376                 error "dd should fail for -ENOSPC, but succeed."
10377         fi
10378 }
10379 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10380
10381 test_99() {
10382         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10383
10384         test_mkdir $DIR/$tdir.cvsroot
10385         chown $RUNAS_ID $DIR/$tdir.cvsroot
10386
10387         cd $TMP
10388         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10389
10390         cd /etc/init.d
10391         # some versions of cvs import exit(1) when asked to import links or
10392         # files they can't read.  ignore those files.
10393         local toignore=$(find . -type l -printf '-I %f\n' -o \
10394                          ! -perm /4 -printf '-I %f\n')
10395         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10396                 $tdir.reposname vtag rtag
10397
10398         cd $DIR
10399         test_mkdir $DIR/$tdir.reposname
10400         chown $RUNAS_ID $DIR/$tdir.reposname
10401         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10402
10403         cd $DIR/$tdir.reposname
10404         $RUNAS touch foo99
10405         $RUNAS cvs add -m 'addmsg' foo99
10406         $RUNAS cvs update
10407         $RUNAS cvs commit -m 'nomsg' foo99
10408         rm -fr $DIR/$tdir.cvsroot
10409 }
10410 run_test 99 "cvs strange file/directory operations"
10411
10412 test_100() {
10413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10414         [[ "$NETTYPE" =~ tcp ]] ||
10415                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10416         remote_ost_nodsh && skip "remote OST with nodsh"
10417         remote_mds_nodsh && skip "remote MDS with nodsh"
10418         remote_servers ||
10419                 skip "useless for local single node setup"
10420
10421         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10422                 [ "$PROT" != "tcp" ] && continue
10423                 RPORT=$(echo $REMOTE | cut -d: -f2)
10424                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10425
10426                 rc=0
10427                 LPORT=`echo $LOCAL | cut -d: -f2`
10428                 if [ $LPORT -ge 1024 ]; then
10429                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10430                         netstat -tna
10431                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10432                 fi
10433         done
10434         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10435 }
10436 run_test 100 "check local port using privileged port ==========="
10437
10438 function get_named_value()
10439 {
10440     local tag=$1
10441
10442     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10443 }
10444
10445 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10446                    awk '/^max_cached_mb/ { print $2 }')
10447
10448 cleanup_101a() {
10449         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10450         trap 0
10451 }
10452
10453 test_101a() {
10454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10455
10456         local s
10457         local discard
10458         local nreads=10000
10459         local cache_limit=32
10460
10461         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10462         trap cleanup_101a EXIT
10463         $LCTL set_param -n llite.*.read_ahead_stats=0
10464         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10465
10466         #
10467         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10468         #
10469         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10470         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10471
10472         discard=0
10473         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10474                    get_named_value 'read.but.discarded'); do
10475                         discard=$(($discard + $s))
10476         done
10477         cleanup_101a
10478
10479         $LCTL get_param osc.*-osc*.rpc_stats
10480         $LCTL get_param llite.*.read_ahead_stats
10481
10482         # Discard is generally zero, but sometimes a few random reads line up
10483         # and trigger larger readahead, which is wasted & leads to discards.
10484         if [[ $(($discard)) -gt $nreads ]]; then
10485                 error "too many ($discard) discarded pages"
10486         fi
10487         rm -f $DIR/$tfile || true
10488 }
10489 run_test 101a "check read-ahead for random reads"
10490
10491 setup_test101bc() {
10492         test_mkdir $DIR/$tdir
10493         local ssize=$1
10494         local FILE_LENGTH=$2
10495         STRIPE_OFFSET=0
10496
10497         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10498
10499         local list=$(comma_list $(osts_nodes))
10500         set_osd_param $list '' read_cache_enable 0
10501         set_osd_param $list '' writethrough_cache_enable 0
10502
10503         trap cleanup_test101bc EXIT
10504         # prepare the read-ahead file
10505         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10506
10507         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10508                                 count=$FILE_SIZE_MB 2> /dev/null
10509
10510 }
10511
10512 cleanup_test101bc() {
10513         trap 0
10514         rm -rf $DIR/$tdir
10515         rm -f $DIR/$tfile
10516
10517         local list=$(comma_list $(osts_nodes))
10518         set_osd_param $list '' read_cache_enable 1
10519         set_osd_param $list '' writethrough_cache_enable 1
10520 }
10521
10522 calc_total() {
10523         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10524 }
10525
10526 ra_check_101() {
10527         local read_size=$1
10528         local stripe_size=$2
10529         local stride_length=$((stripe_size / read_size))
10530         local stride_width=$((stride_length * OSTCOUNT))
10531         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
10532                                 (stride_width - stride_length) ))
10533         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
10534                   get_named_value 'read.but.discarded' | calc_total)
10535
10536         if [[ $discard -gt $discard_limit ]]; then
10537                 $LCTL get_param llite.*.read_ahead_stats
10538                 error "($discard) discarded pages with size (${read_size})"
10539         else
10540                 echo "Read-ahead success for size ${read_size}"
10541         fi
10542 }
10543
10544 test_101b() {
10545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10546         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10547
10548         local STRIPE_SIZE=1048576
10549         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10550
10551         if [ $SLOW == "yes" ]; then
10552                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10553         else
10554                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10555         fi
10556
10557         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10558
10559         # prepare the read-ahead file
10560         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10561         cancel_lru_locks osc
10562         for BIDX in 2 4 8 16 32 64 128 256
10563         do
10564                 local BSIZE=$((BIDX*4096))
10565                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10566                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10567                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10568                 $LCTL set_param -n llite.*.read_ahead_stats=0
10569                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10570                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10571                 cancel_lru_locks osc
10572                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10573         done
10574         cleanup_test101bc
10575         true
10576 }
10577 run_test 101b "check stride-io mode read-ahead ================="
10578
10579 test_101c() {
10580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10581
10582         local STRIPE_SIZE=1048576
10583         local FILE_LENGTH=$((STRIPE_SIZE*100))
10584         local nreads=10000
10585         local rsize=65536
10586         local osc_rpc_stats
10587
10588         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10589
10590         cancel_lru_locks osc
10591         $LCTL set_param osc.*.rpc_stats=0
10592         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10593         $LCTL get_param osc.*.rpc_stats
10594         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10595                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10596                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10597                 local size
10598
10599                 if [ $lines -le 20 ]; then
10600                         echo "continue debug"
10601                         continue
10602                 fi
10603                 for size in 1 2 4 8; do
10604                         local rpc=$(echo "$stats" |
10605                                     awk '($1 == "'$size':") {print $2; exit; }')
10606                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10607                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10608                 done
10609                 echo "$osc_rpc_stats check passed!"
10610         done
10611         cleanup_test101bc
10612         true
10613 }
10614 run_test 101c "check stripe_size aligned read-ahead"
10615
10616 test_101d() {
10617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10618
10619         local file=$DIR/$tfile
10620         local sz_MB=${FILESIZE_101d:-80}
10621         local ra_MB=${READAHEAD_MB:-40}
10622
10623         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10624         [ $free_MB -lt $sz_MB ] &&
10625                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10626
10627         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10628         $LFS setstripe -c -1 $file || error "setstripe failed"
10629
10630         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10631         echo Cancel LRU locks on lustre client to flush the client cache
10632         cancel_lru_locks osc
10633
10634         echo Disable read-ahead
10635         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10636         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10637         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10638         $LCTL get_param -n llite.*.max_read_ahead_mb
10639
10640         echo "Reading the test file $file with read-ahead disabled"
10641         local sz_KB=$((sz_MB * 1024 / 4))
10642         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10643         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10644         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10645                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10646
10647         echo "Cancel LRU locks on lustre client to flush the client cache"
10648         cancel_lru_locks osc
10649         echo Enable read-ahead with ${ra_MB}MB
10650         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10651
10652         echo "Reading the test file $file with read-ahead enabled"
10653         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10654                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10655
10656         echo "read-ahead disabled time read $raOFF"
10657         echo "read-ahead enabled time read $raON"
10658
10659         rm -f $file
10660         wait_delete_completed
10661
10662         # use awk for this check instead of bash because it handles decimals
10663         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10664                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10665 }
10666 run_test 101d "file read with and without read-ahead enabled"
10667
10668 test_101e() {
10669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10670
10671         local file=$DIR/$tfile
10672         local size_KB=500  #KB
10673         local count=100
10674         local bsize=1024
10675
10676         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10677         local need_KB=$((count * size_KB))
10678         [[ $free_KB -le $need_KB ]] &&
10679                 skip_env "Need free space $need_KB, have $free_KB"
10680
10681         echo "Creating $count ${size_KB}K test files"
10682         for ((i = 0; i < $count; i++)); do
10683                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10684         done
10685
10686         echo "Cancel LRU locks on lustre client to flush the client cache"
10687         cancel_lru_locks $OSC
10688
10689         echo "Reset readahead stats"
10690         $LCTL set_param -n llite.*.read_ahead_stats=0
10691
10692         for ((i = 0; i < $count; i++)); do
10693                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10694         done
10695
10696         $LCTL get_param llite.*.max_cached_mb
10697         $LCTL get_param llite.*.read_ahead_stats
10698         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10699                      get_named_value 'misses' | calc_total)
10700
10701         for ((i = 0; i < $count; i++)); do
10702                 rm -rf $file.$i 2>/dev/null
10703         done
10704
10705         #10000 means 20% reads are missing in readahead
10706         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10707 }
10708 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10709
10710 test_101f() {
10711         which iozone || skip_env "no iozone installed"
10712
10713         local old_debug=$($LCTL get_param debug)
10714         old_debug=${old_debug#*=}
10715         $LCTL set_param debug="reada mmap"
10716
10717         # create a test file
10718         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10719
10720         echo Cancel LRU locks on lustre client to flush the client cache
10721         cancel_lru_locks osc
10722
10723         echo Reset readahead stats
10724         $LCTL set_param -n llite.*.read_ahead_stats=0
10725
10726         echo mmap read the file with small block size
10727         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10728                 > /dev/null 2>&1
10729
10730         echo checking missing pages
10731         $LCTL get_param llite.*.read_ahead_stats
10732         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10733                         get_named_value 'misses' | calc_total)
10734
10735         $LCTL set_param debug="$old_debug"
10736         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10737         rm -f $DIR/$tfile
10738 }
10739 run_test 101f "check mmap read performance"
10740
10741 test_101g_brw_size_test() {
10742         local mb=$1
10743         local pages=$((mb * 1048576 / PAGE_SIZE))
10744         local file=$DIR/$tfile
10745
10746         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10747                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10748         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10749                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10750                         return 2
10751         done
10752
10753         stack_trap "rm -f $file" EXIT
10754         $LCTL set_param -n osc.*.rpc_stats=0
10755
10756         # 10 RPCs should be enough for the test
10757         local count=10
10758         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10759                 { error "dd write ${mb} MB blocks failed"; return 3; }
10760         cancel_lru_locks osc
10761         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10762                 { error "dd write ${mb} MB blocks failed"; return 4; }
10763
10764         # calculate number of full-sized read and write RPCs
10765         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10766                 sed -n '/pages per rpc/,/^$/p' |
10767                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10768                 END { print reads,writes }'))
10769         # allow one extra full-sized read RPC for async readahead
10770         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10771                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10772         [[ ${rpcs[1]} == $count ]] ||
10773                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10774 }
10775
10776 test_101g() {
10777         remote_ost_nodsh && skip "remote OST with nodsh"
10778
10779         local rpcs
10780         local osts=$(get_facets OST)
10781         local list=$(comma_list $(osts_nodes))
10782         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10783         local brw_size="obdfilter.*.brw_size"
10784
10785         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10786
10787         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10788
10789         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10790                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10791                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10792            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10793                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10794                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10795
10796                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10797                         suffix="M"
10798
10799                 if [[ $orig_mb -lt 16 ]]; then
10800                         save_lustre_params $osts "$brw_size" > $p
10801                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10802                                 error "set 16MB RPC size failed"
10803
10804                         echo "remount client to enable new RPC size"
10805                         remount_client $MOUNT || error "remount_client failed"
10806                 fi
10807
10808                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10809                 # should be able to set brw_size=12, but no rpc_stats for that
10810                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10811         fi
10812
10813         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10814
10815         if [[ $orig_mb -lt 16 ]]; then
10816                 restore_lustre_params < $p
10817                 remount_client $MOUNT || error "remount_client restore failed"
10818         fi
10819
10820         rm -f $p $DIR/$tfile
10821 }
10822 run_test 101g "Big bulk(4/16 MiB) readahead"
10823
10824 test_101h() {
10825         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10826
10827         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10828                 error "dd 70M file failed"
10829         echo Cancel LRU locks on lustre client to flush the client cache
10830         cancel_lru_locks osc
10831
10832         echo "Reset readahead stats"
10833         $LCTL set_param -n llite.*.read_ahead_stats 0
10834
10835         echo "Read 10M of data but cross 64M bundary"
10836         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10837         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10838                      get_named_value 'misses' | calc_total)
10839         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10840         rm -f $p $DIR/$tfile
10841 }
10842 run_test 101h "Readahead should cover current read window"
10843
10844 test_101i() {
10845         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10846                 error "dd 10M file failed"
10847
10848         local max_per_file_mb=$($LCTL get_param -n \
10849                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10850         cancel_lru_locks osc
10851         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10852         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10853                 error "set max_read_ahead_per_file_mb to 1 failed"
10854
10855         echo "Reset readahead stats"
10856         $LCTL set_param llite.*.read_ahead_stats=0
10857
10858         dd if=$DIR/$tfile of=/dev/null bs=2M
10859
10860         $LCTL get_param llite.*.read_ahead_stats
10861         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10862                      awk '/misses/ { print $2 }')
10863         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10864         rm -f $DIR/$tfile
10865 }
10866 run_test 101i "allow current readahead to exceed reservation"
10867
10868 test_101j() {
10869         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10870                 error "setstripe $DIR/$tfile failed"
10871         local file_size=$((1048576 * 16))
10872         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10873         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10874
10875         echo Disable read-ahead
10876         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10877
10878         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10879         for blk in $PAGE_SIZE 1048576 $file_size; do
10880                 cancel_lru_locks osc
10881                 echo "Reset readahead stats"
10882                 $LCTL set_param -n llite.*.read_ahead_stats=0
10883                 local count=$(($file_size / $blk))
10884                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10885                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10886                              get_named_value 'failed.to.fast.read' | calc_total)
10887                 $LCTL get_param -n llite.*.read_ahead_stats
10888                 [ $miss -eq $count ] || error "expected $count got $miss"
10889         done
10890
10891         rm -f $p $DIR/$tfile
10892 }
10893 run_test 101j "A complete read block should be submitted when no RA"
10894
10895 setup_test102() {
10896         test_mkdir $DIR/$tdir
10897         chown $RUNAS_ID $DIR/$tdir
10898         STRIPE_SIZE=65536
10899         STRIPE_OFFSET=1
10900         STRIPE_COUNT=$OSTCOUNT
10901         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10902
10903         trap cleanup_test102 EXIT
10904         cd $DIR
10905         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10906         cd $DIR/$tdir
10907         for num in 1 2 3 4; do
10908                 for count in $(seq 1 $STRIPE_COUNT); do
10909                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10910                                 local size=`expr $STRIPE_SIZE \* $num`
10911                                 local file=file"$num-$idx-$count"
10912                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10913                         done
10914                 done
10915         done
10916
10917         cd $DIR
10918         $1 tar cf $TMP/f102.tar $tdir --xattrs
10919 }
10920
10921 cleanup_test102() {
10922         trap 0
10923         rm -f $TMP/f102.tar
10924         rm -rf $DIR/d0.sanity/d102
10925 }
10926
10927 test_102a() {
10928         [ "$UID" != 0 ] && skip "must run as root"
10929         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10930                 skip_env "must have user_xattr"
10931
10932         [ -z "$(which setfattr 2>/dev/null)" ] &&
10933                 skip_env "could not find setfattr"
10934
10935         local testfile=$DIR/$tfile
10936
10937         touch $testfile
10938         echo "set/get xattr..."
10939         setfattr -n trusted.name1 -v value1 $testfile ||
10940                 error "setfattr -n trusted.name1=value1 $testfile failed"
10941         getfattr -n trusted.name1 $testfile 2> /dev/null |
10942           grep "trusted.name1=.value1" ||
10943                 error "$testfile missing trusted.name1=value1"
10944
10945         setfattr -n user.author1 -v author1 $testfile ||
10946                 error "setfattr -n user.author1=author1 $testfile failed"
10947         getfattr -n user.author1 $testfile 2> /dev/null |
10948           grep "user.author1=.author1" ||
10949                 error "$testfile missing trusted.author1=author1"
10950
10951         echo "listxattr..."
10952         setfattr -n trusted.name2 -v value2 $testfile ||
10953                 error "$testfile unable to set trusted.name2"
10954         setfattr -n trusted.name3 -v value3 $testfile ||
10955                 error "$testfile unable to set trusted.name3"
10956         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10957             grep "trusted.name" | wc -l) -eq 3 ] ||
10958                 error "$testfile missing 3 trusted.name xattrs"
10959
10960         setfattr -n user.author2 -v author2 $testfile ||
10961                 error "$testfile unable to set user.author2"
10962         setfattr -n user.author3 -v author3 $testfile ||
10963                 error "$testfile unable to set user.author3"
10964         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10965             grep "user.author" | wc -l) -eq 3 ] ||
10966                 error "$testfile missing 3 user.author xattrs"
10967
10968         echo "remove xattr..."
10969         setfattr -x trusted.name1 $testfile ||
10970                 error "$testfile error deleting trusted.name1"
10971         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10972                 error "$testfile did not delete trusted.name1 xattr"
10973
10974         setfattr -x user.author1 $testfile ||
10975                 error "$testfile error deleting user.author1"
10976         echo "set lustre special xattr ..."
10977         $LFS setstripe -c1 $testfile
10978         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10979                 awk -F "=" '/trusted.lov/ { print $2 }' )
10980         setfattr -n "trusted.lov" -v $lovea $testfile ||
10981                 error "$testfile doesn't ignore setting trusted.lov again"
10982         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10983                 error "$testfile allow setting invalid trusted.lov"
10984         rm -f $testfile
10985 }
10986 run_test 102a "user xattr test =================================="
10987
10988 check_102b_layout() {
10989         local layout="$*"
10990         local testfile=$DIR/$tfile
10991
10992         echo "test layout '$layout'"
10993         $LFS setstripe $layout $testfile || error "setstripe failed"
10994         $LFS getstripe -y $testfile
10995
10996         echo "get/set/list trusted.lov xattr ..." # b=10930
10997         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10998         [[ "$value" =~ "trusted.lov" ]] ||
10999                 error "can't get trusted.lov from $testfile"
11000         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11001                 error "getstripe failed"
11002
11003         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11004
11005         value=$(cut -d= -f2 <<<$value)
11006         # LU-13168: truncated xattr should fail if short lov_user_md header
11007         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11008                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11009         for len in $lens; do
11010                 echo "setfattr $len $testfile.2"
11011                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11012                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11013         done
11014         local stripe_size=$($LFS getstripe -S $testfile.2)
11015         local stripe_count=$($LFS getstripe -c $testfile.2)
11016         [[ $stripe_size -eq 65536 ]] ||
11017                 error "stripe size $stripe_size != 65536"
11018         [[ $stripe_count -eq $stripe_count_orig ]] ||
11019                 error "stripe count $stripe_count != $stripe_count_orig"
11020         rm $testfile $testfile.2
11021 }
11022
11023 test_102b() {
11024         [ -z "$(which setfattr 2>/dev/null)" ] &&
11025                 skip_env "could not find setfattr"
11026         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11027
11028         # check plain layout
11029         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11030
11031         # and also check composite layout
11032         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11033
11034 }
11035 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11036
11037 test_102c() {
11038         [ -z "$(which setfattr 2>/dev/null)" ] &&
11039                 skip_env "could not find setfattr"
11040         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11041
11042         # b10930: get/set/list lustre.lov xattr
11043         echo "get/set/list lustre.lov xattr ..."
11044         test_mkdir $DIR/$tdir
11045         chown $RUNAS_ID $DIR/$tdir
11046         local testfile=$DIR/$tdir/$tfile
11047         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11048                 error "setstripe failed"
11049         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11050                 error "getstripe failed"
11051         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11052         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11053
11054         local testfile2=${testfile}2
11055         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11056                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11057
11058         $RUNAS $MCREATE $testfile2
11059         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11060         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11061         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11062         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11063         [ $stripe_count -eq $STRIPECOUNT ] ||
11064                 error "stripe count $stripe_count != $STRIPECOUNT"
11065 }
11066 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11067
11068 compare_stripe_info1() {
11069         local stripe_index_all_zero=true
11070
11071         for num in 1 2 3 4; do
11072                 for count in $(seq 1 $STRIPE_COUNT); do
11073                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11074                                 local size=$((STRIPE_SIZE * num))
11075                                 local file=file"$num-$offset-$count"
11076                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11077                                 [[ $stripe_size -ne $size ]] &&
11078                                     error "$file: size $stripe_size != $size"
11079                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11080                                 # allow fewer stripes to be created, ORI-601
11081                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11082                                     error "$file: count $stripe_count != $count"
11083                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11084                                 [[ $stripe_index -ne 0 ]] &&
11085                                         stripe_index_all_zero=false
11086                         done
11087                 done
11088         done
11089         $stripe_index_all_zero &&
11090                 error "all files are being extracted starting from OST index 0"
11091         return 0
11092 }
11093
11094 have_xattrs_include() {
11095         tar --help | grep -q xattrs-include &&
11096                 echo --xattrs-include="lustre.*"
11097 }
11098
11099 test_102d() {
11100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11101         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11102
11103         XINC=$(have_xattrs_include)
11104         setup_test102
11105         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11106         cd $DIR/$tdir/$tdir
11107         compare_stripe_info1
11108 }
11109 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11110
11111 test_102f() {
11112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11113         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11114
11115         XINC=$(have_xattrs_include)
11116         setup_test102
11117         test_mkdir $DIR/$tdir.restore
11118         cd $DIR
11119         tar cf - --xattrs $tdir | tar xf - \
11120                 -C $DIR/$tdir.restore --xattrs $XINC
11121         cd $DIR/$tdir.restore/$tdir
11122         compare_stripe_info1
11123 }
11124 run_test 102f "tar copy files, not keep osts"
11125
11126 grow_xattr() {
11127         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11128                 skip "must have user_xattr"
11129         [ -z "$(which setfattr 2>/dev/null)" ] &&
11130                 skip_env "could not find setfattr"
11131         [ -z "$(which getfattr 2>/dev/null)" ] &&
11132                 skip_env "could not find getfattr"
11133
11134         local xsize=${1:-1024}  # in bytes
11135         local file=$DIR/$tfile
11136         local value="$(generate_string $xsize)"
11137         local xbig=trusted.big
11138         local toobig=$2
11139
11140         touch $file
11141         log "save $xbig on $file"
11142         if [ -z "$toobig" ]
11143         then
11144                 setfattr -n $xbig -v $value $file ||
11145                         error "saving $xbig on $file failed"
11146         else
11147                 setfattr -n $xbig -v $value $file &&
11148                         error "saving $xbig on $file succeeded"
11149                 return 0
11150         fi
11151
11152         local orig=$(get_xattr_value $xbig $file)
11153         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11154
11155         local xsml=trusted.sml
11156         log "save $xsml on $file"
11157         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11158
11159         local new=$(get_xattr_value $xbig $file)
11160         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11161
11162         log "grow $xsml on $file"
11163         setfattr -n $xsml -v "$value" $file ||
11164                 error "growing $xsml on $file failed"
11165
11166         new=$(get_xattr_value $xbig $file)
11167         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11168         log "$xbig still valid after growing $xsml"
11169
11170         rm -f $file
11171 }
11172
11173 test_102h() { # bug 15777
11174         grow_xattr 1024
11175 }
11176 run_test 102h "grow xattr from inside inode to external block"
11177
11178 test_102ha() {
11179         large_xattr_enabled || skip_env "ea_inode feature disabled"
11180
11181         echo "setting xattr of max xattr size: $(max_xattr_size)"
11182         grow_xattr $(max_xattr_size)
11183
11184         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11185         echo "This should fail:"
11186         grow_xattr $(($(max_xattr_size) + 10)) 1
11187 }
11188 run_test 102ha "grow xattr from inside inode to external inode"
11189
11190 test_102i() { # bug 17038
11191         [ -z "$(which getfattr 2>/dev/null)" ] &&
11192                 skip "could not find getfattr"
11193
11194         touch $DIR/$tfile
11195         ln -s $DIR/$tfile $DIR/${tfile}link
11196         getfattr -n trusted.lov $DIR/$tfile ||
11197                 error "lgetxattr on $DIR/$tfile failed"
11198         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11199                 grep -i "no such attr" ||
11200                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11201         rm -f $DIR/$tfile $DIR/${tfile}link
11202 }
11203 run_test 102i "lgetxattr test on symbolic link ============"
11204
11205 test_102j() {
11206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11207         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11208
11209         XINC=$(have_xattrs_include)
11210         setup_test102 "$RUNAS"
11211         chown $RUNAS_ID $DIR/$tdir
11212         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11213         cd $DIR/$tdir/$tdir
11214         compare_stripe_info1 "$RUNAS"
11215 }
11216 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11217
11218 test_102k() {
11219         [ -z "$(which setfattr 2>/dev/null)" ] &&
11220                 skip "could not find setfattr"
11221
11222         touch $DIR/$tfile
11223         # b22187 just check that does not crash for regular file.
11224         setfattr -n trusted.lov $DIR/$tfile
11225         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11226         local test_kdir=$DIR/$tdir
11227         test_mkdir $test_kdir
11228         local default_size=$($LFS getstripe -S $test_kdir)
11229         local default_count=$($LFS getstripe -c $test_kdir)
11230         local default_offset=$($LFS getstripe -i $test_kdir)
11231         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11232                 error 'dir setstripe failed'
11233         setfattr -n trusted.lov $test_kdir
11234         local stripe_size=$($LFS getstripe -S $test_kdir)
11235         local stripe_count=$($LFS getstripe -c $test_kdir)
11236         local stripe_offset=$($LFS getstripe -i $test_kdir)
11237         [ $stripe_size -eq $default_size ] ||
11238                 error "stripe size $stripe_size != $default_size"
11239         [ $stripe_count -eq $default_count ] ||
11240                 error "stripe count $stripe_count != $default_count"
11241         [ $stripe_offset -eq $default_offset ] ||
11242                 error "stripe offset $stripe_offset != $default_offset"
11243         rm -rf $DIR/$tfile $test_kdir
11244 }
11245 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11246
11247 test_102l() {
11248         [ -z "$(which getfattr 2>/dev/null)" ] &&
11249                 skip "could not find getfattr"
11250
11251         # LU-532 trusted. xattr is invisible to non-root
11252         local testfile=$DIR/$tfile
11253
11254         touch $testfile
11255
11256         echo "listxattr as user..."
11257         chown $RUNAS_ID $testfile
11258         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11259             grep -q "trusted" &&
11260                 error "$testfile trusted xattrs are user visible"
11261
11262         return 0;
11263 }
11264 run_test 102l "listxattr size test =================================="
11265
11266 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11267         local path=$DIR/$tfile
11268         touch $path
11269
11270         listxattr_size_check $path || error "listattr_size_check $path failed"
11271 }
11272 run_test 102m "Ensure listxattr fails on small bufffer ========"
11273
11274 cleanup_test102
11275
11276 getxattr() { # getxattr path name
11277         # Return the base64 encoding of the value of xattr name on path.
11278         local path=$1
11279         local name=$2
11280
11281         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11282         # file: $path
11283         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11284         #
11285         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11286
11287         getfattr --absolute-names --encoding=base64 --name=$name $path |
11288                 awk -F= -v name=$name '$1 == name {
11289                         print substr($0, index($0, "=") + 1);
11290         }'
11291 }
11292
11293 test_102n() { # LU-4101 mdt: protect internal xattrs
11294         [ -z "$(which setfattr 2>/dev/null)" ] &&
11295                 skip "could not find setfattr"
11296         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11297         then
11298                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11299         fi
11300
11301         local file0=$DIR/$tfile.0
11302         local file1=$DIR/$tfile.1
11303         local xattr0=$TMP/$tfile.0
11304         local xattr1=$TMP/$tfile.1
11305         local namelist="lov lma lmv link fid version som hsm"
11306         local name
11307         local value
11308
11309         rm -rf $file0 $file1 $xattr0 $xattr1
11310         touch $file0 $file1
11311
11312         # Get 'before' xattrs of $file1.
11313         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11314
11315         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11316                 namelist+=" lfsck_namespace"
11317         for name in $namelist; do
11318                 # Try to copy xattr from $file0 to $file1.
11319                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11320
11321                 setfattr --name=trusted.$name --value="$value" $file1 ||
11322                         error "setxattr 'trusted.$name' failed"
11323
11324                 # Try to set a garbage xattr.
11325                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11326
11327                 if [[ x$name == "xlov" ]]; then
11328                         setfattr --name=trusted.lov --value="$value" $file1 &&
11329                         error "setxattr invalid 'trusted.lov' success"
11330                 else
11331                         setfattr --name=trusted.$name --value="$value" $file1 ||
11332                                 error "setxattr invalid 'trusted.$name' failed"
11333                 fi
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         done
11340
11341         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11342         then
11343                 name="lfsck_ns"
11344                 # Try to copy xattr from $file0 to $file1.
11345                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11346
11347                 setfattr --name=trusted.$name --value="$value" $file1 ||
11348                         error "setxattr 'trusted.$name' failed"
11349
11350                 # Try to set a garbage xattr.
11351                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11352
11353                 setfattr --name=trusted.$name --value="$value" $file1 ||
11354                         error "setxattr 'trusted.$name' failed"
11355
11356                 # Try to remove the xattr from $file1. We don't care if this
11357                 # appears to succeed or fail, we just don't want there to be
11358                 # any changes or crashes.
11359                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11360         fi
11361
11362         # Get 'after' xattrs of file1.
11363         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11364
11365         if ! diff $xattr0 $xattr1; then
11366                 error "before and after xattrs of '$file1' differ"
11367         fi
11368
11369         rm -rf $file0 $file1 $xattr0 $xattr1
11370
11371         return 0
11372 }
11373 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11374
11375 test_102p() { # LU-4703 setxattr did not check ownership
11376         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11377                 skip "MDS needs to be at least 2.5.56"
11378
11379         local testfile=$DIR/$tfile
11380
11381         touch $testfile
11382
11383         echo "setfacl as user..."
11384         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11385         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11386
11387         echo "setfattr as user..."
11388         setfacl -m "u:$RUNAS_ID:---" $testfile
11389         $RUNAS setfattr -x system.posix_acl_access $testfile
11390         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11391 }
11392 run_test 102p "check setxattr(2) correctly fails without permission"
11393
11394 test_102q() {
11395         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11396                 skip "MDS needs to be at least 2.6.92"
11397
11398         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11399 }
11400 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11401
11402 test_102r() {
11403         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11404                 skip "MDS needs to be at least 2.6.93"
11405
11406         touch $DIR/$tfile || error "touch"
11407         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11408         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11409         rm $DIR/$tfile || error "rm"
11410
11411         #normal directory
11412         mkdir -p $DIR/$tdir || error "mkdir"
11413         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11414         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11415         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11416                 error "$testfile error deleting user.author1"
11417         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11418                 grep "user.$(basename $tdir)" &&
11419                 error "$tdir did not delete user.$(basename $tdir)"
11420         rmdir $DIR/$tdir || error "rmdir"
11421
11422         #striped directory
11423         test_mkdir $DIR/$tdir
11424         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11425         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11426         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11427                 error "$testfile error deleting user.author1"
11428         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11429                 grep "user.$(basename $tdir)" &&
11430                 error "$tdir did not delete user.$(basename $tdir)"
11431         rmdir $DIR/$tdir || error "rm striped dir"
11432 }
11433 run_test 102r "set EAs with empty values"
11434
11435 test_102s() {
11436         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11437                 skip "MDS needs to be at least 2.11.52"
11438
11439         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11440
11441         save_lustre_params client "llite.*.xattr_cache" > $save
11442
11443         for cache in 0 1; do
11444                 lctl set_param llite.*.xattr_cache=$cache
11445
11446                 rm -f $DIR/$tfile
11447                 touch $DIR/$tfile || error "touch"
11448                 for prefix in lustre security system trusted user; do
11449                         # Note getxattr() may fail with 'Operation not
11450                         # supported' or 'No such attribute' depending
11451                         # on prefix and cache.
11452                         getfattr -n $prefix.n102s $DIR/$tfile &&
11453                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11454                 done
11455         done
11456
11457         restore_lustre_params < $save
11458 }
11459 run_test 102s "getting nonexistent xattrs should fail"
11460
11461 test_102t() {
11462         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11463                 skip "MDS needs to be at least 2.11.52"
11464
11465         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11466
11467         save_lustre_params client "llite.*.xattr_cache" > $save
11468
11469         for cache in 0 1; do
11470                 lctl set_param llite.*.xattr_cache=$cache
11471
11472                 for buf_size in 0 256; do
11473                         rm -f $DIR/$tfile
11474                         touch $DIR/$tfile || error "touch"
11475                         setfattr -n user.multiop $DIR/$tfile
11476                         $MULTIOP $DIR/$tfile oa$buf_size ||
11477                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11478                 done
11479         done
11480
11481         restore_lustre_params < $save
11482 }
11483 run_test 102t "zero length xattr values handled correctly"
11484
11485 run_acl_subtest()
11486 {
11487     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11488     return $?
11489 }
11490
11491 test_103a() {
11492         [ "$UID" != 0 ] && skip "must run as root"
11493         $GSS && skip_env "could not run under gss"
11494         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11495                 skip_env "must have acl enabled"
11496         [ -z "$(which setfacl 2>/dev/null)" ] &&
11497                 skip_env "could not find setfacl"
11498         remote_mds_nodsh && skip "remote MDS with nodsh"
11499
11500         gpasswd -a daemon bin                           # LU-5641
11501         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11502
11503         declare -a identity_old
11504
11505         for num in $(seq $MDSCOUNT); do
11506                 switch_identity $num true || identity_old[$num]=$?
11507         done
11508
11509         SAVE_UMASK=$(umask)
11510         umask 0022
11511         mkdir -p $DIR/$tdir
11512         cd $DIR/$tdir
11513
11514         echo "performing cp ..."
11515         run_acl_subtest cp || error "run_acl_subtest cp failed"
11516         echo "performing getfacl-noacl..."
11517         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11518         echo "performing misc..."
11519         run_acl_subtest misc || error  "misc test failed"
11520         echo "performing permissions..."
11521         run_acl_subtest permissions || error "permissions failed"
11522         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11523         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11524                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11525                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11526         then
11527                 echo "performing permissions xattr..."
11528                 run_acl_subtest permissions_xattr ||
11529                         error "permissions_xattr failed"
11530         fi
11531         echo "performing setfacl..."
11532         run_acl_subtest setfacl || error  "setfacl test failed"
11533
11534         # inheritance test got from HP
11535         echo "performing inheritance..."
11536         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11537         chmod +x make-tree || error "chmod +x failed"
11538         run_acl_subtest inheritance || error "inheritance test failed"
11539         rm -f make-tree
11540
11541         echo "LU-974 ignore umask when acl is enabled..."
11542         run_acl_subtest 974 || error "LU-974 umask test failed"
11543         if [ $MDSCOUNT -ge 2 ]; then
11544                 run_acl_subtest 974_remote ||
11545                         error "LU-974 umask test failed under remote dir"
11546         fi
11547
11548         echo "LU-2561 newly created file is same size as directory..."
11549         if [ "$mds1_FSTYPE" != "zfs" ]; then
11550                 run_acl_subtest 2561 || error "LU-2561 test failed"
11551         else
11552                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11553         fi
11554
11555         run_acl_subtest 4924 || error "LU-4924 test failed"
11556
11557         cd $SAVE_PWD
11558         umask $SAVE_UMASK
11559
11560         for num in $(seq $MDSCOUNT); do
11561                 if [ "${identity_old[$num]}" = 1 ]; then
11562                         switch_identity $num false || identity_old[$num]=$?
11563                 fi
11564         done
11565 }
11566 run_test 103a "acl test"
11567
11568 test_103b() {
11569         declare -a pids
11570         local U
11571
11572         for U in {0..511}; do
11573                 {
11574                 local O=$(printf "%04o" $U)
11575
11576                 umask $(printf "%04o" $((511 ^ $O)))
11577                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11578                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11579
11580                 (( $S == ($O & 0666) )) ||
11581                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11582
11583                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11584                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11585                 (( $S == ($O & 0666) )) ||
11586                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11587
11588                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11589                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11590                 (( $S == ($O & 0666) )) ||
11591                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11592                 rm -f $DIR/$tfile.[smp]$0
11593                 } &
11594                 local pid=$!
11595
11596                 # limit the concurrently running threads to 64. LU-11878
11597                 local idx=$((U % 64))
11598                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11599                 pids[idx]=$pid
11600         done
11601         wait
11602 }
11603 run_test 103b "umask lfs setstripe"
11604
11605 test_103c() {
11606         mkdir -p $DIR/$tdir
11607         cp -rp $DIR/$tdir $DIR/$tdir.bak
11608
11609         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11610                 error "$DIR/$tdir shouldn't contain default ACL"
11611         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11612                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11613         true
11614 }
11615 run_test 103c "'cp -rp' won't set empty acl"
11616
11617 test_103e() {
11618         local numacl
11619         local fileacl
11620         local saved_debug=$($LCTL get_param -n debug)
11621
11622         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
11623                 skip "MDS needs to be at least 2.14.52"
11624
11625         large_xattr_enabled || skip_env "ea_inode feature disabled"
11626
11627         mkdir -p $DIR/$tdir
11628         # add big LOV EA to cause reply buffer overflow earlier
11629         $LFS setstripe -C 1000 $DIR/$tdir
11630         lctl set_param mdc.*-mdc*.stats=clear
11631
11632         $LCTL set_param debug=0
11633         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11634         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11635
11636         # add a large number of default ACLs (expect 8000+ for 2.13+)
11637         for U in {2..7000}; do
11638                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11639                         error "Able to add just $U default ACLs"
11640         done
11641         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11642         echo "$numacl default ACLs created"
11643
11644         stat $DIR/$tdir || error "Cannot stat directory"
11645         # check file creation
11646         touch $DIR/$tdir/$tfile ||
11647                 error "failed to create $tfile with $numacl default ACLs"
11648         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11649         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11650         echo "$fileacl ACLs were inherited"
11651         (( $fileacl == $numacl )) ||
11652                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11653         # check that new ACLs creation adds new ACLs to inherited ACLs
11654         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11655                 error "Cannot set new ACL"
11656         numacl=$((numacl + 1))
11657         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11658         (( $fileacl == $numacl )) ||
11659                 error "failed to add new ACL: $fileacl != $numacl as expected"
11660         # adds more ACLs to a file to reach their maximum at 8000+
11661         numacl=0
11662         for U in {20000..25000}; do
11663                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11664                 numacl=$((numacl + 1))
11665         done
11666         echo "Added $numacl more ACLs to the file"
11667         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11668         echo "Total $fileacl ACLs in file"
11669         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11670         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11671         rmdir $DIR/$tdir || error "Cannot remove directory"
11672 }
11673 run_test 103e "inheritance of big amount of default ACLs"
11674
11675 test_103f() {
11676         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11677                 skip "MDS needs to be at least 2.14.51"
11678
11679         large_xattr_enabled || skip_env "ea_inode feature disabled"
11680
11681         # enable changelog to consume more internal MDD buffers
11682         changelog_register
11683
11684         mkdir -p $DIR/$tdir
11685         # add big LOV EA
11686         $LFS setstripe -C 1000 $DIR/$tdir
11687         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11688         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11689         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11690         rmdir $DIR/$tdir || error "Cannot remove directory"
11691 }
11692 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11693
11694 test_104a() {
11695         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11696
11697         touch $DIR/$tfile
11698         lfs df || error "lfs df failed"
11699         lfs df -ih || error "lfs df -ih failed"
11700         lfs df -h $DIR || error "lfs df -h $DIR failed"
11701         lfs df -i $DIR || error "lfs df -i $DIR failed"
11702         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11703         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11704
11705         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11706         lctl --device %$OSC deactivate
11707         lfs df || error "lfs df with deactivated OSC failed"
11708         lctl --device %$OSC activate
11709         # wait the osc back to normal
11710         wait_osc_import_ready client ost
11711
11712         lfs df || error "lfs df with reactivated OSC failed"
11713         rm -f $DIR/$tfile
11714 }
11715 run_test 104a "lfs df [-ih] [path] test ========================="
11716
11717 test_104b() {
11718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11719         [ $RUNAS_ID -eq $UID ] &&
11720                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11721
11722         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11723                         grep "Permission denied" | wc -l)))
11724         if [ $denied_cnt -ne 0 ]; then
11725                 error "lfs check servers test failed"
11726         fi
11727 }
11728 run_test 104b "$RUNAS lfs check servers test ===================="
11729
11730 #
11731 # Verify $1 is within range of $2.
11732 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11733 # $1 is <= 2% of $2. Else Fail.
11734 #
11735 value_in_range() {
11736         # Strip all units (M, G, T)
11737         actual=$(echo $1 | tr -d A-Z)
11738         expect=$(echo $2 | tr -d A-Z)
11739
11740         expect_lo=$(($expect * 98 / 100)) # 2% below
11741         expect_hi=$(($expect * 102 / 100)) # 2% above
11742
11743         # permit 2% drift above and below
11744         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11745 }
11746
11747 test_104c() {
11748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11749         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11750
11751         local ost_param="osd-zfs.$FSNAME-OST0000."
11752         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11753         local ofacets=$(get_facets OST)
11754         local mfacets=$(get_facets MDS)
11755         local saved_ost_blocks=
11756         local saved_mdt_blocks=
11757
11758         echo "Before recordsize change"
11759         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11760         df=($(df -h | grep "$MOUNT"$))
11761
11762         # For checking.
11763         echo "lfs output : ${lfs_df[*]}"
11764         echo "df  output : ${df[*]}"
11765
11766         for facet in ${ofacets//,/ }; do
11767                 if [ -z $saved_ost_blocks ]; then
11768                         saved_ost_blocks=$(do_facet $facet \
11769                                 lctl get_param -n $ost_param.blocksize)
11770                         echo "OST Blocksize: $saved_ost_blocks"
11771                 fi
11772                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11773                 do_facet $facet zfs set recordsize=32768 $ost
11774         done
11775
11776         # BS too small. Sufficient for functional testing.
11777         for facet in ${mfacets//,/ }; do
11778                 if [ -z $saved_mdt_blocks ]; then
11779                         saved_mdt_blocks=$(do_facet $facet \
11780                                 lctl get_param -n $mdt_param.blocksize)
11781                         echo "MDT Blocksize: $saved_mdt_blocks"
11782                 fi
11783                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11784                 do_facet $facet zfs set recordsize=32768 $mdt
11785         done
11786
11787         # Give new values chance to reflect change
11788         sleep 2
11789
11790         echo "After recordsize change"
11791         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11792         df_after=($(df -h | grep "$MOUNT"$))
11793
11794         # For checking.
11795         echo "lfs output : ${lfs_df_after[*]}"
11796         echo "df  output : ${df_after[*]}"
11797
11798         # Verify lfs df
11799         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11800                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11801         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11802                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11803         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11804                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11805
11806         # Verify df
11807         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11808                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11809         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11810                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11811         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11812                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11813
11814         # Restore MDT recordize back to original
11815         for facet in ${mfacets//,/ }; do
11816                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11817                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11818         done
11819
11820         # Restore OST recordize back to original
11821         for facet in ${ofacets//,/ }; do
11822                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11823                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11824         done
11825
11826         return 0
11827 }
11828 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11829
11830 test_105a() {
11831         # doesn't work on 2.4 kernels
11832         touch $DIR/$tfile
11833         if $(flock_is_enabled); then
11834                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11835         else
11836                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11837         fi
11838         rm -f $DIR/$tfile
11839 }
11840 run_test 105a "flock when mounted without -o flock test ========"
11841
11842 test_105b() {
11843         touch $DIR/$tfile
11844         if $(flock_is_enabled); then
11845                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11846         else
11847                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11848         fi
11849         rm -f $DIR/$tfile
11850 }
11851 run_test 105b "fcntl when mounted without -o flock test ========"
11852
11853 test_105c() {
11854         touch $DIR/$tfile
11855         if $(flock_is_enabled); then
11856                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11857         else
11858                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11859         fi
11860         rm -f $DIR/$tfile
11861 }
11862 run_test 105c "lockf when mounted without -o flock test"
11863
11864 test_105d() { # bug 15924
11865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11866
11867         test_mkdir $DIR/$tdir
11868         flock_is_enabled || skip_env "mount w/o flock enabled"
11869         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11870         $LCTL set_param fail_loc=0x80000315
11871         flocks_test 2 $DIR/$tdir
11872 }
11873 run_test 105d "flock race (should not freeze) ========"
11874
11875 test_105e() { # bug 22660 && 22040
11876         flock_is_enabled || skip_env "mount w/o flock enabled"
11877
11878         touch $DIR/$tfile
11879         flocks_test 3 $DIR/$tfile
11880 }
11881 run_test 105e "Two conflicting flocks from same process"
11882
11883 test_106() { #bug 10921
11884         test_mkdir $DIR/$tdir
11885         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11886         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11887 }
11888 run_test 106 "attempt exec of dir followed by chown of that dir"
11889
11890 test_107() {
11891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11892
11893         CDIR=`pwd`
11894         local file=core
11895
11896         cd $DIR
11897         rm -f $file
11898
11899         local save_pattern=$(sysctl -n kernel.core_pattern)
11900         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11901         sysctl -w kernel.core_pattern=$file
11902         sysctl -w kernel.core_uses_pid=0
11903
11904         ulimit -c unlimited
11905         sleep 60 &
11906         SLEEPPID=$!
11907
11908         sleep 1
11909
11910         kill -s 11 $SLEEPPID
11911         wait $SLEEPPID
11912         if [ -e $file ]; then
11913                 size=`stat -c%s $file`
11914                 [ $size -eq 0 ] && error "Fail to create core file $file"
11915         else
11916                 error "Fail to create core file $file"
11917         fi
11918         rm -f $file
11919         sysctl -w kernel.core_pattern=$save_pattern
11920         sysctl -w kernel.core_uses_pid=$save_uses_pid
11921         cd $CDIR
11922 }
11923 run_test 107 "Coredump on SIG"
11924
11925 test_110() {
11926         test_mkdir $DIR/$tdir
11927         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11928         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11929                 error "mkdir with 256 char should fail, but did not"
11930         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11931                 error "create with 255 char failed"
11932         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11933                 error "create with 256 char should fail, but did not"
11934
11935         ls -l $DIR/$tdir
11936         rm -rf $DIR/$tdir
11937 }
11938 run_test 110 "filename length checking"
11939
11940 #
11941 # Purpose: To verify dynamic thread (OSS) creation.
11942 #
11943 test_115() {
11944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11945         remote_ost_nodsh && skip "remote OST with nodsh"
11946
11947         # Lustre does not stop service threads once they are started.
11948         # Reset number of running threads to default.
11949         stopall
11950         setupall
11951
11952         local OSTIO_pre
11953         local save_params="$TMP/sanity-$TESTNAME.parameters"
11954
11955         # Get ll_ost_io count before I/O
11956         OSTIO_pre=$(do_facet ost1 \
11957                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11958         # Exit if lustre is not running (ll_ost_io not running).
11959         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11960
11961         echo "Starting with $OSTIO_pre threads"
11962         local thread_max=$((OSTIO_pre * 2))
11963         local rpc_in_flight=$((thread_max * 2))
11964         # this is limited to OSC_MAX_RIF_MAX (256)
11965         [ $rpc_in_flight -gt 256 ] && rpc_in_flight=256
11966         thread_max=$((rpc_in_flight / 2))
11967         [ $thread_max -le $OSTIO_pre ] && skip "Too many ost_io threads" &&
11968                 return
11969
11970         # Number of I/O Process proposed to be started.
11971         local nfiles
11972         local facets=$(get_facets OST)
11973
11974         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11975         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11976
11977         # Set in_flight to $rpc_in_flight
11978         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11979                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11980         nfiles=${rpc_in_flight}
11981         # Set ost thread_max to $thread_max
11982         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11983
11984         # 5 Minutes should be sufficient for max number of OSS
11985         # threads(thread_max) to be created.
11986         local timeout=300
11987
11988         # Start I/O.
11989         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11990         test_mkdir $DIR/$tdir
11991         for i in $(seq $nfiles); do
11992                 local file=$DIR/$tdir/${tfile}-$i
11993                 $LFS setstripe -c -1 -i 0 $file
11994                 ($WTL $file $timeout)&
11995         done
11996
11997         # I/O Started - Wait for thread_started to reach thread_max or report
11998         # error if thread_started is more than thread_max.
11999         echo "Waiting for thread_started to reach thread_max"
12000         local thread_started=0
12001         local end_time=$((SECONDS + timeout))
12002
12003         while [ $SECONDS -le $end_time ] ; do
12004                 echo -n "."
12005                 # Get ost i/o thread_started count.
12006                 thread_started=$(do_facet ost1 \
12007                         "$LCTL get_param \
12008                         ost.OSS.ost_io.threads_started | cut -d= -f2")
12009                 # Break out if thread_started is equal/greater than thread_max
12010                 if [[ $thread_started -ge $thread_max ]]; then
12011                         echo ll_ost_io thread_started $thread_started, \
12012                                 equal/greater than thread_max $thread_max
12013                         break
12014                 fi
12015                 sleep 1
12016         done
12017
12018         # Cleanup - We have the numbers, Kill i/o jobs if running.
12019         jobcount=($(jobs -p))
12020         for i in $(seq 0 $((${#jobcount[@]}-1)))
12021         do
12022                 kill -9 ${jobcount[$i]}
12023                 if [ $? -ne 0 ] ; then
12024                         echo Warning: \
12025                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
12026                 fi
12027         done
12028
12029         # Cleanup files left by WTL binary.
12030         for i in $(seq $nfiles); do
12031                 local file=$DIR/$tdir/${tfile}-$i
12032                 rm -rf $file
12033                 if [ $? -ne 0 ] ; then
12034                         echo "Warning: Failed to delete file $file"
12035                 fi
12036         done
12037
12038         restore_lustre_params <$save_params
12039         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
12040
12041         # Error out if no new thread has started or Thread started is greater
12042         # than thread max.
12043         if [[ $thread_started -le $OSTIO_pre ||
12044                         $thread_started -gt $thread_max ]]; then
12045                 error "ll_ost_io: thread_started $thread_started" \
12046                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
12047                       "No new thread started or thread started greater " \
12048                       "than thread_max."
12049         fi
12050 }
12051 run_test 115 "verify dynamic thread creation===================="
12052
12053 test_116a() { # was previously test_116()
12054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12055         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12056         remote_mds_nodsh && skip "remote MDS with nodsh"
12057
12058         echo -n "Free space priority "
12059         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12060                 head -n1
12061         declare -a AVAIL
12062         free_min_max
12063
12064         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12065         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12066         stack_trap simple_cleanup_common
12067
12068         # Check if we need to generate uneven OSTs
12069         test_mkdir -p $DIR/$tdir/OST${MINI}
12070         local FILL=$((MINV / 4))
12071         local DIFF=$((MAXV - MINV))
12072         local DIFF2=$((DIFF * 100 / MINV))
12073
12074         local threshold=$(do_facet $SINGLEMDS \
12075                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12076         threshold=${threshold%%%}
12077         echo -n "Check for uneven OSTs: "
12078         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12079
12080         if [[ $DIFF2 -gt $threshold ]]; then
12081                 echo "ok"
12082                 echo "Don't need to fill OST$MINI"
12083         else
12084                 # generate uneven OSTs. Write 2% over the QOS threshold value
12085                 echo "no"
12086                 DIFF=$((threshold - DIFF2 + 2))
12087                 DIFF2=$((MINV * DIFF / 100))
12088                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12089                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12090                         error "setstripe failed"
12091                 DIFF=$((DIFF2 / 2048))
12092                 i=0
12093                 while [ $i -lt $DIFF ]; do
12094                         i=$((i + 1))
12095                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12096                                 bs=2M count=1 2>/dev/null
12097                         echo -n .
12098                 done
12099                 echo .
12100                 sync
12101                 sleep_maxage
12102                 free_min_max
12103         fi
12104
12105         DIFF=$((MAXV - MINV))
12106         DIFF2=$((DIFF * 100 / MINV))
12107         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12108         if [ $DIFF2 -gt $threshold ]; then
12109                 echo "ok"
12110         else
12111                 skip "QOS imbalance criteria not met"
12112         fi
12113
12114         MINI1=$MINI
12115         MINV1=$MINV
12116         MAXI1=$MAXI
12117         MAXV1=$MAXV
12118
12119         # now fill using QOS
12120         $LFS setstripe -c 1 $DIR/$tdir
12121         FILL=$((FILL / 200))
12122         if [ $FILL -gt 600 ]; then
12123                 FILL=600
12124         fi
12125         echo "writing $FILL files to QOS-assigned OSTs"
12126         i=0
12127         while [ $i -lt $FILL ]; do
12128                 i=$((i + 1))
12129                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12130                         count=1 2>/dev/null
12131                 echo -n .
12132         done
12133         echo "wrote $i 200k files"
12134         sync
12135         sleep_maxage
12136
12137         echo "Note: free space may not be updated, so measurements might be off"
12138         free_min_max
12139         DIFF2=$((MAXV - MINV))
12140         echo "free space delta: orig $DIFF final $DIFF2"
12141         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12142         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12143         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12144         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12145         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12146         if [[ $DIFF -gt 0 ]]; then
12147                 FILL=$((DIFF2 * 100 / DIFF - 100))
12148                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12149         fi
12150
12151         # Figure out which files were written where
12152         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12153                awk '/'$MINI1': / {print $2; exit}')
12154         echo $UUID
12155         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12156         echo "$MINC files created on smaller OST $MINI1"
12157         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12158                awk '/'$MAXI1': / {print $2; exit}')
12159         echo $UUID
12160         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12161         echo "$MAXC files created on larger OST $MAXI1"
12162         if [[ $MINC -gt 0 ]]; then
12163                 FILL=$((MAXC * 100 / MINC - 100))
12164                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12165         fi
12166         [[ $MAXC -gt $MINC ]] ||
12167                 error_ignore LU-9 "stripe QOS didn't balance free space"
12168 }
12169 run_test 116a "stripe QOS: free space balance ==================="
12170
12171 test_116b() { # LU-2093
12172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12173         remote_mds_nodsh && skip "remote MDS with nodsh"
12174
12175 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12176         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12177                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12178         [ -z "$old_rr" ] && skip "no QOS"
12179         do_facet $SINGLEMDS lctl set_param \
12180                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12181         mkdir -p $DIR/$tdir
12182         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12183         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12184         do_facet $SINGLEMDS lctl set_param fail_loc=0
12185         rm -rf $DIR/$tdir
12186         do_facet $SINGLEMDS lctl set_param \
12187                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12188 }
12189 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12190
12191 test_117() # bug 10891
12192 {
12193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12194
12195         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12196         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12197         lctl set_param fail_loc=0x21e
12198         > $DIR/$tfile || error "truncate failed"
12199         lctl set_param fail_loc=0
12200         echo "Truncate succeeded."
12201         rm -f $DIR/$tfile
12202 }
12203 run_test 117 "verify osd extend =========="
12204
12205 NO_SLOW_RESENDCOUNT=4
12206 export OLD_RESENDCOUNT=""
12207 set_resend_count () {
12208         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12209         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12210         lctl set_param -n $PROC_RESENDCOUNT $1
12211         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12212 }
12213
12214 # for reduce test_118* time (b=14842)
12215 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12216
12217 # Reset async IO behavior after error case
12218 reset_async() {
12219         FILE=$DIR/reset_async
12220
12221         # Ensure all OSCs are cleared
12222         $LFS setstripe -c -1 $FILE
12223         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12224         sync
12225         rm $FILE
12226 }
12227
12228 test_118a() #bug 11710
12229 {
12230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12231
12232         reset_async
12233
12234         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12235         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12236         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12237
12238         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12239                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12240                 return 1;
12241         fi
12242         rm -f $DIR/$tfile
12243 }
12244 run_test 118a "verify O_SYNC works =========="
12245
12246 test_118b()
12247 {
12248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12249         remote_ost_nodsh && skip "remote OST with nodsh"
12250
12251         reset_async
12252
12253         #define OBD_FAIL_SRV_ENOENT 0x217
12254         set_nodes_failloc "$(osts_nodes)" 0x217
12255         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12256         RC=$?
12257         set_nodes_failloc "$(osts_nodes)" 0
12258         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12259         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12260                     grep -c writeback)
12261
12262         if [[ $RC -eq 0 ]]; then
12263                 error "Must return error due to dropped pages, rc=$RC"
12264                 return 1;
12265         fi
12266
12267         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12268                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12269                 return 1;
12270         fi
12271
12272         echo "Dirty pages not leaked on ENOENT"
12273
12274         # Due to the above error the OSC will issue all RPCs syncronously
12275         # until a subsequent RPC completes successfully without error.
12276         $MULTIOP $DIR/$tfile Ow4096yc
12277         rm -f $DIR/$tfile
12278
12279         return 0
12280 }
12281 run_test 118b "Reclaim dirty pages on fatal error =========="
12282
12283 test_118c()
12284 {
12285         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12286
12287         # for 118c, restore the original resend count, LU-1940
12288         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12289                                 set_resend_count $OLD_RESENDCOUNT
12290         remote_ost_nodsh && skip "remote OST with nodsh"
12291
12292         reset_async
12293
12294         #define OBD_FAIL_OST_EROFS               0x216
12295         set_nodes_failloc "$(osts_nodes)" 0x216
12296
12297         # multiop should block due to fsync until pages are written
12298         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12299         MULTIPID=$!
12300         sleep 1
12301
12302         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12303                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12304         fi
12305
12306         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12307                     grep -c writeback)
12308         if [[ $WRITEBACK -eq 0 ]]; then
12309                 error "No page in writeback, writeback=$WRITEBACK"
12310         fi
12311
12312         set_nodes_failloc "$(osts_nodes)" 0
12313         wait $MULTIPID
12314         RC=$?
12315         if [[ $RC -ne 0 ]]; then
12316                 error "Multiop fsync failed, rc=$RC"
12317         fi
12318
12319         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12320         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12321                     grep -c writeback)
12322         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12323                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12324         fi
12325
12326         rm -f $DIR/$tfile
12327         echo "Dirty pages flushed via fsync on EROFS"
12328         return 0
12329 }
12330 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12331
12332 # continue to use small resend count to reduce test_118* time (b=14842)
12333 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12334
12335 test_118d()
12336 {
12337         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12338         remote_ost_nodsh && skip "remote OST with nodsh"
12339
12340         reset_async
12341
12342         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12343         set_nodes_failloc "$(osts_nodes)" 0x214
12344         # multiop should block due to fsync until pages are written
12345         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12346         MULTIPID=$!
12347         sleep 1
12348
12349         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12350                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12351         fi
12352
12353         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12354                     grep -c writeback)
12355         if [[ $WRITEBACK -eq 0 ]]; then
12356                 error "No page in writeback, writeback=$WRITEBACK"
12357         fi
12358
12359         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12360         set_nodes_failloc "$(osts_nodes)" 0
12361
12362         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12363         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12364                     grep -c writeback)
12365         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12366                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12367         fi
12368
12369         rm -f $DIR/$tfile
12370         echo "Dirty pages gaurenteed flushed via fsync"
12371         return 0
12372 }
12373 run_test 118d "Fsync validation inject a delay of the bulk =========="
12374
12375 test_118f() {
12376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12377
12378         reset_async
12379
12380         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12381         lctl set_param fail_loc=0x8000040a
12382
12383         # Should simulate EINVAL error which is fatal
12384         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12385         RC=$?
12386         if [[ $RC -eq 0 ]]; then
12387                 error "Must return error due to dropped pages, rc=$RC"
12388         fi
12389
12390         lctl set_param fail_loc=0x0
12391
12392         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12393         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12394         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12395                     grep -c writeback)
12396         if [[ $LOCKED -ne 0 ]]; then
12397                 error "Locked pages remain in cache, locked=$LOCKED"
12398         fi
12399
12400         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12401                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12402         fi
12403
12404         rm -f $DIR/$tfile
12405         echo "No pages locked after fsync"
12406
12407         reset_async
12408         return 0
12409 }
12410 run_test 118f "Simulate unrecoverable OSC side error =========="
12411
12412 test_118g() {
12413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12414
12415         reset_async
12416
12417         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12418         lctl set_param fail_loc=0x406
12419
12420         # simulate local -ENOMEM
12421         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12422         RC=$?
12423
12424         lctl set_param fail_loc=0
12425         if [[ $RC -eq 0 ]]; then
12426                 error "Must return error due to dropped pages, rc=$RC"
12427         fi
12428
12429         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12430         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12431         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12432                         grep -c writeback)
12433         if [[ $LOCKED -ne 0 ]]; then
12434                 error "Locked pages remain in cache, locked=$LOCKED"
12435         fi
12436
12437         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12438                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12439         fi
12440
12441         rm -f $DIR/$tfile
12442         echo "No pages locked after fsync"
12443
12444         reset_async
12445         return 0
12446 }
12447 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12448
12449 test_118h() {
12450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12451         remote_ost_nodsh && skip "remote OST with nodsh"
12452
12453         reset_async
12454
12455         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12456         set_nodes_failloc "$(osts_nodes)" 0x20e
12457         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12458         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12459         RC=$?
12460
12461         set_nodes_failloc "$(osts_nodes)" 0
12462         if [[ $RC -eq 0 ]]; then
12463                 error "Must return error due to dropped pages, rc=$RC"
12464         fi
12465
12466         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12467         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12468         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12469                     grep -c writeback)
12470         if [[ $LOCKED -ne 0 ]]; then
12471                 error "Locked pages remain in cache, locked=$LOCKED"
12472         fi
12473
12474         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12475                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12476         fi
12477
12478         rm -f $DIR/$tfile
12479         echo "No pages locked after fsync"
12480
12481         return 0
12482 }
12483 run_test 118h "Verify timeout in handling recoverables errors  =========="
12484
12485 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12486
12487 test_118i() {
12488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12489         remote_ost_nodsh && skip "remote OST with nodsh"
12490
12491         reset_async
12492
12493         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12494         set_nodes_failloc "$(osts_nodes)" 0x20e
12495
12496         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12497         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12498         PID=$!
12499         sleep 5
12500         set_nodes_failloc "$(osts_nodes)" 0
12501
12502         wait $PID
12503         RC=$?
12504         if [[ $RC -ne 0 ]]; then
12505                 error "got error, but should be not, rc=$RC"
12506         fi
12507
12508         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12509         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12510         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12511         if [[ $LOCKED -ne 0 ]]; then
12512                 error "Locked pages remain in cache, locked=$LOCKED"
12513         fi
12514
12515         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12516                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12517         fi
12518
12519         rm -f $DIR/$tfile
12520         echo "No pages locked after fsync"
12521
12522         return 0
12523 }
12524 run_test 118i "Fix error before timeout in recoverable error  =========="
12525
12526 [ "$SLOW" = "no" ] && set_resend_count 4
12527
12528 test_118j() {
12529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12530         remote_ost_nodsh && skip "remote OST with nodsh"
12531
12532         reset_async
12533
12534         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12535         set_nodes_failloc "$(osts_nodes)" 0x220
12536
12537         # return -EIO from OST
12538         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12539         RC=$?
12540         set_nodes_failloc "$(osts_nodes)" 0x0
12541         if [[ $RC -eq 0 ]]; then
12542                 error "Must return error due to dropped pages, rc=$RC"
12543         fi
12544
12545         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12546         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12547         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12548         if [[ $LOCKED -ne 0 ]]; then
12549                 error "Locked pages remain in cache, locked=$LOCKED"
12550         fi
12551
12552         # in recoverable error on OST we want resend and stay until it finished
12553         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12554                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12555         fi
12556
12557         rm -f $DIR/$tfile
12558         echo "No pages locked after fsync"
12559
12560         return 0
12561 }
12562 run_test 118j "Simulate unrecoverable OST side error =========="
12563
12564 test_118k()
12565 {
12566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12567         remote_ost_nodsh && skip "remote OSTs with nodsh"
12568
12569         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12570         set_nodes_failloc "$(osts_nodes)" 0x20e
12571         test_mkdir $DIR/$tdir
12572
12573         for ((i=0;i<10;i++)); do
12574                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12575                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12576                 SLEEPPID=$!
12577                 sleep 0.500s
12578                 kill $SLEEPPID
12579                 wait $SLEEPPID
12580         done
12581
12582         set_nodes_failloc "$(osts_nodes)" 0
12583         rm -rf $DIR/$tdir
12584 }
12585 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12586
12587 test_118l() # LU-646
12588 {
12589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12590
12591         test_mkdir $DIR/$tdir
12592         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12593         rm -rf $DIR/$tdir
12594 }
12595 run_test 118l "fsync dir"
12596
12597 test_118m() # LU-3066
12598 {
12599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12600
12601         test_mkdir $DIR/$tdir
12602         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12603         rm -rf $DIR/$tdir
12604 }
12605 run_test 118m "fdatasync dir ========="
12606
12607 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12608
12609 test_118n()
12610 {
12611         local begin
12612         local end
12613
12614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12615         remote_ost_nodsh && skip "remote OSTs with nodsh"
12616
12617         # Sleep to avoid a cached response.
12618         #define OBD_STATFS_CACHE_SECONDS 1
12619         sleep 2
12620
12621         # Inject a 10 second delay in the OST_STATFS handler.
12622         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12623         set_nodes_failloc "$(osts_nodes)" 0x242
12624
12625         begin=$SECONDS
12626         stat --file-system $MOUNT > /dev/null
12627         end=$SECONDS
12628
12629         set_nodes_failloc "$(osts_nodes)" 0
12630
12631         if ((end - begin > 20)); then
12632             error "statfs took $((end - begin)) seconds, expected 10"
12633         fi
12634 }
12635 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12636
12637 test_119a() # bug 11737
12638 {
12639         BSIZE=$((512 * 1024))
12640         directio write $DIR/$tfile 0 1 $BSIZE
12641         # We ask to read two blocks, which is more than a file size.
12642         # directio will indicate an error when requested and actual
12643         # sizes aren't equeal (a normal situation in this case) and
12644         # print actual read amount.
12645         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12646         if [ "$NOB" != "$BSIZE" ]; then
12647                 error "read $NOB bytes instead of $BSIZE"
12648         fi
12649         rm -f $DIR/$tfile
12650 }
12651 run_test 119a "Short directIO read must return actual read amount"
12652
12653 test_119b() # bug 11737
12654 {
12655         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12656
12657         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12658         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12659         sync
12660         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12661                 error "direct read failed"
12662         rm -f $DIR/$tfile
12663 }
12664 run_test 119b "Sparse directIO read must return actual read amount"
12665
12666 test_119c() # bug 13099
12667 {
12668         BSIZE=1048576
12669         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12670         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12671         rm -f $DIR/$tfile
12672 }
12673 run_test 119c "Testing for direct read hitting hole"
12674
12675 test_119d() # bug 15950
12676 {
12677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12678
12679         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12680         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12681         BSIZE=1048576
12682         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12683         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12684         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12685         lctl set_param fail_loc=0x40d
12686         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12687         pid_dio=$!
12688         sleep 1
12689         cat $DIR/$tfile > /dev/null &
12690         lctl set_param fail_loc=0
12691         pid_reads=$!
12692         wait $pid_dio
12693         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12694         sleep 2
12695         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12696         error "the read rpcs have not completed in 2s"
12697         rm -f $DIR/$tfile
12698         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12699 }
12700 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12701
12702 test_120a() {
12703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12704         remote_mds_nodsh && skip "remote MDS with nodsh"
12705         test_mkdir -i0 -c1 $DIR/$tdir
12706         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12707                 skip_env "no early lock cancel on server"
12708
12709         lru_resize_disable mdc
12710         lru_resize_disable osc
12711         cancel_lru_locks mdc
12712         # asynchronous object destroy at MDT could cause bl ast to client
12713         cancel_lru_locks osc
12714
12715         stat $DIR/$tdir > /dev/null
12716         can1=$(do_facet mds1 \
12717                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12718                awk '/ldlm_cancel/ {print $2}')
12719         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12720                awk '/ldlm_bl_callback/ {print $2}')
12721         test_mkdir -i0 -c1 $DIR/$tdir/d1
12722         can2=$(do_facet mds1 \
12723                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12724                awk '/ldlm_cancel/ {print $2}')
12725         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12726                awk '/ldlm_bl_callback/ {print $2}')
12727         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12728         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12729         lru_resize_enable mdc
12730         lru_resize_enable osc
12731 }
12732 run_test 120a "Early Lock Cancel: mkdir test"
12733
12734 test_120b() {
12735         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12736         remote_mds_nodsh && skip "remote MDS with nodsh"
12737         test_mkdir $DIR/$tdir
12738         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12739                 skip_env "no early lock cancel on server"
12740
12741         lru_resize_disable mdc
12742         lru_resize_disable osc
12743         cancel_lru_locks mdc
12744         stat $DIR/$tdir > /dev/null
12745         can1=$(do_facet $SINGLEMDS \
12746                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12747                awk '/ldlm_cancel/ {print $2}')
12748         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12749                awk '/ldlm_bl_callback/ {print $2}')
12750         touch $DIR/$tdir/f1
12751         can2=$(do_facet $SINGLEMDS \
12752                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12753                awk '/ldlm_cancel/ {print $2}')
12754         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12755                awk '/ldlm_bl_callback/ {print $2}')
12756         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12757         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12758         lru_resize_enable mdc
12759         lru_resize_enable osc
12760 }
12761 run_test 120b "Early Lock Cancel: create test"
12762
12763 test_120c() {
12764         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12765         remote_mds_nodsh && skip "remote MDS with nodsh"
12766         test_mkdir -i0 -c1 $DIR/$tdir
12767         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12768                 skip "no early lock cancel on server"
12769
12770         lru_resize_disable mdc
12771         lru_resize_disable osc
12772         test_mkdir -i0 -c1 $DIR/$tdir/d1
12773         test_mkdir -i0 -c1 $DIR/$tdir/d2
12774         touch $DIR/$tdir/d1/f1
12775         cancel_lru_locks mdc
12776         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12777         can1=$(do_facet mds1 \
12778                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12779                awk '/ldlm_cancel/ {print $2}')
12780         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12781                awk '/ldlm_bl_callback/ {print $2}')
12782         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12783         can2=$(do_facet mds1 \
12784                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12785                awk '/ldlm_cancel/ {print $2}')
12786         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12787                awk '/ldlm_bl_callback/ {print $2}')
12788         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12789         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12790         lru_resize_enable mdc
12791         lru_resize_enable osc
12792 }
12793 run_test 120c "Early Lock Cancel: link test"
12794
12795 test_120d() {
12796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12797         remote_mds_nodsh && skip "remote MDS with nodsh"
12798         test_mkdir -i0 -c1 $DIR/$tdir
12799         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12800                 skip_env "no early lock cancel on server"
12801
12802         lru_resize_disable mdc
12803         lru_resize_disable osc
12804         touch $DIR/$tdir
12805         cancel_lru_locks mdc
12806         stat $DIR/$tdir > /dev/null
12807         can1=$(do_facet mds1 \
12808                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12809                awk '/ldlm_cancel/ {print $2}')
12810         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12811                awk '/ldlm_bl_callback/ {print $2}')
12812         chmod a+x $DIR/$tdir
12813         can2=$(do_facet mds1 \
12814                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12815                awk '/ldlm_cancel/ {print $2}')
12816         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12817                awk '/ldlm_bl_callback/ {print $2}')
12818         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12819         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12820         lru_resize_enable mdc
12821         lru_resize_enable osc
12822 }
12823 run_test 120d "Early Lock Cancel: setattr test"
12824
12825 test_120e() {
12826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12827         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12828                 skip_env "no early lock cancel on server"
12829         remote_mds_nodsh && skip "remote MDS with nodsh"
12830
12831         local dlmtrace_set=false
12832
12833         test_mkdir -i0 -c1 $DIR/$tdir
12834         lru_resize_disable mdc
12835         lru_resize_disable osc
12836         ! $LCTL get_param debug | grep -q dlmtrace &&
12837                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12838         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12839         cancel_lru_locks mdc
12840         cancel_lru_locks osc
12841         dd if=$DIR/$tdir/f1 of=/dev/null
12842         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12843         # XXX client can not do early lock cancel of OST lock
12844         # during unlink (LU-4206), so cancel osc lock now.
12845         sleep 2
12846         cancel_lru_locks osc
12847         can1=$(do_facet mds1 \
12848                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12849                awk '/ldlm_cancel/ {print $2}')
12850         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12851                awk '/ldlm_bl_callback/ {print $2}')
12852         unlink $DIR/$tdir/f1
12853         sleep 5
12854         can2=$(do_facet mds1 \
12855                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12856                awk '/ldlm_cancel/ {print $2}')
12857         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12858                awk '/ldlm_bl_callback/ {print $2}')
12859         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12860                 $LCTL dk $TMP/cancel.debug.txt
12861         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12862                 $LCTL dk $TMP/blocking.debug.txt
12863         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12864         lru_resize_enable mdc
12865         lru_resize_enable osc
12866 }
12867 run_test 120e "Early Lock Cancel: unlink test"
12868
12869 test_120f() {
12870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12871         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12872                 skip_env "no early lock cancel on server"
12873         remote_mds_nodsh && skip "remote MDS with nodsh"
12874
12875         test_mkdir -i0 -c1 $DIR/$tdir
12876         lru_resize_disable mdc
12877         lru_resize_disable osc
12878         test_mkdir -i0 -c1 $DIR/$tdir/d1
12879         test_mkdir -i0 -c1 $DIR/$tdir/d2
12880         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12881         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12882         cancel_lru_locks mdc
12883         cancel_lru_locks osc
12884         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12885         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12886         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12887         # XXX client can not do early lock cancel of OST lock
12888         # during rename (LU-4206), so cancel osc lock now.
12889         sleep 2
12890         cancel_lru_locks osc
12891         can1=$(do_facet mds1 \
12892                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12893                awk '/ldlm_cancel/ {print $2}')
12894         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12895                awk '/ldlm_bl_callback/ {print $2}')
12896         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12897         sleep 5
12898         can2=$(do_facet mds1 \
12899                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12900                awk '/ldlm_cancel/ {print $2}')
12901         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12902                awk '/ldlm_bl_callback/ {print $2}')
12903         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12904         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12905         lru_resize_enable mdc
12906         lru_resize_enable osc
12907 }
12908 run_test 120f "Early Lock Cancel: rename test"
12909
12910 test_120g() {
12911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12912         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12913                 skip_env "no early lock cancel on server"
12914         remote_mds_nodsh && skip "remote MDS with nodsh"
12915
12916         lru_resize_disable mdc
12917         lru_resize_disable osc
12918         count=10000
12919         echo create $count files
12920         test_mkdir $DIR/$tdir
12921         cancel_lru_locks mdc
12922         cancel_lru_locks osc
12923         t0=$(date +%s)
12924
12925         can0=$(do_facet $SINGLEMDS \
12926                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12927                awk '/ldlm_cancel/ {print $2}')
12928         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12929                awk '/ldlm_bl_callback/ {print $2}')
12930         createmany -o $DIR/$tdir/f $count
12931         sync
12932         can1=$(do_facet $SINGLEMDS \
12933                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12934                awk '/ldlm_cancel/ {print $2}')
12935         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12936                awk '/ldlm_bl_callback/ {print $2}')
12937         t1=$(date +%s)
12938         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12939         echo rm $count files
12940         rm -r $DIR/$tdir
12941         sync
12942         can2=$(do_facet $SINGLEMDS \
12943                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12944                awk '/ldlm_cancel/ {print $2}')
12945         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12946                awk '/ldlm_bl_callback/ {print $2}')
12947         t2=$(date +%s)
12948         echo total: $count removes in $((t2-t1))
12949         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12950         sleep 2
12951         # wait for commitment of removal
12952         lru_resize_enable mdc
12953         lru_resize_enable osc
12954 }
12955 run_test 120g "Early Lock Cancel: performance test"
12956
12957 test_121() { #bug #10589
12958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12959
12960         rm -rf $DIR/$tfile
12961         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12962 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12963         lctl set_param fail_loc=0x310
12964         cancel_lru_locks osc > /dev/null
12965         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12966         lctl set_param fail_loc=0
12967         [[ $reads -eq $writes ]] ||
12968                 error "read $reads blocks, must be $writes blocks"
12969 }
12970 run_test 121 "read cancel race ========="
12971
12972 test_123a_base() { # was test 123, statahead(bug 11401)
12973         local lsx="$1"
12974
12975         SLOWOK=0
12976         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12977                 log "testing UP system. Performance may be lower than expected."
12978                 SLOWOK=1
12979         fi
12980         running_in_vm && SLOWOK=1
12981
12982         rm -rf $DIR/$tdir
12983         test_mkdir $DIR/$tdir
12984         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12985         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12986         MULT=10
12987         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12988                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12989
12990                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12991                 lctl set_param -n llite.*.statahead_max 0
12992                 lctl get_param llite.*.statahead_max
12993                 cancel_lru_locks mdc
12994                 cancel_lru_locks osc
12995                 stime=$(date +%s)
12996                 time $lsx $DIR/$tdir | wc -l
12997                 etime=$(date +%s)
12998                 delta=$((etime - stime))
12999                 log "$lsx $i files without statahead: $delta sec"
13000                 lctl set_param llite.*.statahead_max=$max
13001
13002                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13003                         grep "statahead wrong:" | awk '{print $3}')
13004                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13005                 cancel_lru_locks mdc
13006                 cancel_lru_locks osc
13007                 stime=$(date +%s)
13008                 time $lsx $DIR/$tdir | wc -l
13009                 etime=$(date +%s)
13010                 delta_sa=$((etime - stime))
13011                 log "$lsx $i files with statahead: $delta_sa sec"
13012                 lctl get_param -n llite.*.statahead_stats
13013                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13014                         grep "statahead wrong:" | awk '{print $3}')
13015
13016                 [[ $swrong -lt $ewrong ]] &&
13017                         log "statahead was stopped, maybe too many locks held!"
13018                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13019
13020                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
13021                         max=$(lctl get_param -n llite.*.statahead_max |
13022                                 head -n 1)
13023                         lctl set_param -n llite.*.statahead_max 0
13024                         lctl get_param llite.*.statahead_max
13025                         cancel_lru_locks mdc
13026                         cancel_lru_locks osc
13027                         stime=$(date +%s)
13028                         time $lsx $DIR/$tdir | wc -l
13029                         etime=$(date +%s)
13030                         delta=$((etime - stime))
13031                         log "$lsx $i files again without statahead: $delta sec"
13032                         lctl set_param llite.*.statahead_max=$max
13033                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
13034                                 if [  $SLOWOK -eq 0 ]; then
13035                                         error "$lsx $i files is slower with statahead!"
13036                                 else
13037                                         log "$lsx $i files is slower with statahead!"
13038                                 fi
13039                                 break
13040                         fi
13041                 fi
13042
13043                 [ $delta -gt 20 ] && break
13044                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13045                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13046         done
13047         log "$lsx done"
13048
13049         stime=$(date +%s)
13050         rm -r $DIR/$tdir
13051         sync
13052         etime=$(date +%s)
13053         delta=$((etime - stime))
13054         log "rm -r $DIR/$tdir/: $delta seconds"
13055         log "rm done"
13056         lctl get_param -n llite.*.statahead_stats
13057 }
13058
13059 test_123aa() {
13060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13061
13062         test_123a_base "ls -l"
13063 }
13064 run_test 123aa "verify statahead work"
13065
13066 test_123ab() {
13067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13068
13069         statx_supported || skip_env "Test must be statx() syscall supported"
13070
13071         test_123a_base "$STATX -l"
13072 }
13073 run_test 123ab "verify statahead work by using statx"
13074
13075 test_123ac() {
13076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13077
13078         statx_supported || skip_env "Test must be statx() syscall supported"
13079
13080         local rpcs_before
13081         local rpcs_after
13082         local agl_before
13083         local agl_after
13084
13085         cancel_lru_locks $OSC
13086         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13087         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13088                 awk '/agl.total:/ {print $3}')
13089         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13090         test_123a_base "$STATX --cached=always -D"
13091         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13092                 awk '/agl.total:/ {print $3}')
13093         [ $agl_before -eq $agl_after ] ||
13094                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13095         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13096         [ $rpcs_after -eq $rpcs_before ] ||
13097                 error "$STATX should not send glimpse RPCs to $OSC"
13098 }
13099 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13100
13101 test_123b () { # statahead(bug 15027)
13102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13103
13104         test_mkdir $DIR/$tdir
13105         createmany -o $DIR/$tdir/$tfile-%d 1000
13106
13107         cancel_lru_locks mdc
13108         cancel_lru_locks osc
13109
13110 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13111         lctl set_param fail_loc=0x80000803
13112         ls -lR $DIR/$tdir > /dev/null
13113         log "ls done"
13114         lctl set_param fail_loc=0x0
13115         lctl get_param -n llite.*.statahead_stats
13116         rm -r $DIR/$tdir
13117         sync
13118
13119 }
13120 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13121
13122 test_123c() {
13123         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13124
13125         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13126         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13127         touch $DIR/$tdir.1/{1..3}
13128         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13129
13130         remount_client $MOUNT
13131
13132         $MULTIOP $DIR/$tdir.0 Q
13133
13134         # let statahead to complete
13135         ls -l $DIR/$tdir.0 > /dev/null
13136
13137         testid=$(echo $TESTNAME | tr '_' ' ')
13138         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13139                 error "statahead warning" || true
13140 }
13141 run_test 123c "Can not initialize inode warning on DNE statahead"
13142
13143 test_124a() {
13144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13145         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13146                 skip_env "no lru resize on server"
13147
13148         local NR=2000
13149
13150         test_mkdir $DIR/$tdir
13151
13152         log "create $NR files at $DIR/$tdir"
13153         createmany -o $DIR/$tdir/f $NR ||
13154                 error "failed to create $NR files in $DIR/$tdir"
13155
13156         cancel_lru_locks mdc
13157         ls -l $DIR/$tdir > /dev/null
13158
13159         local NSDIR=""
13160         local LRU_SIZE=0
13161         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13162                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13163                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13164                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13165                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13166                         log "NSDIR=$NSDIR"
13167                         log "NS=$(basename $NSDIR)"
13168                         break
13169                 fi
13170         done
13171
13172         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13173                 skip "Not enough cached locks created!"
13174         fi
13175         log "LRU=$LRU_SIZE"
13176
13177         local SLEEP=30
13178
13179         # We know that lru resize allows one client to hold $LIMIT locks
13180         # for 10h. After that locks begin to be killed by client.
13181         local MAX_HRS=10
13182         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13183         log "LIMIT=$LIMIT"
13184         if [ $LIMIT -lt $LRU_SIZE ]; then
13185                 skip "Limit is too small $LIMIT"
13186         fi
13187
13188         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13189         # killing locks. Some time was spent for creating locks. This means
13190         # that up to the moment of sleep finish we must have killed some of
13191         # them (10-100 locks). This depends on how fast ther were created.
13192         # Many of them were touched in almost the same moment and thus will
13193         # be killed in groups.
13194         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13195
13196         # Use $LRU_SIZE_B here to take into account real number of locks
13197         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13198         local LRU_SIZE_B=$LRU_SIZE
13199         log "LVF=$LVF"
13200         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13201         log "OLD_LVF=$OLD_LVF"
13202         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13203
13204         # Let's make sure that we really have some margin. Client checks
13205         # cached locks every 10 sec.
13206         SLEEP=$((SLEEP+20))
13207         log "Sleep ${SLEEP} sec"
13208         local SEC=0
13209         while ((SEC<$SLEEP)); do
13210                 echo -n "..."
13211                 sleep 5
13212                 SEC=$((SEC+5))
13213                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13214                 echo -n "$LRU_SIZE"
13215         done
13216         echo ""
13217         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13218         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13219
13220         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13221                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13222                 unlinkmany $DIR/$tdir/f $NR
13223                 return
13224         }
13225
13226         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13227         log "unlink $NR files at $DIR/$tdir"
13228         unlinkmany $DIR/$tdir/f $NR
13229 }
13230 run_test 124a "lru resize ======================================="
13231
13232 get_max_pool_limit()
13233 {
13234         local limit=$($LCTL get_param \
13235                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13236         local max=0
13237         for l in $limit; do
13238                 if [[ $l -gt $max ]]; then
13239                         max=$l
13240                 fi
13241         done
13242         echo $max
13243 }
13244
13245 test_124b() {
13246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13247         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13248                 skip_env "no lru resize on server"
13249
13250         LIMIT=$(get_max_pool_limit)
13251
13252         NR=$(($(default_lru_size)*20))
13253         if [[ $NR -gt $LIMIT ]]; then
13254                 log "Limit lock number by $LIMIT locks"
13255                 NR=$LIMIT
13256         fi
13257
13258         IFree=$(mdsrate_inodes_available)
13259         if [ $IFree -lt $NR ]; then
13260                 log "Limit lock number by $IFree inodes"
13261                 NR=$IFree
13262         fi
13263
13264         lru_resize_disable mdc
13265         test_mkdir -p $DIR/$tdir/disable_lru_resize
13266
13267         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13268         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13269         cancel_lru_locks mdc
13270         stime=`date +%s`
13271         PID=""
13272         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13273         PID="$PID $!"
13274         sleep 2
13275         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13276         PID="$PID $!"
13277         sleep 2
13278         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13279         PID="$PID $!"
13280         wait $PID
13281         etime=`date +%s`
13282         nolruresize_delta=$((etime-stime))
13283         log "ls -la time: $nolruresize_delta seconds"
13284         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13285         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13286
13287         lru_resize_enable mdc
13288         test_mkdir -p $DIR/$tdir/enable_lru_resize
13289
13290         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13291         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13292         cancel_lru_locks mdc
13293         stime=`date +%s`
13294         PID=""
13295         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13296         PID="$PID $!"
13297         sleep 2
13298         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13299         PID="$PID $!"
13300         sleep 2
13301         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13302         PID="$PID $!"
13303         wait $PID
13304         etime=`date +%s`
13305         lruresize_delta=$((etime-stime))
13306         log "ls -la time: $lruresize_delta seconds"
13307         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13308
13309         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13310                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13311         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13312                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13313         else
13314                 log "lru resize performs the same with no lru resize"
13315         fi
13316         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13317 }
13318 run_test 124b "lru resize (performance test) ======================="
13319
13320 test_124c() {
13321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13322         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13323                 skip_env "no lru resize on server"
13324
13325         # cache ununsed locks on client
13326         local nr=100
13327         cancel_lru_locks mdc
13328         test_mkdir $DIR/$tdir
13329         createmany -o $DIR/$tdir/f $nr ||
13330                 error "failed to create $nr files in $DIR/$tdir"
13331         ls -l $DIR/$tdir > /dev/null
13332
13333         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13334         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13335         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13336         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13337         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13338
13339         # set lru_max_age to 1 sec
13340         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13341         echo "sleep $((recalc_p * 2)) seconds..."
13342         sleep $((recalc_p * 2))
13343
13344         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13345         # restore lru_max_age
13346         $LCTL set_param -n $nsdir.lru_max_age $max_age
13347         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13348         unlinkmany $DIR/$tdir/f $nr
13349 }
13350 run_test 124c "LRUR cancel very aged locks"
13351
13352 test_124d() {
13353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13354         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13355                 skip_env "no lru resize on server"
13356
13357         # cache ununsed locks on client
13358         local nr=100
13359
13360         lru_resize_disable mdc
13361         stack_trap "lru_resize_enable mdc" EXIT
13362
13363         cancel_lru_locks mdc
13364
13365         # asynchronous object destroy at MDT could cause bl ast to client
13366         test_mkdir $DIR/$tdir
13367         createmany -o $DIR/$tdir/f $nr ||
13368                 error "failed to create $nr files in $DIR/$tdir"
13369         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13370
13371         ls -l $DIR/$tdir > /dev/null
13372
13373         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13374         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13375         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13376         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13377
13378         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13379
13380         # set lru_max_age to 1 sec
13381         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13382         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13383
13384         echo "sleep $((recalc_p * 2)) seconds..."
13385         sleep $((recalc_p * 2))
13386
13387         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13388
13389         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13390 }
13391 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13392
13393 test_125() { # 13358
13394         $LCTL get_param -n llite.*.client_type | grep -q local ||
13395                 skip "must run as local client"
13396         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13397                 skip_env "must have acl enabled"
13398         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13399
13400         test_mkdir $DIR/$tdir
13401         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13402         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13403         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13404 }
13405 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13406
13407 test_126() { # bug 12829/13455
13408         $GSS && skip_env "must run as gss disabled"
13409         $LCTL get_param -n llite.*.client_type | grep -q local ||
13410                 skip "must run as local client"
13411         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13412
13413         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13414         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13415         rm -f $DIR/$tfile
13416         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13417 }
13418 run_test 126 "check that the fsgid provided by the client is taken into account"
13419
13420 test_127a() { # bug 15521
13421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13422         local name count samp unit min max sum sumsq
13423
13424         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13425         echo "stats before reset"
13426         $LCTL get_param osc.*.stats
13427         $LCTL set_param osc.*.stats=0
13428         local fsize=$((2048 * 1024))
13429
13430         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13431         cancel_lru_locks osc
13432         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13433
13434         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13435         stack_trap "rm -f $TMP/$tfile.tmp"
13436         while read name count samp unit min max sum sumsq; do
13437                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13438                 [ ! $min ] && error "Missing min value for $name proc entry"
13439                 eval $name=$count || error "Wrong proc format"
13440
13441                 case $name in
13442                 read_bytes|write_bytes)
13443                         [[ "$unit" =~ "bytes" ]] ||
13444                                 error "unit is not 'bytes': $unit"
13445                         (( $min >= 4096 )) || error "min is too small: $min"
13446                         (( $min <= $fsize )) || error "min is too big: $min"
13447                         (( $max >= 4096 )) || error "max is too small: $max"
13448                         (( $max <= $fsize )) || error "max is too big: $max"
13449                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13450                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13451                                 error "sumsquare is too small: $sumsq"
13452                         (( $sumsq <= $fsize * $fsize )) ||
13453                                 error "sumsquare is too big: $sumsq"
13454                         ;;
13455                 ost_read|ost_write)
13456                         [[ "$unit" =~ "usec" ]] ||
13457                                 error "unit is not 'usec': $unit"
13458                         ;;
13459                 *)      ;;
13460                 esac
13461         done < $DIR/$tfile.tmp
13462
13463         #check that we actually got some stats
13464         [ "$read_bytes" ] || error "Missing read_bytes stats"
13465         [ "$write_bytes" ] || error "Missing write_bytes stats"
13466         [ "$read_bytes" != 0 ] || error "no read done"
13467         [ "$write_bytes" != 0 ] || error "no write done"
13468 }
13469 run_test 127a "verify the client stats are sane"
13470
13471 test_127b() { # bug LU-333
13472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13473         local name count samp unit min max sum sumsq
13474
13475         echo "stats before reset"
13476         $LCTL get_param llite.*.stats
13477         $LCTL set_param llite.*.stats=0
13478
13479         # perform 2 reads and writes so MAX is different from SUM.
13480         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13481         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13482         cancel_lru_locks osc
13483         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13484         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13485
13486         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13487         stack_trap "rm -f $TMP/$tfile.tmp"
13488         while read name count samp unit min max sum sumsq; do
13489                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13490                 eval $name=$count || error "Wrong proc format"
13491
13492                 case $name in
13493                 read_bytes|write_bytes)
13494                         [[ "$unit" =~ "bytes" ]] ||
13495                                 error "unit is not 'bytes': $unit"
13496                         (( $count == 2 )) || error "count is not 2: $count"
13497                         (( $min == $PAGE_SIZE )) ||
13498                                 error "min is not $PAGE_SIZE: $min"
13499                         (( $max == $PAGE_SIZE )) ||
13500                                 error "max is not $PAGE_SIZE: $max"
13501                         (( $sum == $PAGE_SIZE * 2 )) ||
13502                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13503                         ;;
13504                 read|write)
13505                         [[ "$unit" =~ "usec" ]] ||
13506                                 error "unit is not 'usec': $unit"
13507                         ;;
13508                 *)      ;;
13509                 esac
13510         done < $TMP/$tfile.tmp
13511
13512         #check that we actually got some stats
13513         [ "$read_bytes" ] || error "Missing read_bytes stats"
13514         [ "$write_bytes" ] || error "Missing write_bytes stats"
13515         [ "$read_bytes" != 0 ] || error "no read done"
13516         [ "$write_bytes" != 0 ] || error "no write done"
13517 }
13518 run_test 127b "verify the llite client stats are sane"
13519
13520 test_127c() { # LU-12394
13521         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13522         local size
13523         local bsize
13524         local reads
13525         local writes
13526         local count
13527
13528         $LCTL set_param llite.*.extents_stats=1
13529         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13530
13531         # Use two stripes so there is enough space in default config
13532         $LFS setstripe -c 2 $DIR/$tfile
13533
13534         # Extent stats start at 0-4K and go in power of two buckets
13535         # LL_HIST_START = 12 --> 2^12 = 4K
13536         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13537         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13538         # small configs
13539         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13540                 do
13541                 # Write and read, 2x each, second time at a non-zero offset
13542                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13543                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13544                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13545                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13546                 rm -f $DIR/$tfile
13547         done
13548
13549         $LCTL get_param llite.*.extents_stats
13550
13551         count=2
13552         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13553                 do
13554                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13555                                 grep -m 1 $bsize)
13556                 reads=$(echo $bucket | awk '{print $5}')
13557                 writes=$(echo $bucket | awk '{print $9}')
13558                 [ "$reads" -eq $count ] ||
13559                         error "$reads reads in < $bsize bucket, expect $count"
13560                 [ "$writes" -eq $count ] ||
13561                         error "$writes writes in < $bsize bucket, expect $count"
13562         done
13563
13564         # Test mmap write and read
13565         $LCTL set_param llite.*.extents_stats=c
13566         size=512
13567         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13568         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13569         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13570
13571         $LCTL get_param llite.*.extents_stats
13572
13573         count=$(((size*1024) / PAGE_SIZE))
13574
13575         bsize=$((2 * PAGE_SIZE / 1024))K
13576
13577         bucket=$($LCTL get_param -n llite.*.extents_stats |
13578                         grep -m 1 $bsize)
13579         reads=$(echo $bucket | awk '{print $5}')
13580         writes=$(echo $bucket | awk '{print $9}')
13581         # mmap writes fault in the page first, creating an additonal read
13582         [ "$reads" -eq $((2 * count)) ] ||
13583                 error "$reads reads in < $bsize bucket, expect $count"
13584         [ "$writes" -eq $count ] ||
13585                 error "$writes writes in < $bsize bucket, expect $count"
13586 }
13587 run_test 127c "test llite extent stats with regular & mmap i/o"
13588
13589 test_128() { # bug 15212
13590         touch $DIR/$tfile
13591         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13592                 find $DIR/$tfile
13593                 find $DIR/$tfile
13594         EOF
13595
13596         result=$(grep error $TMP/$tfile.log)
13597         rm -f $DIR/$tfile $TMP/$tfile.log
13598         [ -z "$result" ] ||
13599                 error "consecutive find's under interactive lfs failed"
13600 }
13601 run_test 128 "interactive lfs for 2 consecutive find's"
13602
13603 set_dir_limits () {
13604         local mntdev
13605         local canondev
13606         local node
13607
13608         local ldproc=/proc/fs/ldiskfs
13609         local facets=$(get_facets MDS)
13610
13611         for facet in ${facets//,/ }; do
13612                 canondev=$(ldiskfs_canon \
13613                            *.$(convert_facet2label $facet).mntdev $facet)
13614                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13615                         ldproc=/sys/fs/ldiskfs
13616                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13617                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13618         done
13619 }
13620
13621 check_mds_dmesg() {
13622         local facets=$(get_facets MDS)
13623         for facet in ${facets//,/ }; do
13624                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13625         done
13626         return 1
13627 }
13628
13629 test_129() {
13630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13631         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13632                 skip "Need MDS version with at least 2.5.56"
13633         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13634                 skip_env "ldiskfs only test"
13635         fi
13636         remote_mds_nodsh && skip "remote MDS with nodsh"
13637
13638         local ENOSPC=28
13639         local has_warning=false
13640
13641         rm -rf $DIR/$tdir
13642         mkdir -p $DIR/$tdir
13643
13644         # block size of mds1
13645         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13646         set_dir_limits $maxsize $((maxsize * 6 / 8))
13647         stack_trap "set_dir_limits 0 0"
13648         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13649         local dirsize=$(stat -c%s "$DIR/$tdir")
13650         local nfiles=0
13651         while (( $dirsize <= $maxsize )); do
13652                 $MCREATE $DIR/$tdir/file_base_$nfiles
13653                 rc=$?
13654                 # check two errors:
13655                 # ENOSPC for ext4 max_dir_size, which has been used since
13656                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13657                 if (( rc == ENOSPC )); then
13658                         set_dir_limits 0 0
13659                         echo "rc=$rc returned as expected after $nfiles files"
13660
13661                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13662                                 error "create failed w/o dir size limit"
13663
13664                         # messages may be rate limited if test is run repeatedly
13665                         check_mds_dmesg '"is approaching max"' ||
13666                                 echo "warning message should be output"
13667                         check_mds_dmesg '"has reached max"' ||
13668                                 echo "reached message should be output"
13669
13670                         dirsize=$(stat -c%s "$DIR/$tdir")
13671
13672                         [[ $dirsize -ge $maxsize ]] && return 0
13673                         error "dirsize $dirsize < $maxsize after $nfiles files"
13674                 elif (( rc != 0 )); then
13675                         break
13676                 fi
13677                 nfiles=$((nfiles + 1))
13678                 dirsize=$(stat -c%s "$DIR/$tdir")
13679         done
13680
13681         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13682 }
13683 run_test 129 "test directory size limit ========================"
13684
13685 OLDIFS="$IFS"
13686 cleanup_130() {
13687         trap 0
13688         IFS="$OLDIFS"
13689 }
13690
13691 test_130a() {
13692         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13693         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13694
13695         trap cleanup_130 EXIT RETURN
13696
13697         local fm_file=$DIR/$tfile
13698         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13699         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13700                 error "dd failed for $fm_file"
13701
13702         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13703         filefrag -ves $fm_file
13704         RC=$?
13705         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13706                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13707         [ $RC != 0 ] && error "filefrag $fm_file failed"
13708
13709         filefrag_op=$(filefrag -ve -k $fm_file |
13710                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13711         lun=$($LFS getstripe -i $fm_file)
13712
13713         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13714         IFS=$'\n'
13715         tot_len=0
13716         for line in $filefrag_op
13717         do
13718                 frag_lun=`echo $line | cut -d: -f5`
13719                 ext_len=`echo $line | cut -d: -f4`
13720                 if (( $frag_lun != $lun )); then
13721                         cleanup_130
13722                         error "FIEMAP on 1-stripe file($fm_file) failed"
13723                         return
13724                 fi
13725                 (( tot_len += ext_len ))
13726         done
13727
13728         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13729                 cleanup_130
13730                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13731                 return
13732         fi
13733
13734         cleanup_130
13735
13736         echo "FIEMAP on single striped file succeeded"
13737 }
13738 run_test 130a "FIEMAP (1-stripe file)"
13739
13740 test_130b() {
13741         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13742
13743         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13744         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13745
13746         trap cleanup_130 EXIT RETURN
13747
13748         local fm_file=$DIR/$tfile
13749         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13750                         error "setstripe on $fm_file"
13751         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13752                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13753
13754         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13755                 error "dd failed on $fm_file"
13756
13757         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13758         filefrag_op=$(filefrag -ve -k $fm_file |
13759                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13760
13761         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13762                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13763
13764         IFS=$'\n'
13765         tot_len=0
13766         num_luns=1
13767         for line in $filefrag_op
13768         do
13769                 frag_lun=$(echo $line | cut -d: -f5 |
13770                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13771                 ext_len=$(echo $line | cut -d: -f4)
13772                 if (( $frag_lun != $last_lun )); then
13773                         if (( tot_len != 1024 )); then
13774                                 cleanup_130
13775                                 error "FIEMAP on $fm_file failed; returned " \
13776                                 "len $tot_len for OST $last_lun instead of 1024"
13777                                 return
13778                         else
13779                                 (( num_luns += 1 ))
13780                                 tot_len=0
13781                         fi
13782                 fi
13783                 (( tot_len += ext_len ))
13784                 last_lun=$frag_lun
13785         done
13786         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13787                 cleanup_130
13788                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13789                         "luns or wrong len for OST $last_lun"
13790                 return
13791         fi
13792
13793         cleanup_130
13794
13795         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13796 }
13797 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13798
13799 test_130c() {
13800         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13801
13802         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13803         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13804
13805         trap cleanup_130 EXIT RETURN
13806
13807         local fm_file=$DIR/$tfile
13808         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13809         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13810                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13811
13812         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13813                         error "dd failed on $fm_file"
13814
13815         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13816         filefrag_op=$(filefrag -ve -k $fm_file |
13817                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13818
13819         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13820                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13821
13822         IFS=$'\n'
13823         tot_len=0
13824         num_luns=1
13825         for line in $filefrag_op
13826         do
13827                 frag_lun=$(echo $line | cut -d: -f5 |
13828                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13829                 ext_len=$(echo $line | cut -d: -f4)
13830                 if (( $frag_lun != $last_lun )); then
13831                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13832                         if (( logical != 512 )); then
13833                                 cleanup_130
13834                                 error "FIEMAP on $fm_file failed; returned " \
13835                                 "logical start for lun $logical instead of 512"
13836                                 return
13837                         fi
13838                         if (( tot_len != 512 )); then
13839                                 cleanup_130
13840                                 error "FIEMAP on $fm_file failed; returned " \
13841                                 "len $tot_len for OST $last_lun instead of 1024"
13842                                 return
13843                         else
13844                                 (( num_luns += 1 ))
13845                                 tot_len=0
13846                         fi
13847                 fi
13848                 (( tot_len += ext_len ))
13849                 last_lun=$frag_lun
13850         done
13851         if (( num_luns != 2 || tot_len != 512 )); then
13852                 cleanup_130
13853                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13854                         "luns or wrong len for OST $last_lun"
13855                 return
13856         fi
13857
13858         cleanup_130
13859
13860         echo "FIEMAP on 2-stripe file with hole succeeded"
13861 }
13862 run_test 130c "FIEMAP (2-stripe file with hole)"
13863
13864 test_130d() {
13865         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13866
13867         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13868         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13869
13870         trap cleanup_130 EXIT RETURN
13871
13872         local fm_file=$DIR/$tfile
13873         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13874                         error "setstripe on $fm_file"
13875         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13876                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13877
13878         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13879         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13880                 error "dd failed on $fm_file"
13881
13882         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13883         filefrag_op=$(filefrag -ve -k $fm_file |
13884                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13885
13886         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13887                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13888
13889         IFS=$'\n'
13890         tot_len=0
13891         num_luns=1
13892         for line in $filefrag_op
13893         do
13894                 frag_lun=$(echo $line | cut -d: -f5 |
13895                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13896                 ext_len=$(echo $line | cut -d: -f4)
13897                 if (( $frag_lun != $last_lun )); then
13898                         if (( tot_len != 1024 )); then
13899                                 cleanup_130
13900                                 error "FIEMAP on $fm_file failed; returned " \
13901                                 "len $tot_len for OST $last_lun instead of 1024"
13902                                 return
13903                         else
13904                                 (( num_luns += 1 ))
13905                                 tot_len=0
13906                         fi
13907                 fi
13908                 (( tot_len += ext_len ))
13909                 last_lun=$frag_lun
13910         done
13911         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13912                 cleanup_130
13913                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13914                         "luns or wrong len for OST $last_lun"
13915                 return
13916         fi
13917
13918         cleanup_130
13919
13920         echo "FIEMAP on N-stripe file succeeded"
13921 }
13922 run_test 130d "FIEMAP (N-stripe file)"
13923
13924 test_130e() {
13925         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13926
13927         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13928         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13929
13930         trap cleanup_130 EXIT RETURN
13931
13932         local fm_file=$DIR/$tfile
13933         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13934
13935         NUM_BLKS=512
13936         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13937         for ((i = 0; i < $NUM_BLKS; i++)); do
13938                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13939                         conv=notrunc > /dev/null 2>&1
13940         done
13941
13942         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13943         filefrag_op=$(filefrag -ve -k $fm_file |
13944                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13945
13946         last_lun=$(echo $filefrag_op | cut -d: -f5)
13947
13948         IFS=$'\n'
13949         tot_len=0
13950         num_luns=1
13951         for line in $filefrag_op; do
13952                 frag_lun=$(echo $line | cut -d: -f5)
13953                 ext_len=$(echo $line | cut -d: -f4)
13954                 if [[ "$frag_lun" != "$last_lun" ]]; then
13955                         if (( tot_len != $EXPECTED_LEN )); then
13956                                 cleanup_130
13957                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13958                         else
13959                                 (( num_luns += 1 ))
13960                                 tot_len=0
13961                         fi
13962                 fi
13963                 (( tot_len += ext_len ))
13964                 last_lun=$frag_lun
13965         done
13966         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13967                 cleanup_130
13968                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13969         fi
13970
13971         echo "FIEMAP with continuation calls succeeded"
13972 }
13973 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13974
13975 test_130f() {
13976         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13977         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13978
13979         local fm_file=$DIR/$tfile
13980         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13981                 error "multiop create with lov_delay_create on $fm_file"
13982
13983         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13984         filefrag_extents=$(filefrag -vek $fm_file |
13985                            awk '/extents? found/ { print $2 }')
13986         if [[ "$filefrag_extents" != "0" ]]; then
13987                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13988         fi
13989
13990         rm -f $fm_file
13991 }
13992 run_test 130f "FIEMAP (unstriped file)"
13993
13994 test_130g() {
13995         local file=$DIR/$tfile
13996         local nr=$((OSTCOUNT * 100))
13997
13998         $LFS setstripe -C $nr $file ||
13999                 error "failed to setstripe -C $nr $file"
14000
14001         dd if=/dev/zero of=$file count=$nr bs=1M
14002         sync
14003         nr=$($LFS getstripe -c $file)
14004
14005         local extents=$(filefrag -v $file |
14006                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14007
14008         echo "filefrag list $extents extents in file with stripecount $nr"
14009         if (( extents < nr )); then
14010                 $LFS getstripe $file
14011                 filefrag -v $file
14012                 error "filefrag printed $extents < $nr extents"
14013         fi
14014
14015         rm -f $file
14016 }
14017 run_test 130g "FIEMAP (overstripe file)"
14018
14019 # Test for writev/readv
14020 test_131a() {
14021         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14022                 error "writev test failed"
14023         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14024                 error "readv failed"
14025         rm -f $DIR/$tfile
14026 }
14027 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14028
14029 test_131b() {
14030         local fsize=$((524288 + 1048576 + 1572864))
14031         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14032                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14033                         error "append writev test failed"
14034
14035         ((fsize += 1572864 + 1048576))
14036         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14037                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14038                         error "append writev test failed"
14039         rm -f $DIR/$tfile
14040 }
14041 run_test 131b "test append writev"
14042
14043 test_131c() {
14044         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14045         error "NOT PASS"
14046 }
14047 run_test 131c "test read/write on file w/o objects"
14048
14049 test_131d() {
14050         rwv -f $DIR/$tfile -w -n 1 1572864
14051         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14052         if [ "$NOB" != 1572864 ]; then
14053                 error "Short read filed: read $NOB bytes instead of 1572864"
14054         fi
14055         rm -f $DIR/$tfile
14056 }
14057 run_test 131d "test short read"
14058
14059 test_131e() {
14060         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14061         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14062         error "read hitting hole failed"
14063         rm -f $DIR/$tfile
14064 }
14065 run_test 131e "test read hitting hole"
14066
14067 check_stats() {
14068         local facet=$1
14069         local op=$2
14070         local want=${3:-0}
14071         local res
14072
14073         case $facet in
14074         mds*) res=$(do_facet $facet \
14075                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
14076                  ;;
14077         ost*) res=$(do_facet $facet \
14078                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
14079                  ;;
14080         *) error "Wrong facet '$facet'" ;;
14081         esac
14082         [ "$res" ] || error "The counter for $op on $facet was not incremented"
14083         # if the argument $3 is zero, it means any stat increment is ok.
14084         if [[ $want -gt 0 ]]; then
14085                 local count=$(echo $res | awk '{ print $2 }')
14086                 [[ $count -ne $want ]] &&
14087                         error "The $op counter on $facet is $count, not $want"
14088         fi
14089 }
14090
14091 test_133a() {
14092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14093         remote_ost_nodsh && skip "remote OST with nodsh"
14094         remote_mds_nodsh && skip "remote MDS with nodsh"
14095         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14096                 skip_env "MDS doesn't support rename stats"
14097
14098         local testdir=$DIR/${tdir}/stats_testdir
14099
14100         mkdir -p $DIR/${tdir}
14101
14102         # clear stats.
14103         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14104         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14105
14106         # verify mdt stats first.
14107         mkdir ${testdir} || error "mkdir failed"
14108         check_stats $SINGLEMDS "mkdir" 1
14109         touch ${testdir}/${tfile} || error "touch failed"
14110         check_stats $SINGLEMDS "open" 1
14111         check_stats $SINGLEMDS "close" 1
14112         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14113                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14114                 check_stats $SINGLEMDS "mknod" 2
14115         }
14116         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14117         check_stats $SINGLEMDS "unlink" 1
14118         rm -f ${testdir}/${tfile} || error "file remove failed"
14119         check_stats $SINGLEMDS "unlink" 2
14120
14121         # remove working dir and check mdt stats again.
14122         rmdir ${testdir} || error "rmdir failed"
14123         check_stats $SINGLEMDS "rmdir" 1
14124
14125         local testdir1=$DIR/${tdir}/stats_testdir1
14126         mkdir -p ${testdir}
14127         mkdir -p ${testdir1}
14128         touch ${testdir1}/test1
14129         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14130         check_stats $SINGLEMDS "crossdir_rename" 1
14131
14132         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14133         check_stats $SINGLEMDS "samedir_rename" 1
14134
14135         rm -rf $DIR/${tdir}
14136 }
14137 run_test 133a "Verifying MDT stats ========================================"
14138
14139 test_133b() {
14140         local res
14141
14142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14143         remote_ost_nodsh && skip "remote OST with nodsh"
14144         remote_mds_nodsh && skip "remote MDS with nodsh"
14145
14146         local testdir=$DIR/${tdir}/stats_testdir
14147
14148         mkdir -p ${testdir} || error "mkdir failed"
14149         touch ${testdir}/${tfile} || error "touch failed"
14150         cancel_lru_locks mdc
14151
14152         # clear stats.
14153         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14154         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14155
14156         # extra mdt stats verification.
14157         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14158         check_stats $SINGLEMDS "setattr" 1
14159         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14160         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14161         then            # LU-1740
14162                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14163                 check_stats $SINGLEMDS "getattr" 1
14164         fi
14165         rm -rf $DIR/${tdir}
14166
14167         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14168         # so the check below is not reliable
14169         [ $MDSCOUNT -eq 1 ] || return 0
14170
14171         # Sleep to avoid a cached response.
14172         #define OBD_STATFS_CACHE_SECONDS 1
14173         sleep 2
14174         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14175         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14176         $LFS df || error "lfs failed"
14177         check_stats $SINGLEMDS "statfs" 1
14178
14179         # check aggregated statfs (LU-10018)
14180         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14181                 return 0
14182         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14183                 return 0
14184         sleep 2
14185         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14186         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14187         df $DIR
14188         check_stats $SINGLEMDS "statfs" 1
14189
14190         # We want to check that the client didn't send OST_STATFS to
14191         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14192         # extra care is needed here.
14193         if remote_mds; then
14194                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14195                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14196
14197                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14198                 [ "$res" ] && error "OST got STATFS"
14199         fi
14200
14201         return 0
14202 }
14203 run_test 133b "Verifying extra MDT stats =================================="
14204
14205 test_133c() {
14206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14207         remote_ost_nodsh && skip "remote OST with nodsh"
14208         remote_mds_nodsh && skip "remote MDS with nodsh"
14209
14210         local testdir=$DIR/$tdir/stats_testdir
14211
14212         test_mkdir -p $testdir
14213
14214         # verify obdfilter stats.
14215         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14216         sync
14217         cancel_lru_locks osc
14218         wait_delete_completed
14219
14220         # clear stats.
14221         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14222         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14223
14224         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14225                 error "dd failed"
14226         sync
14227         cancel_lru_locks osc
14228         check_stats ost1 "write" 1
14229
14230         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14231         check_stats ost1 "read" 1
14232
14233         > $testdir/$tfile || error "truncate failed"
14234         check_stats ost1 "punch" 1
14235
14236         rm -f $testdir/$tfile || error "file remove failed"
14237         wait_delete_completed
14238         check_stats ost1 "destroy" 1
14239
14240         rm -rf $DIR/$tdir
14241 }
14242 run_test 133c "Verifying OST stats ========================================"
14243
14244 order_2() {
14245         local value=$1
14246         local orig=$value
14247         local order=1
14248
14249         while [ $value -ge 2 ]; do
14250                 order=$((order*2))
14251                 value=$((value/2))
14252         done
14253
14254         if [ $orig -gt $order ]; then
14255                 order=$((order*2))
14256         fi
14257         echo $order
14258 }
14259
14260 size_in_KMGT() {
14261     local value=$1
14262     local size=('K' 'M' 'G' 'T');
14263     local i=0
14264     local size_string=$value
14265
14266     while [ $value -ge 1024 ]; do
14267         if [ $i -gt 3 ]; then
14268             #T is the biggest unit we get here, if that is bigger,
14269             #just return XXXT
14270             size_string=${value}T
14271             break
14272         fi
14273         value=$((value >> 10))
14274         if [ $value -lt 1024 ]; then
14275             size_string=${value}${size[$i]}
14276             break
14277         fi
14278         i=$((i + 1))
14279     done
14280
14281     echo $size_string
14282 }
14283
14284 get_rename_size() {
14285         local size=$1
14286         local context=${2:-.}
14287         local sample=$(do_facet $SINGLEMDS $LCTL \
14288                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14289                 grep -A1 $context |
14290                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14291         echo $sample
14292 }
14293
14294 test_133d() {
14295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14296         remote_ost_nodsh && skip "remote OST with nodsh"
14297         remote_mds_nodsh && skip "remote MDS with nodsh"
14298         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14299                 skip_env "MDS doesn't support rename stats"
14300
14301         local testdir1=$DIR/${tdir}/stats_testdir1
14302         local testdir2=$DIR/${tdir}/stats_testdir2
14303         mkdir -p $DIR/${tdir}
14304
14305         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14306
14307         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14308         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14309
14310         createmany -o $testdir1/test 512 || error "createmany failed"
14311
14312         # check samedir rename size
14313         mv ${testdir1}/test0 ${testdir1}/test_0
14314
14315         local testdir1_size=$(ls -l $DIR/${tdir} |
14316                 awk '/stats_testdir1/ {print $5}')
14317         local testdir2_size=$(ls -l $DIR/${tdir} |
14318                 awk '/stats_testdir2/ {print $5}')
14319
14320         testdir1_size=$(order_2 $testdir1_size)
14321         testdir2_size=$(order_2 $testdir2_size)
14322
14323         testdir1_size=$(size_in_KMGT $testdir1_size)
14324         testdir2_size=$(size_in_KMGT $testdir2_size)
14325
14326         echo "source rename dir size: ${testdir1_size}"
14327         echo "target rename dir size: ${testdir2_size}"
14328
14329         local cmd="do_facet $SINGLEMDS $LCTL "
14330         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14331
14332         eval $cmd || error "$cmd failed"
14333         local samedir=$($cmd | grep 'same_dir')
14334         local same_sample=$(get_rename_size $testdir1_size)
14335         [ -z "$samedir" ] && error "samedir_rename_size count error"
14336         [[ $same_sample -eq 1 ]] ||
14337                 error "samedir_rename_size error $same_sample"
14338         echo "Check same dir rename stats success"
14339
14340         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14341
14342         # check crossdir rename size
14343         mv ${testdir1}/test_0 ${testdir2}/test_0
14344
14345         testdir1_size=$(ls -l $DIR/${tdir} |
14346                 awk '/stats_testdir1/ {print $5}')
14347         testdir2_size=$(ls -l $DIR/${tdir} |
14348                 awk '/stats_testdir2/ {print $5}')
14349
14350         testdir1_size=$(order_2 $testdir1_size)
14351         testdir2_size=$(order_2 $testdir2_size)
14352
14353         testdir1_size=$(size_in_KMGT $testdir1_size)
14354         testdir2_size=$(size_in_KMGT $testdir2_size)
14355
14356         echo "source rename dir size: ${testdir1_size}"
14357         echo "target rename dir size: ${testdir2_size}"
14358
14359         eval $cmd || error "$cmd failed"
14360         local crossdir=$($cmd | grep 'crossdir')
14361         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14362         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14363         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14364         [[ $src_sample -eq 1 ]] ||
14365                 error "crossdir_rename_size error $src_sample"
14366         [[ $tgt_sample -eq 1 ]] ||
14367                 error "crossdir_rename_size error $tgt_sample"
14368         echo "Check cross dir rename stats success"
14369         rm -rf $DIR/${tdir}
14370 }
14371 run_test 133d "Verifying rename_stats ========================================"
14372
14373 test_133e() {
14374         remote_mds_nodsh && skip "remote MDS with nodsh"
14375         remote_ost_nodsh && skip "remote OST with nodsh"
14376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14377
14378         local testdir=$DIR/${tdir}/stats_testdir
14379         local ctr f0 f1 bs=32768 count=42 sum
14380
14381         mkdir -p ${testdir} || error "mkdir failed"
14382
14383         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14384
14385         for ctr in {write,read}_bytes; do
14386                 sync
14387                 cancel_lru_locks osc
14388
14389                 do_facet ost1 $LCTL set_param -n \
14390                         "obdfilter.*.exports.clear=clear"
14391
14392                 if [ $ctr = write_bytes ]; then
14393                         f0=/dev/zero
14394                         f1=${testdir}/${tfile}
14395                 else
14396                         f0=${testdir}/${tfile}
14397                         f1=/dev/null
14398                 fi
14399
14400                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14401                         error "dd failed"
14402                 sync
14403                 cancel_lru_locks osc
14404
14405                 sum=$(do_facet ost1 $LCTL get_param \
14406                         "obdfilter.*.exports.*.stats" |
14407                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14408                                 $1 == ctr { sum += $7 }
14409                                 END { printf("%0.0f", sum) }')
14410
14411                 if ((sum != bs * count)); then
14412                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14413                 fi
14414         done
14415
14416         rm -rf $DIR/${tdir}
14417 }
14418 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14419
14420 test_133f() {
14421         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14422                 skip "too old lustre for get_param -R ($facet_ver)"
14423
14424         # verifying readability.
14425         $LCTL get_param -R '*' &> /dev/null
14426
14427         # Verifing writability with badarea_io.
14428         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14429         local skipped_params='force_lbug|changelog_mask|daemon_file'
14430         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14431                 egrep -v "$skipped_params" |
14432                 xargs -n 1 find $proc_dirs -name |
14433                 xargs -n 1 badarea_io ||
14434                 error "client badarea_io failed"
14435
14436         # remount the FS in case writes/reads /proc break the FS
14437         cleanup || error "failed to unmount"
14438         setup || error "failed to setup"
14439 }
14440 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14441
14442 test_133g() {
14443         remote_mds_nodsh && skip "remote MDS with nodsh"
14444         remote_ost_nodsh && skip "remote OST with nodsh"
14445
14446         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14447         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14448         local facet
14449         for facet in mds1 ost1; do
14450                 local facet_ver=$(lustre_version_code $facet)
14451                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14452                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14453                 else
14454                         log "$facet: too old lustre for get_param -R"
14455                 fi
14456                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14457                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14458                                 tr -d = | egrep -v $skipped_params |
14459                                 xargs -n 1 find $proc_dirs -name |
14460                                 xargs -n 1 badarea_io" ||
14461                                         error "$facet badarea_io failed"
14462                 else
14463                         skip_noexit "$facet: too old lustre for get_param -R"
14464                 fi
14465         done
14466
14467         # remount the FS in case writes/reads /proc break the FS
14468         cleanup || error "failed to unmount"
14469         setup || error "failed to setup"
14470 }
14471 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14472
14473 test_133h() {
14474         remote_mds_nodsh && skip "remote MDS with nodsh"
14475         remote_ost_nodsh && skip "remote OST with nodsh"
14476         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14477                 skip "Need MDS version at least 2.9.54"
14478
14479         local facet
14480         for facet in client mds1 ost1; do
14481                 # Get the list of files that are missing the terminating newline
14482                 local plist=$(do_facet $facet
14483                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14484                 local ent
14485                 for ent in $plist; do
14486                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14487                                 awk -v FS='\v' -v RS='\v\v' \
14488                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14489                                         print FILENAME}'" 2>/dev/null)
14490                         [ -z $missing ] || {
14491                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14492                                 error "file does not end with newline: $facet-$ent"
14493                         }
14494                 done
14495         done
14496 }
14497 run_test 133h "Proc files should end with newlines"
14498
14499 test_134a() {
14500         remote_mds_nodsh && skip "remote MDS with nodsh"
14501         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14502                 skip "Need MDS version at least 2.7.54"
14503
14504         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14505         cancel_lru_locks mdc
14506
14507         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14508         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14509         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14510
14511         local nr=1000
14512         createmany -o $DIR/$tdir/f $nr ||
14513                 error "failed to create $nr files in $DIR/$tdir"
14514         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14515
14516         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14517         do_facet mds1 $LCTL set_param fail_loc=0x327
14518         do_facet mds1 $LCTL set_param fail_val=500
14519         touch $DIR/$tdir/m
14520
14521         echo "sleep 10 seconds ..."
14522         sleep 10
14523         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14524
14525         do_facet mds1 $LCTL set_param fail_loc=0
14526         do_facet mds1 $LCTL set_param fail_val=0
14527         [ $lck_cnt -lt $unused ] ||
14528                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14529
14530         rm $DIR/$tdir/m
14531         unlinkmany $DIR/$tdir/f $nr
14532 }
14533 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14534
14535 test_134b() {
14536         remote_mds_nodsh && skip "remote MDS with nodsh"
14537         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14538                 skip "Need MDS version at least 2.7.54"
14539
14540         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14541         cancel_lru_locks mdc
14542
14543         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14544                         ldlm.lock_reclaim_threshold_mb)
14545         # disable reclaim temporarily
14546         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14547
14548         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14549         do_facet mds1 $LCTL set_param fail_loc=0x328
14550         do_facet mds1 $LCTL set_param fail_val=500
14551
14552         $LCTL set_param debug=+trace
14553
14554         local nr=600
14555         createmany -o $DIR/$tdir/f $nr &
14556         local create_pid=$!
14557
14558         echo "Sleep $TIMEOUT seconds ..."
14559         sleep $TIMEOUT
14560         if ! ps -p $create_pid  > /dev/null 2>&1; then
14561                 do_facet mds1 $LCTL set_param fail_loc=0
14562                 do_facet mds1 $LCTL set_param fail_val=0
14563                 do_facet mds1 $LCTL set_param \
14564                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14565                 error "createmany finished incorrectly!"
14566         fi
14567         do_facet mds1 $LCTL set_param fail_loc=0
14568         do_facet mds1 $LCTL set_param fail_val=0
14569         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14570         wait $create_pid || return 1
14571
14572         unlinkmany $DIR/$tdir/f $nr
14573 }
14574 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14575
14576 test_135() {
14577         remote_mds_nodsh && skip "remote MDS with nodsh"
14578         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14579                 skip "Need MDS version at least 2.13.50"
14580         local fname
14581
14582         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14583
14584 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14585         #set only one record at plain llog
14586         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14587
14588         #fill already existed plain llog each 64767
14589         #wrapping whole catalog
14590         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14591
14592         createmany -o $DIR/$tdir/$tfile_ 64700
14593         for (( i = 0; i < 64700; i = i + 2 ))
14594         do
14595                 rm $DIR/$tdir/$tfile_$i &
14596                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14597                 local pid=$!
14598                 wait $pid
14599         done
14600
14601         #waiting osp synchronization
14602         wait_delete_completed
14603 }
14604 run_test 135 "Race catalog processing"
14605
14606 test_136() {
14607         remote_mds_nodsh && skip "remote MDS with nodsh"
14608         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14609                 skip "Need MDS version at least 2.13.50"
14610         local fname
14611
14612         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14613         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14614         #set only one record at plain llog
14615 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14616         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14617
14618         #fill already existed 2 plain llogs each 64767
14619         #wrapping whole catalog
14620         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14621         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14622         wait_delete_completed
14623
14624         createmany -o $DIR/$tdir/$tfile_ 10
14625         sleep 25
14626
14627         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14628         for (( i = 0; i < 10; i = i + 3 ))
14629         do
14630                 rm $DIR/$tdir/$tfile_$i &
14631                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14632                 local pid=$!
14633                 wait $pid
14634                 sleep 7
14635                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14636         done
14637
14638         #waiting osp synchronization
14639         wait_delete_completed
14640 }
14641 run_test 136 "Race catalog processing 2"
14642
14643 test_140() { #bug-17379
14644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14645
14646         test_mkdir $DIR/$tdir
14647         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14648         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14649
14650         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14651         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14652         local i=0
14653         while i=$((i + 1)); do
14654                 test_mkdir $i
14655                 cd $i || error "Changing to $i"
14656                 ln -s ../stat stat || error "Creating stat symlink"
14657                 # Read the symlink until ELOOP present,
14658                 # not LBUGing the system is considered success,
14659                 # we didn't overrun the stack.
14660                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14661                 if [ $ret -ne 0 ]; then
14662                         if [ $ret -eq 40 ]; then
14663                                 break  # -ELOOP
14664                         else
14665                                 error "Open stat symlink"
14666                                         return
14667                         fi
14668                 fi
14669         done
14670         i=$((i - 1))
14671         echo "The symlink depth = $i"
14672         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14673                 error "Invalid symlink depth"
14674
14675         # Test recursive symlink
14676         ln -s symlink_self symlink_self
14677         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14678         echo "open symlink_self returns $ret"
14679         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14680 }
14681 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14682
14683 test_150a() {
14684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14685
14686         local TF="$TMP/$tfile"
14687
14688         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14689         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14690         cp $TF $DIR/$tfile
14691         cancel_lru_locks $OSC
14692         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14693         remount_client $MOUNT
14694         df -P $MOUNT
14695         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14696
14697         $TRUNCATE $TF 6000
14698         $TRUNCATE $DIR/$tfile 6000
14699         cancel_lru_locks $OSC
14700         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14701
14702         echo "12345" >>$TF
14703         echo "12345" >>$DIR/$tfile
14704         cancel_lru_locks $OSC
14705         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14706
14707         echo "12345" >>$TF
14708         echo "12345" >>$DIR/$tfile
14709         cancel_lru_locks $OSC
14710         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14711 }
14712 run_test 150a "truncate/append tests"
14713
14714 test_150b() {
14715         check_set_fallocate_or_skip
14716
14717         touch $DIR/$tfile
14718         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14719         check_fallocate $DIR/$tfile || skip_eopnotsupp "fallocate failed"
14720 }
14721 run_test 150b "Verify fallocate (prealloc) functionality"
14722
14723 test_150bb() {
14724         check_set_fallocate_or_skip
14725
14726         touch $DIR/$tfile
14727         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14728         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14729         > $DIR/$tfile
14730         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14731         # precomputed md5sum for 20MB of zeroes
14732         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14733         local sum=($(md5sum $DIR/$tfile))
14734
14735         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14736
14737         check_set_fallocate 1
14738
14739         > $DIR/$tfile
14740         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14741         sum=($(md5sum $DIR/$tfile))
14742
14743         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14744 }
14745 run_test 150bb "Verify fallocate modes both zero space"
14746
14747 test_150c() {
14748         check_set_fallocate_or_skip
14749         local striping="-c2"
14750
14751         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14752         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14753         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14754         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14755         local want=$((OSTCOUNT * 1048576))
14756
14757         # Must allocate all requested space, not more than 5% extra
14758         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14759                 error "bytes $bytes is not $want"
14760
14761         rm -f $DIR/$tfile
14762
14763         echo "verify fallocate on PFL file"
14764
14765         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14766
14767         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14768                 error "Create $DIR/$tfile failed"
14769         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
14770         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14771         want=$((512 * 1048576))
14772
14773         # Must allocate all requested space, not more than 5% extra
14774         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14775                 error "bytes $bytes is not $want"
14776 }
14777 run_test 150c "Verify fallocate Size and Blocks"
14778
14779 test_150d() {
14780         check_set_fallocate_or_skip
14781         local striping="-c2"
14782
14783         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14784
14785         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14786         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14787                 error "setstripe failed"
14788         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14789         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14790         local want=$((OSTCOUNT * 1048576))
14791
14792         # Must allocate all requested space, not more than 5% extra
14793         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14794                 error "bytes $bytes is not $want"
14795 }
14796 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14797
14798 test_150e() {
14799         check_set_fallocate_or_skip
14800
14801         echo "df before:"
14802         $LFS df
14803         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14804         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14805                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14806
14807         # Find OST with Minimum Size
14808         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14809                        sort -un | head -1)
14810
14811         # Get 100MB per OST of the available space to reduce run time
14812         # else 60% of the available space if we are running SLOW tests
14813         if [ $SLOW == "no" ]; then
14814                 local space=$((1024 * 100 * OSTCOUNT))
14815         else
14816                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14817         fi
14818
14819         fallocate -l${space}k $DIR/$tfile ||
14820                 error "fallocate ${space}k $DIR/$tfile failed"
14821         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14822
14823         # get size immediately after fallocate. This should be correctly
14824         # updated
14825         local size=$(stat -c '%s' $DIR/$tfile)
14826         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14827
14828         # Sleep for a while for statfs to get updated. And not pull from cache.
14829         sleep 2
14830
14831         echo "df after fallocate:"
14832         $LFS df
14833
14834         (( size / 1024 == space )) || error "size $size != requested $space"
14835         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14836                 error "used $used < space $space"
14837
14838         rm $DIR/$tfile || error "rm failed"
14839         sync
14840         wait_delete_completed
14841
14842         echo "df after unlink:"
14843         $LFS df
14844 }
14845 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14846
14847 test_150f() {
14848         local size
14849         local blocks
14850         local want_size_before=20480 # in bytes
14851         local want_blocks_before=40 # 512 sized blocks
14852         local want_blocks_after=24  # 512 sized blocks
14853         local length=$(((want_blocks_before - want_blocks_after) * 512))
14854
14855         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14856                 skip "need at least 2.14.0 for fallocate punch"
14857
14858         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14859                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14860         fi
14861
14862         check_set_fallocate_or_skip
14863         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14864
14865         [[ "x$DOM" == "xyes" ]] &&
14866                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14867
14868         echo "Verify fallocate punch: Range within the file range"
14869         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14870                 error "dd failed for bs 4096 and count 5"
14871
14872         # Call fallocate with punch range which is within the file range
14873         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
14874                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
14875         # client must see changes immediately after fallocate
14876         size=$(stat -c '%s' $DIR/$tfile)
14877         blocks=$(stat -c '%b' $DIR/$tfile)
14878
14879         # Verify punch worked.
14880         (( blocks == want_blocks_after )) ||
14881                 error "punch failed: blocks $blocks != $want_blocks_after"
14882
14883         (( size == want_size_before )) ||
14884                 error "punch failed: size $size != $want_size_before"
14885
14886         # Verify there is hole in file
14887         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14888         # precomputed md5sum
14889         local expect="4a9a834a2db02452929c0a348273b4aa"
14890
14891         cksum=($(md5sum $DIR/$tfile))
14892         [[ "${cksum[0]}" == "$expect" ]] ||
14893                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14894
14895         # Start second sub-case for fallocate punch.
14896         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14897         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14898                 error "dd failed for bs 4096 and count 5"
14899
14900         # Punch range less than block size will have no change in block count
14901         want_blocks_after=40  # 512 sized blocks
14902
14903         # Punch overlaps two blocks and less than blocksize
14904         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
14905                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
14906         size=$(stat -c '%s' $DIR/$tfile)
14907         blocks=$(stat -c '%b' $DIR/$tfile)
14908
14909         # Verify punch worked.
14910         (( blocks == want_blocks_after )) ||
14911                 error "punch failed: blocks $blocks != $want_blocks_after"
14912
14913         (( size == want_size_before )) ||
14914                 error "punch failed: size $size != $want_size_before"
14915
14916         # Verify if range is really zero'ed out. We expect Zeros.
14917         # precomputed md5sum
14918         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14919         cksum=($(md5sum $DIR/$tfile))
14920         [[ "${cksum[0]}" == "$expect" ]] ||
14921                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14922 }
14923 run_test 150f "Verify fallocate punch functionality"
14924
14925 test_150g() {
14926         local space
14927         local size
14928         local blocks
14929         local blocks_after
14930         local size_after
14931         local BS=4096 # Block size in bytes
14932
14933         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14934                 skip "need at least 2.14.0 for fallocate punch"
14935
14936         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14937                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14938         fi
14939
14940         check_set_fallocate_or_skip
14941         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14942
14943         if [[ "x$DOM" == "xyes" ]]; then
14944                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
14945                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
14946         else
14947                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14948                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14949         fi
14950
14951         # Get 100MB per OST of the available space to reduce run time
14952         # else 60% of the available space if we are running SLOW tests
14953         if [ $SLOW == "no" ]; then
14954                 space=$((1024 * 100 * OSTCOUNT))
14955         else
14956                 # Find OST with Minimum Size
14957                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14958                         sort -un | head -1)
14959                 echo "min size OST: $space"
14960                 space=$(((space * 60)/100 * OSTCOUNT))
14961         fi
14962         # space in 1k units, round to 4k blocks
14963         local blkcount=$((space * 1024 / $BS))
14964
14965         echo "Verify fallocate punch: Very large Range"
14966         fallocate -l${space}k $DIR/$tfile ||
14967                 error "fallocate ${space}k $DIR/$tfile failed"
14968         # write 1M at the end, start and in the middle
14969         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14970                 error "dd failed: bs $BS count 256"
14971         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14972                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14973         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14974                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14975
14976         # Gather stats.
14977         size=$(stat -c '%s' $DIR/$tfile)
14978
14979         # gather punch length.
14980         local punch_size=$((size - (BS * 2)))
14981
14982         echo "punch_size = $punch_size"
14983         echo "size - punch_size: $((size - punch_size))"
14984         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14985
14986         # Call fallocate to punch all except 2 blocks. We leave the
14987         # first and the last block
14988         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14989         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
14990                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
14991
14992         size_after=$(stat -c '%s' $DIR/$tfile)
14993         blocks_after=$(stat -c '%b' $DIR/$tfile)
14994
14995         # Verify punch worked.
14996         # Size should be kept
14997         (( size == size_after )) ||
14998                 error "punch failed: size $size != $size_after"
14999
15000         # two 4k data blocks to remain plus possible 1 extra extent block
15001         (( blocks_after <= ((BS / 512) * 3) )) ||
15002                 error "too many blocks remains: $blocks_after"
15003
15004         # Verify that file has hole between the first and the last blocks
15005         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15006         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15007
15008         echo "Hole at [$hole_start, $hole_end)"
15009         (( hole_start == BS )) ||
15010                 error "no hole at offset $BS after punch"
15011
15012         (( hole_end == BS + punch_size )) ||
15013                 error "data at offset $hole_end < $((BS + punch_size))"
15014 }
15015 run_test 150g "Verify fallocate punch on large range"
15016
15017 #LU-2902 roc_hit was not able to read all values from lproc
15018 function roc_hit_init() {
15019         local list=$(comma_list $(osts_nodes))
15020         local dir=$DIR/$tdir-check
15021         local file=$dir/$tfile
15022         local BEFORE
15023         local AFTER
15024         local idx
15025
15026         test_mkdir $dir
15027         #use setstripe to do a write to every ost
15028         for i in $(seq 0 $((OSTCOUNT-1))); do
15029                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15030                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15031                 idx=$(printf %04x $i)
15032                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15033                         awk '$1 == "cache_access" {sum += $7}
15034                                 END { printf("%0.0f", sum) }')
15035
15036                 cancel_lru_locks osc
15037                 cat $file >/dev/null
15038
15039                 AFTER=$(get_osd_param $list *OST*$idx stats |
15040                         awk '$1 == "cache_access" {sum += $7}
15041                                 END { printf("%0.0f", sum) }')
15042
15043                 echo BEFORE:$BEFORE AFTER:$AFTER
15044                 if ! let "AFTER - BEFORE == 4"; then
15045                         rm -rf $dir
15046                         error "roc_hit is not safe to use"
15047                 fi
15048                 rm $file
15049         done
15050
15051         rm -rf $dir
15052 }
15053
15054 function roc_hit() {
15055         local list=$(comma_list $(osts_nodes))
15056         echo $(get_osd_param $list '' stats |
15057                 awk '$1 == "cache_hit" {sum += $7}
15058                         END { printf("%0.0f", sum) }')
15059 }
15060
15061 function set_cache() {
15062         local on=1
15063
15064         if [ "$2" == "off" ]; then
15065                 on=0;
15066         fi
15067         local list=$(comma_list $(osts_nodes))
15068         set_osd_param $list '' $1_cache_enable $on
15069
15070         cancel_lru_locks osc
15071 }
15072
15073 test_151() {
15074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15075         remote_ost_nodsh && skip "remote OST with nodsh"
15076
15077         local CPAGES=3
15078         local list=$(comma_list $(osts_nodes))
15079
15080         # check whether obdfilter is cache capable at all
15081         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15082                 skip "not cache-capable obdfilter"
15083         fi
15084
15085         # check cache is enabled on all obdfilters
15086         if get_osd_param $list '' read_cache_enable | grep 0; then
15087                 skip "oss cache is disabled"
15088         fi
15089
15090         set_osd_param $list '' writethrough_cache_enable 1
15091
15092         # check write cache is enabled on all obdfilters
15093         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15094                 skip "oss write cache is NOT enabled"
15095         fi
15096
15097         roc_hit_init
15098
15099         #define OBD_FAIL_OBD_NO_LRU  0x609
15100         do_nodes $list $LCTL set_param fail_loc=0x609
15101
15102         # pages should be in the case right after write
15103         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15104                 error "dd failed"
15105
15106         local BEFORE=$(roc_hit)
15107         cancel_lru_locks osc
15108         cat $DIR/$tfile >/dev/null
15109         local AFTER=$(roc_hit)
15110
15111         do_nodes $list $LCTL set_param fail_loc=0
15112
15113         if ! let "AFTER - BEFORE == CPAGES"; then
15114                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15115         fi
15116
15117         cancel_lru_locks osc
15118         # invalidates OST cache
15119         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15120         set_osd_param $list '' read_cache_enable 0
15121         cat $DIR/$tfile >/dev/null
15122
15123         # now data shouldn't be found in the cache
15124         BEFORE=$(roc_hit)
15125         cancel_lru_locks osc
15126         cat $DIR/$tfile >/dev/null
15127         AFTER=$(roc_hit)
15128         if let "AFTER - BEFORE != 0"; then
15129                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15130         fi
15131
15132         set_osd_param $list '' read_cache_enable 1
15133         rm -f $DIR/$tfile
15134 }
15135 run_test 151 "test cache on oss and controls ==============================="
15136
15137 test_152() {
15138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15139
15140         local TF="$TMP/$tfile"
15141
15142         # simulate ENOMEM during write
15143 #define OBD_FAIL_OST_NOMEM      0x226
15144         lctl set_param fail_loc=0x80000226
15145         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15146         cp $TF $DIR/$tfile
15147         sync || error "sync failed"
15148         lctl set_param fail_loc=0
15149
15150         # discard client's cache
15151         cancel_lru_locks osc
15152
15153         # simulate ENOMEM during read
15154         lctl set_param fail_loc=0x80000226
15155         cmp $TF $DIR/$tfile || error "cmp failed"
15156         lctl set_param fail_loc=0
15157
15158         rm -f $TF
15159 }
15160 run_test 152 "test read/write with enomem ============================"
15161
15162 test_153() {
15163         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15164 }
15165 run_test 153 "test if fdatasync does not crash ======================="
15166
15167 dot_lustre_fid_permission_check() {
15168         local fid=$1
15169         local ffid=$MOUNT/.lustre/fid/$fid
15170         local test_dir=$2
15171
15172         echo "stat fid $fid"
15173         stat $ffid > /dev/null || error "stat $ffid failed."
15174         echo "touch fid $fid"
15175         touch $ffid || error "touch $ffid failed."
15176         echo "write to fid $fid"
15177         cat /etc/hosts > $ffid || error "write $ffid failed."
15178         echo "read fid $fid"
15179         diff /etc/hosts $ffid || error "read $ffid failed."
15180         echo "append write to fid $fid"
15181         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15182         echo "rename fid $fid"
15183         mv $ffid $test_dir/$tfile.1 &&
15184                 error "rename $ffid to $tfile.1 should fail."
15185         touch $test_dir/$tfile.1
15186         mv $test_dir/$tfile.1 $ffid &&
15187                 error "rename $tfile.1 to $ffid should fail."
15188         rm -f $test_dir/$tfile.1
15189         echo "truncate fid $fid"
15190         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15191         echo "link fid $fid"
15192         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15193         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15194                 echo "setfacl fid $fid"
15195                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
15196                 echo "getfacl fid $fid"
15197                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
15198         fi
15199         echo "unlink fid $fid"
15200         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15201         echo "mknod fid $fid"
15202         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15203
15204         fid=[0xf00000400:0x1:0x0]
15205         ffid=$MOUNT/.lustre/fid/$fid
15206
15207         echo "stat non-exist fid $fid"
15208         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15209         echo "write to non-exist fid $fid"
15210         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15211         echo "link new fid $fid"
15212         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15213
15214         mkdir -p $test_dir/$tdir
15215         touch $test_dir/$tdir/$tfile
15216         fid=$($LFS path2fid $test_dir/$tdir)
15217         rc=$?
15218         [ $rc -ne 0 ] &&
15219                 error "error: could not get fid for $test_dir/$dir/$tfile."
15220
15221         ffid=$MOUNT/.lustre/fid/$fid
15222
15223         echo "ls $fid"
15224         ls $ffid > /dev/null || error "ls $ffid failed."
15225         echo "touch $fid/$tfile.1"
15226         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15227
15228         echo "touch $MOUNT/.lustre/fid/$tfile"
15229         touch $MOUNT/.lustre/fid/$tfile && \
15230                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15231
15232         echo "setxattr to $MOUNT/.lustre/fid"
15233         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15234
15235         echo "listxattr for $MOUNT/.lustre/fid"
15236         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15237
15238         echo "delxattr from $MOUNT/.lustre/fid"
15239         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15240
15241         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15242         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15243                 error "touch invalid fid should fail."
15244
15245         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15246         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15247                 error "touch non-normal fid should fail."
15248
15249         echo "rename $tdir to $MOUNT/.lustre/fid"
15250         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15251                 error "rename to $MOUNT/.lustre/fid should fail."
15252
15253         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15254         then            # LU-3547
15255                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15256                 local new_obf_mode=777
15257
15258                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15259                 chmod $new_obf_mode $DIR/.lustre/fid ||
15260                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15261
15262                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15263                 [ $obf_mode -eq $new_obf_mode ] ||
15264                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15265
15266                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15267                 chmod $old_obf_mode $DIR/.lustre/fid ||
15268                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15269         fi
15270
15271         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15272         fid=$($LFS path2fid $test_dir/$tfile-2)
15273
15274         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15275         then # LU-5424
15276                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15277                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15278                         error "create lov data thru .lustre failed"
15279         fi
15280         echo "cp /etc/passwd $test_dir/$tfile-2"
15281         cp /etc/passwd $test_dir/$tfile-2 ||
15282                 error "copy to $test_dir/$tfile-2 failed."
15283         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15284         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15285                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15286
15287         rm -rf $test_dir/tfile.lnk
15288         rm -rf $test_dir/$tfile-2
15289 }
15290
15291 test_154A() {
15292         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15293                 skip "Need MDS version at least 2.4.1"
15294
15295         local tf=$DIR/$tfile
15296         touch $tf
15297
15298         local fid=$($LFS path2fid $tf)
15299         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15300
15301         # check that we get the same pathname back
15302         local rootpath
15303         local found
15304         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15305                 echo "$rootpath $fid"
15306                 found=$($LFS fid2path $rootpath "$fid")
15307                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15308                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15309         done
15310
15311         # check wrong root path format
15312         rootpath=$MOUNT"_wrong"
15313         found=$($LFS fid2path $rootpath "$fid")
15314         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15315 }
15316 run_test 154A "lfs path2fid and fid2path basic checks"
15317
15318 test_154B() {
15319         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15320                 skip "Need MDS version at least 2.4.1"
15321
15322         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15323         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15324         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15325         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15326
15327         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15328         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15329
15330         # check that we get the same pathname
15331         echo "PFID: $PFID, name: $name"
15332         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15333         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15334         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15335                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15336
15337         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15338 }
15339 run_test 154B "verify the ll_decode_linkea tool"
15340
15341 test_154a() {
15342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15343         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15344         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15345                 skip "Need MDS version at least 2.2.51"
15346         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15347
15348         cp /etc/hosts $DIR/$tfile
15349
15350         fid=$($LFS path2fid $DIR/$tfile)
15351         rc=$?
15352         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15353
15354         dot_lustre_fid_permission_check "$fid" $DIR ||
15355                 error "dot lustre permission check $fid failed"
15356
15357         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15358
15359         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15360
15361         touch $MOUNT/.lustre/file &&
15362                 error "creation is not allowed under .lustre"
15363
15364         mkdir $MOUNT/.lustre/dir &&
15365                 error "mkdir is not allowed under .lustre"
15366
15367         rm -rf $DIR/$tfile
15368 }
15369 run_test 154a "Open-by-FID"
15370
15371 test_154b() {
15372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15373         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15374         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15375         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15376                 skip "Need MDS version at least 2.2.51"
15377
15378         local remote_dir=$DIR/$tdir/remote_dir
15379         local MDTIDX=1
15380         local rc=0
15381
15382         mkdir -p $DIR/$tdir
15383         $LFS mkdir -i $MDTIDX $remote_dir ||
15384                 error "create remote directory failed"
15385
15386         cp /etc/hosts $remote_dir/$tfile
15387
15388         fid=$($LFS path2fid $remote_dir/$tfile)
15389         rc=$?
15390         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15391
15392         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15393                 error "dot lustre permission check $fid failed"
15394         rm -rf $DIR/$tdir
15395 }
15396 run_test 154b "Open-by-FID for remote directory"
15397
15398 test_154c() {
15399         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15400                 skip "Need MDS version at least 2.4.1"
15401
15402         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15403         local FID1=$($LFS path2fid $DIR/$tfile.1)
15404         local FID2=$($LFS path2fid $DIR/$tfile.2)
15405         local FID3=$($LFS path2fid $DIR/$tfile.3)
15406
15407         local N=1
15408         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15409                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15410                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15411                 local want=FID$N
15412                 [ "$FID" = "${!want}" ] ||
15413                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15414                 N=$((N + 1))
15415         done
15416
15417         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15418         do
15419                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15420                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15421                 N=$((N + 1))
15422         done
15423 }
15424 run_test 154c "lfs path2fid and fid2path multiple arguments"
15425
15426 test_154d() {
15427         remote_mds_nodsh && skip "remote MDS with nodsh"
15428         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15429                 skip "Need MDS version at least 2.5.53"
15430
15431         if remote_mds; then
15432                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15433         else
15434                 nid="0@lo"
15435         fi
15436         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15437         local fd
15438         local cmd
15439
15440         rm -f $DIR/$tfile
15441         touch $DIR/$tfile
15442
15443         local fid=$($LFS path2fid $DIR/$tfile)
15444         # Open the file
15445         fd=$(free_fd)
15446         cmd="exec $fd<$DIR/$tfile"
15447         eval $cmd
15448         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15449         echo "$fid_list" | grep "$fid"
15450         rc=$?
15451
15452         cmd="exec $fd>/dev/null"
15453         eval $cmd
15454         if [ $rc -ne 0 ]; then
15455                 error "FID $fid not found in open files list $fid_list"
15456         fi
15457 }
15458 run_test 154d "Verify open file fid"
15459
15460 test_154e()
15461 {
15462         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15463                 skip "Need MDS version at least 2.6.50"
15464
15465         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15466                 error ".lustre returned by readdir"
15467         fi
15468 }
15469 run_test 154e ".lustre is not returned by readdir"
15470
15471 test_154f() {
15472         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15473
15474         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15475         mkdir_on_mdt0 $DIR/$tdir
15476         # test dirs inherit from its stripe
15477         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15478         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15479         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15480         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15481         touch $DIR/f
15482
15483         # get fid of parents
15484         local FID0=$($LFS path2fid $DIR/$tdir)
15485         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15486         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15487         local FID3=$($LFS path2fid $DIR)
15488
15489         # check that path2fid --parents returns expected <parent_fid>/name
15490         # 1) test for a directory (single parent)
15491         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15492         [ "$parent" == "$FID0/foo1" ] ||
15493                 error "expected parent: $FID0/foo1, got: $parent"
15494
15495         # 2) test for a file with nlink > 1 (multiple parents)
15496         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15497         echo "$parent" | grep -F "$FID1/$tfile" ||
15498                 error "$FID1/$tfile not returned in parent list"
15499         echo "$parent" | grep -F "$FID2/link" ||
15500                 error "$FID2/link not returned in parent list"
15501
15502         # 3) get parent by fid
15503         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15504         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15505         echo "$parent" | grep -F "$FID1/$tfile" ||
15506                 error "$FID1/$tfile not returned in parent list (by fid)"
15507         echo "$parent" | grep -F "$FID2/link" ||
15508                 error "$FID2/link not returned in parent list (by fid)"
15509
15510         # 4) test for entry in root directory
15511         parent=$($LFS path2fid --parents $DIR/f)
15512         echo "$parent" | grep -F "$FID3/f" ||
15513                 error "$FID3/f not returned in parent list"
15514
15515         # 5) test it on root directory
15516         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15517                 error "$MOUNT should not have parents"
15518
15519         # enable xattr caching and check that linkea is correctly updated
15520         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15521         save_lustre_params client "llite.*.xattr_cache" > $save
15522         lctl set_param llite.*.xattr_cache 1
15523
15524         # 6.1) linkea update on rename
15525         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15526
15527         # get parents by fid
15528         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15529         # foo1 should no longer be returned in parent list
15530         echo "$parent" | grep -F "$FID1" &&
15531                 error "$FID1 should no longer be in parent list"
15532         # the new path should appear
15533         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15534                 error "$FID2/$tfile.moved is not in parent list"
15535
15536         # 6.2) linkea update on unlink
15537         rm -f $DIR/$tdir/foo2/link
15538         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15539         # foo2/link should no longer be returned in parent list
15540         echo "$parent" | grep -F "$FID2/link" &&
15541                 error "$FID2/link should no longer be in parent list"
15542         true
15543
15544         rm -f $DIR/f
15545         restore_lustre_params < $save
15546         rm -f $save
15547 }
15548 run_test 154f "get parent fids by reading link ea"
15549
15550 test_154g()
15551 {
15552         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15553         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15554            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15555                 skip "Need MDS version at least 2.6.92"
15556
15557         mkdir_on_mdt0 $DIR/$tdir
15558         llapi_fid_test -d $DIR/$tdir
15559 }
15560 run_test 154g "various llapi FID tests"
15561
15562 test_155_small_load() {
15563     local temp=$TMP/$tfile
15564     local file=$DIR/$tfile
15565
15566     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15567         error "dd of=$temp bs=6096 count=1 failed"
15568     cp $temp $file
15569     cancel_lru_locks $OSC
15570     cmp $temp $file || error "$temp $file differ"
15571
15572     $TRUNCATE $temp 6000
15573     $TRUNCATE $file 6000
15574     cmp $temp $file || error "$temp $file differ (truncate1)"
15575
15576     echo "12345" >>$temp
15577     echo "12345" >>$file
15578     cmp $temp $file || error "$temp $file differ (append1)"
15579
15580     echo "12345" >>$temp
15581     echo "12345" >>$file
15582     cmp $temp $file || error "$temp $file differ (append2)"
15583
15584     rm -f $temp $file
15585     true
15586 }
15587
15588 test_155_big_load() {
15589         remote_ost_nodsh && skip "remote OST with nodsh"
15590
15591         local temp=$TMP/$tfile
15592         local file=$DIR/$tfile
15593
15594         free_min_max
15595         local cache_size=$(do_facet ost$((MAXI+1)) \
15596                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15597         local large_file_size=$((cache_size * 2))
15598
15599         echo "OSS cache size: $cache_size KB"
15600         echo "Large file size: $large_file_size KB"
15601
15602         [ $MAXV -le $large_file_size ] &&
15603                 skip_env "max available OST size needs > $large_file_size KB"
15604
15605         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15606
15607         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15608                 error "dd of=$temp bs=$large_file_size count=1k failed"
15609         cp $temp $file
15610         ls -lh $temp $file
15611         cancel_lru_locks osc
15612         cmp $temp $file || error "$temp $file differ"
15613
15614         rm -f $temp $file
15615         true
15616 }
15617
15618 save_writethrough() {
15619         local facets=$(get_facets OST)
15620
15621         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15622 }
15623
15624 test_155a() {
15625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15626
15627         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15628
15629         save_writethrough $p
15630
15631         set_cache read on
15632         set_cache writethrough on
15633         test_155_small_load
15634         restore_lustre_params < $p
15635         rm -f $p
15636 }
15637 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15638
15639 test_155b() {
15640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15641
15642         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15643
15644         save_writethrough $p
15645
15646         set_cache read on
15647         set_cache writethrough off
15648         test_155_small_load
15649         restore_lustre_params < $p
15650         rm -f $p
15651 }
15652 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15653
15654 test_155c() {
15655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15656
15657         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15658
15659         save_writethrough $p
15660
15661         set_cache read off
15662         set_cache writethrough on
15663         test_155_small_load
15664         restore_lustre_params < $p
15665         rm -f $p
15666 }
15667 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15668
15669 test_155d() {
15670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15671
15672         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15673
15674         save_writethrough $p
15675
15676         set_cache read off
15677         set_cache writethrough off
15678         test_155_small_load
15679         restore_lustre_params < $p
15680         rm -f $p
15681 }
15682 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15683
15684 test_155e() {
15685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15686
15687         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15688
15689         save_writethrough $p
15690
15691         set_cache read on
15692         set_cache writethrough on
15693         test_155_big_load
15694         restore_lustre_params < $p
15695         rm -f $p
15696 }
15697 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15698
15699 test_155f() {
15700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15701
15702         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15703
15704         save_writethrough $p
15705
15706         set_cache read on
15707         set_cache writethrough off
15708         test_155_big_load
15709         restore_lustre_params < $p
15710         rm -f $p
15711 }
15712 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15713
15714 test_155g() {
15715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15716
15717         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15718
15719         save_writethrough $p
15720
15721         set_cache read off
15722         set_cache writethrough on
15723         test_155_big_load
15724         restore_lustre_params < $p
15725         rm -f $p
15726 }
15727 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15728
15729 test_155h() {
15730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15731
15732         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15733
15734         save_writethrough $p
15735
15736         set_cache read off
15737         set_cache writethrough off
15738         test_155_big_load
15739         restore_lustre_params < $p
15740         rm -f $p
15741 }
15742 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15743
15744 test_156() {
15745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15746         remote_ost_nodsh && skip "remote OST with nodsh"
15747         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15748                 skip "stats not implemented on old servers"
15749         [ "$ost1_FSTYPE" = "zfs" ] &&
15750                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15751
15752         local CPAGES=3
15753         local BEFORE
15754         local AFTER
15755         local file="$DIR/$tfile"
15756         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15757
15758         save_writethrough $p
15759         roc_hit_init
15760
15761         log "Turn on read and write cache"
15762         set_cache read on
15763         set_cache writethrough on
15764
15765         log "Write data and read it back."
15766         log "Read should be satisfied from the cache."
15767         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15768         BEFORE=$(roc_hit)
15769         cancel_lru_locks osc
15770         cat $file >/dev/null
15771         AFTER=$(roc_hit)
15772         if ! let "AFTER - BEFORE == CPAGES"; then
15773                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15774         else
15775                 log "cache hits: before: $BEFORE, after: $AFTER"
15776         fi
15777
15778         log "Read again; it should be satisfied from the cache."
15779         BEFORE=$AFTER
15780         cancel_lru_locks osc
15781         cat $file >/dev/null
15782         AFTER=$(roc_hit)
15783         if ! let "AFTER - BEFORE == CPAGES"; then
15784                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15785         else
15786                 log "cache hits:: before: $BEFORE, after: $AFTER"
15787         fi
15788
15789         log "Turn off the read cache and turn on the write cache"
15790         set_cache read off
15791         set_cache writethrough on
15792
15793         log "Read again; it should be satisfied from the cache."
15794         BEFORE=$(roc_hit)
15795         cancel_lru_locks osc
15796         cat $file >/dev/null
15797         AFTER=$(roc_hit)
15798         if ! let "AFTER - BEFORE == CPAGES"; then
15799                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15800         else
15801                 log "cache hits:: before: $BEFORE, after: $AFTER"
15802         fi
15803
15804         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15805                 # > 2.12.56 uses pagecache if cached
15806                 log "Read again; it should not be satisfied from the cache."
15807                 BEFORE=$AFTER
15808                 cancel_lru_locks osc
15809                 cat $file >/dev/null
15810                 AFTER=$(roc_hit)
15811                 if ! let "AFTER - BEFORE == 0"; then
15812                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15813                 else
15814                         log "cache hits:: before: $BEFORE, after: $AFTER"
15815                 fi
15816         fi
15817
15818         log "Write data and read it back."
15819         log "Read should be satisfied from the cache."
15820         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15821         BEFORE=$(roc_hit)
15822         cancel_lru_locks osc
15823         cat $file >/dev/null
15824         AFTER=$(roc_hit)
15825         if ! let "AFTER - BEFORE == CPAGES"; then
15826                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15827         else
15828                 log "cache hits:: before: $BEFORE, after: $AFTER"
15829         fi
15830
15831         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15832                 # > 2.12.56 uses pagecache if cached
15833                 log "Read again; it should not be satisfied from the cache."
15834                 BEFORE=$AFTER
15835                 cancel_lru_locks osc
15836                 cat $file >/dev/null
15837                 AFTER=$(roc_hit)
15838                 if ! let "AFTER - BEFORE == 0"; then
15839                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15840                 else
15841                         log "cache hits:: before: $BEFORE, after: $AFTER"
15842                 fi
15843         fi
15844
15845         log "Turn off read and write cache"
15846         set_cache read off
15847         set_cache writethrough off
15848
15849         log "Write data and read it back"
15850         log "It should not be satisfied from the cache."
15851         rm -f $file
15852         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15853         cancel_lru_locks osc
15854         BEFORE=$(roc_hit)
15855         cat $file >/dev/null
15856         AFTER=$(roc_hit)
15857         if ! let "AFTER - BEFORE == 0"; then
15858                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15859         else
15860                 log "cache hits:: before: $BEFORE, after: $AFTER"
15861         fi
15862
15863         log "Turn on the read cache and turn off the write cache"
15864         set_cache read on
15865         set_cache writethrough off
15866
15867         log "Write data and read it back"
15868         log "It should not be satisfied from the cache."
15869         rm -f $file
15870         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15871         BEFORE=$(roc_hit)
15872         cancel_lru_locks osc
15873         cat $file >/dev/null
15874         AFTER=$(roc_hit)
15875         if ! let "AFTER - BEFORE == 0"; then
15876                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15877         else
15878                 log "cache hits:: before: $BEFORE, after: $AFTER"
15879         fi
15880
15881         log "Read again; it should be satisfied from the cache."
15882         BEFORE=$(roc_hit)
15883         cancel_lru_locks osc
15884         cat $file >/dev/null
15885         AFTER=$(roc_hit)
15886         if ! let "AFTER - BEFORE == CPAGES"; then
15887                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15888         else
15889                 log "cache hits:: before: $BEFORE, after: $AFTER"
15890         fi
15891
15892         restore_lustre_params < $p
15893         rm -f $p $file
15894 }
15895 run_test 156 "Verification of tunables"
15896
15897 test_160a() {
15898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15899         remote_mds_nodsh && skip "remote MDS with nodsh"
15900         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15901                 skip "Need MDS version at least 2.2.0"
15902
15903         changelog_register || error "changelog_register failed"
15904         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15905         changelog_users $SINGLEMDS | grep -q $cl_user ||
15906                 error "User $cl_user not found in changelog_users"
15907
15908         mkdir_on_mdt0 $DIR/$tdir
15909
15910         # change something
15911         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15912         changelog_clear 0 || error "changelog_clear failed"
15913         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15914         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15915         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15916         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15917         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15918         rm $DIR/$tdir/pics/desktop.jpg
15919
15920         echo "verifying changelog mask"
15921         changelog_chmask "-MKDIR"
15922         changelog_chmask "-CLOSE"
15923
15924         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15925         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15926
15927         changelog_chmask "+MKDIR"
15928         changelog_chmask "+CLOSE"
15929
15930         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15931         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15932
15933         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15934         CLOSES=$(changelog_dump | grep -c "CLOSE")
15935         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15936         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15937
15938         # verify contents
15939         echo "verifying target fid"
15940         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15941         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15942         [ "$fidc" == "$fidf" ] ||
15943                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15944         echo "verifying parent fid"
15945         # The FID returned from the Changelog may be the directory shard on
15946         # a different MDT, and not the FID returned by path2fid on the parent.
15947         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15948         # since this is what will matter when recreating this file in the tree.
15949         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15950         local pathp=$($LFS fid2path $MOUNT "$fidp")
15951         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15952                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15953
15954         echo "getting records for $cl_user"
15955         changelog_users $SINGLEMDS
15956         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15957         local nclr=3
15958         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15959                 error "changelog_clear failed"
15960         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15961         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15962         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15963                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15964
15965         local min0_rec=$(changelog_users $SINGLEMDS |
15966                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15967         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15968                           awk '{ print $1; exit; }')
15969
15970         changelog_dump | tail -n 5
15971         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15972         [ $first_rec == $((min0_rec + 1)) ] ||
15973                 error "first index should be $min0_rec + 1 not $first_rec"
15974
15975         # LU-3446 changelog index reset on MDT restart
15976         local cur_rec1=$(changelog_users $SINGLEMDS |
15977                          awk '/^current.index:/ { print $NF }')
15978         changelog_clear 0 ||
15979                 error "clear all changelog records for $cl_user failed"
15980         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15981         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15982                 error "Fail to start $SINGLEMDS"
15983         local cur_rec2=$(changelog_users $SINGLEMDS |
15984                          awk '/^current.index:/ { print $NF }')
15985         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15986         [ $cur_rec1 == $cur_rec2 ] ||
15987                 error "current index should be $cur_rec1 not $cur_rec2"
15988
15989         echo "verifying users from this test are deregistered"
15990         changelog_deregister || error "changelog_deregister failed"
15991         changelog_users $SINGLEMDS | grep -q $cl_user &&
15992                 error "User '$cl_user' still in changelog_users"
15993
15994         # lctl get_param -n mdd.*.changelog_users
15995         # current_index: 144
15996         # ID    index (idle seconds)
15997         # cl3   144   (2) mask=<list>
15998         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15999                 # this is the normal case where all users were deregistered
16000                 # make sure no new records are added when no users are present
16001                 local last_rec1=$(changelog_users $SINGLEMDS |
16002                                   awk '/^current.index:/ { print $NF }')
16003                 touch $DIR/$tdir/chloe
16004                 local last_rec2=$(changelog_users $SINGLEMDS |
16005                                   awk '/^current.index:/ { print $NF }')
16006                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16007                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16008         else
16009                 # any changelog users must be leftovers from a previous test
16010                 changelog_users $SINGLEMDS
16011                 echo "other changelog users; can't verify off"
16012         fi
16013 }
16014 run_test 160a "changelog sanity"
16015
16016 test_160b() { # LU-3587
16017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16018         remote_mds_nodsh && skip "remote MDS with nodsh"
16019         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16020                 skip "Need MDS version at least 2.2.0"
16021
16022         changelog_register || error "changelog_register failed"
16023         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16024         changelog_users $SINGLEMDS | grep -q $cl_user ||
16025                 error "User '$cl_user' not found in changelog_users"
16026
16027         local longname1=$(str_repeat a 255)
16028         local longname2=$(str_repeat b 255)
16029
16030         cd $DIR
16031         echo "creating very long named file"
16032         touch $longname1 || error "create of '$longname1' failed"
16033         echo "renaming very long named file"
16034         mv $longname1 $longname2
16035
16036         changelog_dump | grep RENME | tail -n 5
16037         rm -f $longname2
16038 }
16039 run_test 160b "Verify that very long rename doesn't crash in changelog"
16040
16041 test_160c() {
16042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16043         remote_mds_nodsh && skip "remote MDS with nodsh"
16044
16045         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16046                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16047                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16048                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16049
16050         local rc=0
16051
16052         # Registration step
16053         changelog_register || error "changelog_register failed"
16054
16055         rm -rf $DIR/$tdir
16056         mkdir -p $DIR/$tdir
16057         $MCREATE $DIR/$tdir/foo_160c
16058         changelog_chmask "-TRUNC"
16059         $TRUNCATE $DIR/$tdir/foo_160c 200
16060         changelog_chmask "+TRUNC"
16061         $TRUNCATE $DIR/$tdir/foo_160c 199
16062         changelog_dump | tail -n 5
16063         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16064         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16065 }
16066 run_test 160c "verify that changelog log catch the truncate event"
16067
16068 test_160d() {
16069         remote_mds_nodsh && skip "remote MDS with nodsh"
16070         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16072         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16073                 skip "Need MDS version at least 2.7.60"
16074
16075         # Registration step
16076         changelog_register || error "changelog_register failed"
16077
16078         mkdir -p $DIR/$tdir/migrate_dir
16079         changelog_clear 0 || error "changelog_clear failed"
16080
16081         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16082         changelog_dump | tail -n 5
16083         local migrates=$(changelog_dump | grep -c "MIGRT")
16084         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16085 }
16086 run_test 160d "verify that changelog log catch the migrate event"
16087
16088 test_160e() {
16089         remote_mds_nodsh && skip "remote MDS with nodsh"
16090
16091         # Create a user
16092         changelog_register || error "changelog_register failed"
16093
16094         local MDT0=$(facet_svc $SINGLEMDS)
16095         local rc
16096
16097         # No user (expect fail)
16098         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16099         rc=$?
16100         if [ $rc -eq 0 ]; then
16101                 error "Should fail without user"
16102         elif [ $rc -ne 4 ]; then
16103                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16104         fi
16105
16106         # Delete a future user (expect fail)
16107         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16108         rc=$?
16109         if [ $rc -eq 0 ]; then
16110                 error "Deleted non-existant user cl77"
16111         elif [ $rc -ne 2 ]; then
16112                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16113         fi
16114
16115         # Clear to a bad index (1 billion should be safe)
16116         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16117         rc=$?
16118
16119         if [ $rc -eq 0 ]; then
16120                 error "Successfully cleared to invalid CL index"
16121         elif [ $rc -ne 22 ]; then
16122                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16123         fi
16124 }
16125 run_test 160e "changelog negative testing (should return errors)"
16126
16127 test_160f() {
16128         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16129         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16130                 skip "Need MDS version at least 2.10.56"
16131
16132         local mdts=$(comma_list $(mdts_nodes))
16133
16134         # Create a user
16135         changelog_register || error "first changelog_register failed"
16136         changelog_register || error "second changelog_register failed"
16137         local cl_users
16138         declare -A cl_user1
16139         declare -A cl_user2
16140         local user_rec1
16141         local user_rec2
16142         local i
16143
16144         # generate some changelog records to accumulate on each MDT
16145         # use all_char because created files should be evenly distributed
16146         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16147                 error "test_mkdir $tdir failed"
16148         log "$(date +%s): creating first files"
16149         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16150                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16151                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16152         done
16153
16154         # check changelogs have been generated
16155         local start=$SECONDS
16156         local idle_time=$((MDSCOUNT * 5 + 5))
16157         local nbcl=$(changelog_dump | wc -l)
16158         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16159
16160         for param in "changelog_max_idle_time=$idle_time" \
16161                      "changelog_gc=1" \
16162                      "changelog_min_gc_interval=2" \
16163                      "changelog_min_free_cat_entries=3"; do
16164                 local MDT0=$(facet_svc $SINGLEMDS)
16165                 local var="${param%=*}"
16166                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16167
16168                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16169                 do_nodes $mdts $LCTL set_param mdd.*.$param
16170         done
16171
16172         # force cl_user2 to be idle (1st part), but also cancel the
16173         # cl_user1 records so that it is not evicted later in the test.
16174         local sleep1=$((idle_time / 2))
16175         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16176         sleep $sleep1
16177
16178         # simulate changelog catalog almost full
16179         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16180         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16181
16182         for i in $(seq $MDSCOUNT); do
16183                 cl_users=(${CL_USERS[mds$i]})
16184                 cl_user1[mds$i]="${cl_users[0]}"
16185                 cl_user2[mds$i]="${cl_users[1]}"
16186
16187                 [ -n "${cl_user1[mds$i]}" ] ||
16188                         error "mds$i: no user registered"
16189                 [ -n "${cl_user2[mds$i]}" ] ||
16190                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16191
16192                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16193                 [ -n "$user_rec1" ] ||
16194                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16195                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16196                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16197                 [ -n "$user_rec2" ] ||
16198                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16199                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16200                      "$user_rec1 + 2 == $user_rec2"
16201                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16202                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16203                               "$user_rec1 + 2, but is $user_rec2"
16204                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16205                 [ -n "$user_rec2" ] ||
16206                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16207                 [ $user_rec1 == $user_rec2 ] ||
16208                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16209                               "$user_rec1, but is $user_rec2"
16210         done
16211
16212         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16213         local sleep2=$((idle_time - (SECONDS - start) + 1))
16214         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16215         sleep $sleep2
16216
16217         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16218         # cl_user1 should be OK because it recently processed records.
16219         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16220         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16221                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16222                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16223         done
16224
16225         # ensure gc thread is done
16226         for i in $(mdts_nodes); do
16227                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16228                         error "$i: GC-thread not done"
16229         done
16230
16231         local first_rec
16232         for (( i = 1; i <= MDSCOUNT; i++ )); do
16233                 # check cl_user1 still registered
16234                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16235                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16236                 # check cl_user2 unregistered
16237                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16238                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16239
16240                 # check changelogs are present and starting at $user_rec1 + 1
16241                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16242                 [ -n "$user_rec1" ] ||
16243                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16244                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16245                             awk '{ print $1; exit; }')
16246
16247                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16248                 [ $((user_rec1 + 1)) == $first_rec ] ||
16249                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16250         done
16251 }
16252 run_test 160f "changelog garbage collect (timestamped users)"
16253
16254 test_160g() {
16255         remote_mds_nodsh && skip "remote MDS with nodsh"
16256         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16257                 skip "Need MDS version at least 2.14.55"
16258
16259         local mdts=$(comma_list $(mdts_nodes))
16260
16261         # Create a user
16262         changelog_register || error "first changelog_register failed"
16263         changelog_register || error "second changelog_register failed"
16264         local cl_users
16265         declare -A cl_user1
16266         declare -A cl_user2
16267         local user_rec1
16268         local user_rec2
16269         local i
16270
16271         # generate some changelog records to accumulate on each MDT
16272         # use all_char because created files should be evenly distributed
16273         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16274                 error "test_mkdir $tdir failed"
16275         for ((i = 0; i < MDSCOUNT; i++)); do
16276                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16277                         error "create $DIR/$tdir/d$i.1 failed"
16278         done
16279
16280         # check changelogs have been generated
16281         local nbcl=$(changelog_dump | wc -l)
16282         (( $nbcl > 0 )) || error "no changelogs found"
16283
16284         # reduce the max_idle_indexes value to make sure we exceed it
16285         for param in "changelog_max_idle_indexes=2" \
16286                      "changelog_gc=1" \
16287                      "changelog_min_gc_interval=2"; do
16288                 local MDT0=$(facet_svc $SINGLEMDS)
16289                 local var="${param%=*}"
16290                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16291
16292                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16293                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16294                         error "unable to set mdd.*.$param"
16295         done
16296
16297         local start=$SECONDS
16298         for i in $(seq $MDSCOUNT); do
16299                 cl_users=(${CL_USERS[mds$i]})
16300                 cl_user1[mds$i]="${cl_users[0]}"
16301                 cl_user2[mds$i]="${cl_users[1]}"
16302
16303                 [ -n "${cl_user1[mds$i]}" ] ||
16304                         error "mds$i: user1 is not registered"
16305                 [ -n "${cl_user2[mds$i]}" ] ||
16306                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16307
16308                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16309                 [ -n "$user_rec1" ] ||
16310                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16311                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16312                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16313                 [ -n "$user_rec2" ] ||
16314                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16315                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16316                      "$user_rec1 + 2 == $user_rec2"
16317                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16318                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16319                               "expected $user_rec1 + 2, but is $user_rec2"
16320                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16321                 [ -n "$user_rec2" ] ||
16322                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16323                 [ $user_rec1 == $user_rec2 ] ||
16324                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16325                               "expected $user_rec1, but is $user_rec2"
16326         done
16327
16328         # ensure we are past the previous changelog_min_gc_interval set above
16329         local sleep2=$((start + 2 - SECONDS))
16330         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16331         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16332         # cl_user1 should be OK because it recently processed records.
16333         for ((i = 0; i < MDSCOUNT; i++)); do
16334                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16335                         error "create $DIR/$tdir/d$i.3 failed"
16336         done
16337
16338         # ensure gc thread is done
16339         for i in $(mdts_nodes); do
16340                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16341                         error "$i: GC-thread not done"
16342         done
16343
16344         local first_rec
16345         for (( i = 1; i <= MDSCOUNT; i++ )); do
16346                 # check cl_user1 still registered
16347                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16348                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16349                 # check cl_user2 unregistered
16350                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16351                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16352
16353                 # check changelogs are present and starting at $user_rec1 + 1
16354                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16355                 [ -n "$user_rec1" ] ||
16356                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16357                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16358                             awk '{ print $1; exit; }')
16359
16360                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16361                 [ $((user_rec1 + 1)) == $first_rec ] ||
16362                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16363         done
16364 }
16365 run_test 160g "changelog garbage collect on idle records"
16366
16367 test_160h() {
16368         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16369         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16370                 skip "Need MDS version at least 2.10.56"
16371
16372         local mdts=$(comma_list $(mdts_nodes))
16373
16374         # Create a user
16375         changelog_register || error "first changelog_register failed"
16376         changelog_register || error "second changelog_register failed"
16377         local cl_users
16378         declare -A cl_user1
16379         declare -A cl_user2
16380         local user_rec1
16381         local user_rec2
16382         local i
16383
16384         # generate some changelog records to accumulate on each MDT
16385         # use all_char because created files should be evenly distributed
16386         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16387                 error "test_mkdir $tdir failed"
16388         for ((i = 0; i < MDSCOUNT; i++)); do
16389                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16390                         error "create $DIR/$tdir/d$i.1 failed"
16391         done
16392
16393         # check changelogs have been generated
16394         local nbcl=$(changelog_dump | wc -l)
16395         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16396
16397         for param in "changelog_max_idle_time=10" \
16398                      "changelog_gc=1" \
16399                      "changelog_min_gc_interval=2"; do
16400                 local MDT0=$(facet_svc $SINGLEMDS)
16401                 local var="${param%=*}"
16402                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16403
16404                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16405                 do_nodes $mdts $LCTL set_param mdd.*.$param
16406         done
16407
16408         # force cl_user2 to be idle (1st part)
16409         sleep 9
16410
16411         for i in $(seq $MDSCOUNT); do
16412                 cl_users=(${CL_USERS[mds$i]})
16413                 cl_user1[mds$i]="${cl_users[0]}"
16414                 cl_user2[mds$i]="${cl_users[1]}"
16415
16416                 [ -n "${cl_user1[mds$i]}" ] ||
16417                         error "mds$i: no user registered"
16418                 [ -n "${cl_user2[mds$i]}" ] ||
16419                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16420
16421                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16422                 [ -n "$user_rec1" ] ||
16423                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16424                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16425                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16426                 [ -n "$user_rec2" ] ||
16427                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16428                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16429                      "$user_rec1 + 2 == $user_rec2"
16430                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16431                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16432                               "$user_rec1 + 2, but is $user_rec2"
16433                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16434                 [ -n "$user_rec2" ] ||
16435                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16436                 [ $user_rec1 == $user_rec2 ] ||
16437                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16438                               "$user_rec1, but is $user_rec2"
16439         done
16440
16441         # force cl_user2 to be idle (2nd part) and to reach
16442         # changelog_max_idle_time
16443         sleep 2
16444
16445         # force each GC-thread start and block then
16446         # one per MDT/MDD, set fail_val accordingly
16447         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16448         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16449
16450         # generate more changelogs to trigger fail_loc
16451         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16452                 error "create $DIR/$tdir/${tfile}bis failed"
16453
16454         # stop MDT to stop GC-thread, should be done in back-ground as it will
16455         # block waiting for the thread to be released and exit
16456         declare -A stop_pids
16457         for i in $(seq $MDSCOUNT); do
16458                 stop mds$i &
16459                 stop_pids[mds$i]=$!
16460         done
16461
16462         for i in $(mdts_nodes); do
16463                 local facet
16464                 local nb=0
16465                 local facets=$(facets_up_on_host $i)
16466
16467                 for facet in ${facets//,/ }; do
16468                         if [[ $facet == mds* ]]; then
16469                                 nb=$((nb + 1))
16470                         fi
16471                 done
16472                 # ensure each MDS's gc threads are still present and all in "R"
16473                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16474                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16475                         error "$i: expected $nb GC-thread"
16476                 wait_update $i \
16477                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16478                         "R" 20 ||
16479                         error "$i: GC-thread not found in R-state"
16480                 # check umounts of each MDT on MDS have reached kthread_stop()
16481                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16482                         error "$i: expected $nb umount"
16483                 wait_update $i \
16484                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16485                         error "$i: umount not found in D-state"
16486         done
16487
16488         # release all GC-threads
16489         do_nodes $mdts $LCTL set_param fail_loc=0
16490
16491         # wait for MDT stop to complete
16492         for i in $(seq $MDSCOUNT); do
16493                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16494         done
16495
16496         # XXX
16497         # may try to check if any orphan changelog records are present
16498         # via ldiskfs/zfs and llog_reader...
16499
16500         # re-start/mount MDTs
16501         for i in $(seq $MDSCOUNT); do
16502                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16503                         error "Fail to start mds$i"
16504         done
16505
16506         local first_rec
16507         for i in $(seq $MDSCOUNT); do
16508                 # check cl_user1 still registered
16509                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16510                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16511                 # check cl_user2 unregistered
16512                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16513                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16514
16515                 # check changelogs are present and starting at $user_rec1 + 1
16516                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16517                 [ -n "$user_rec1" ] ||
16518                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16519                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16520                             awk '{ print $1; exit; }')
16521
16522                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16523                 [ $((user_rec1 + 1)) == $first_rec ] ||
16524                         error "mds$i: first index should be $user_rec1 + 1, " \
16525                               "but is $first_rec"
16526         done
16527 }
16528 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16529               "during mount"
16530
16531 test_160i() {
16532
16533         local mdts=$(comma_list $(mdts_nodes))
16534
16535         changelog_register || error "first changelog_register failed"
16536
16537         # generate some changelog records to accumulate on each MDT
16538         # use all_char because created files should be evenly distributed
16539         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16540                 error "test_mkdir $tdir failed"
16541         for ((i = 0; i < MDSCOUNT; i++)); do
16542                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16543                         error "create $DIR/$tdir/d$i.1 failed"
16544         done
16545
16546         # check changelogs have been generated
16547         local nbcl=$(changelog_dump | wc -l)
16548         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16549
16550         # simulate race between register and unregister
16551         # XXX as fail_loc is set per-MDS, with DNE configs the race
16552         # simulation will only occur for one MDT per MDS and for the
16553         # others the normal race scenario will take place
16554         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16555         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16556         do_nodes $mdts $LCTL set_param fail_val=1
16557
16558         # unregister 1st user
16559         changelog_deregister &
16560         local pid1=$!
16561         # wait some time for deregister work to reach race rdv
16562         sleep 2
16563         # register 2nd user
16564         changelog_register || error "2nd user register failed"
16565
16566         wait $pid1 || error "1st user deregister failed"
16567
16568         local i
16569         local last_rec
16570         declare -A LAST_REC
16571         for i in $(seq $MDSCOUNT); do
16572                 if changelog_users mds$i | grep "^cl"; then
16573                         # make sure new records are added with one user present
16574                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16575                                           awk '/^current.index:/ { print $NF }')
16576                 else
16577                         error "mds$i has no user registered"
16578                 fi
16579         done
16580
16581         # generate more changelog records to accumulate on each MDT
16582         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16583                 error "create $DIR/$tdir/${tfile}bis failed"
16584
16585         for i in $(seq $MDSCOUNT); do
16586                 last_rec=$(changelog_users $SINGLEMDS |
16587                            awk '/^current.index:/ { print $NF }')
16588                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16589                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16590                         error "changelogs are off on mds$i"
16591         done
16592 }
16593 run_test 160i "changelog user register/unregister race"
16594
16595 test_160j() {
16596         remote_mds_nodsh && skip "remote MDS with nodsh"
16597         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16598                 skip "Need MDS version at least 2.12.56"
16599
16600         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16601         stack_trap "umount $MOUNT2" EXIT
16602
16603         changelog_register || error "first changelog_register failed"
16604         stack_trap "changelog_deregister" EXIT
16605
16606         # generate some changelog
16607         # use all_char because created files should be evenly distributed
16608         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16609                 error "mkdir $tdir failed"
16610         for ((i = 0; i < MDSCOUNT; i++)); do
16611                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16612                         error "create $DIR/$tdir/d$i.1 failed"
16613         done
16614
16615         # open the changelog device
16616         exec 3>/dev/changelog-$FSNAME-MDT0000
16617         stack_trap "exec 3>&-" EXIT
16618         exec 4</dev/changelog-$FSNAME-MDT0000
16619         stack_trap "exec 4<&-" EXIT
16620
16621         # umount the first lustre mount
16622         umount $MOUNT
16623         stack_trap "mount_client $MOUNT" EXIT
16624
16625         # read changelog, which may or may not fail, but should not crash
16626         cat <&4 >/dev/null
16627
16628         # clear changelog
16629         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16630         changelog_users $SINGLEMDS | grep -q $cl_user ||
16631                 error "User $cl_user not found in changelog_users"
16632
16633         printf 'clear:'$cl_user':0' >&3
16634 }
16635 run_test 160j "client can be umounted while its chanangelog is being used"
16636
16637 test_160k() {
16638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16639         remote_mds_nodsh && skip "remote MDS with nodsh"
16640
16641         mkdir -p $DIR/$tdir/1/1
16642
16643         changelog_register || error "changelog_register failed"
16644         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16645
16646         changelog_users $SINGLEMDS | grep -q $cl_user ||
16647                 error "User '$cl_user' not found in changelog_users"
16648 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16649         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16650         rmdir $DIR/$tdir/1/1 & sleep 1
16651         mkdir $DIR/$tdir/2
16652         touch $DIR/$tdir/2/2
16653         rm -rf $DIR/$tdir/2
16654
16655         wait
16656         sleep 4
16657
16658         changelog_dump | grep rmdir || error "rmdir not recorded"
16659 }
16660 run_test 160k "Verify that changelog records are not lost"
16661
16662 # Verifies that a file passed as a parameter has recently had an operation
16663 # performed on it that has generated an MTIME changelog which contains the
16664 # correct parent FID. As files might reside on a different MDT from the
16665 # parent directory in DNE configurations, the FIDs are translated to paths
16666 # before being compared, which should be identical
16667 compare_mtime_changelog() {
16668         local file="${1}"
16669         local mdtidx
16670         local mtime
16671         local cl_fid
16672         local pdir
16673         local dir
16674
16675         mdtidx=$($LFS getstripe --mdt-index $file)
16676         mdtidx=$(printf "%04x" $mdtidx)
16677
16678         # Obtain the parent FID from the MTIME changelog
16679         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16680         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16681
16682         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16683         [ -z "$cl_fid" ] && error "parent FID not present"
16684
16685         # Verify that the path for the parent FID is the same as the path for
16686         # the test directory
16687         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16688
16689         dir=$(dirname $1)
16690
16691         [[ "${pdir%/}" == "$dir" ]] ||
16692                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16693 }
16694
16695 test_160l() {
16696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16697
16698         remote_mds_nodsh && skip "remote MDS with nodsh"
16699         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16700                 skip "Need MDS version at least 2.13.55"
16701
16702         local cl_user
16703
16704         changelog_register || error "changelog_register failed"
16705         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16706
16707         changelog_users $SINGLEMDS | grep -q $cl_user ||
16708                 error "User '$cl_user' not found in changelog_users"
16709
16710         # Clear some types so that MTIME changelogs are generated
16711         changelog_chmask "-CREAT"
16712         changelog_chmask "-CLOSE"
16713
16714         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16715
16716         # Test CL_MTIME during setattr
16717         touch $DIR/$tdir/$tfile
16718         compare_mtime_changelog $DIR/$tdir/$tfile
16719
16720         # Test CL_MTIME during close
16721         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16722         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16723 }
16724 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16725
16726 test_160m() {
16727         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16728         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16729                 skip "Need MDS version at least 2.14.51"
16730         local cl_users
16731         local cl_user1
16732         local cl_user2
16733         local pid1
16734
16735         # Create a user
16736         changelog_register || error "first changelog_register failed"
16737         changelog_register || error "second changelog_register failed"
16738
16739         cl_users=(${CL_USERS[mds1]})
16740         cl_user1="${cl_users[0]}"
16741         cl_user2="${cl_users[1]}"
16742         # generate some changelog records to accumulate on MDT0
16743         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16744         createmany -m $DIR/$tdir/$tfile 50 ||
16745                 error "create $DIR/$tdir/$tfile failed"
16746         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16747         rm -f $DIR/$tdir
16748
16749         # check changelogs have been generated
16750         local nbcl=$(changelog_dump | wc -l)
16751         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16752
16753 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16754         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16755
16756         __changelog_clear mds1 $cl_user1 +10
16757         __changelog_clear mds1 $cl_user2 0 &
16758         pid1=$!
16759         sleep 2
16760         __changelog_clear mds1 $cl_user1 0 ||
16761                 error "fail to cancel record for $cl_user1"
16762         wait $pid1
16763         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16764 }
16765 run_test 160m "Changelog clear race"
16766
16767 test_160n() {
16768         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16769         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16770                 skip "Need MDS version at least 2.14.51"
16771         local cl_users
16772         local cl_user1
16773         local cl_user2
16774         local pid1
16775         local first_rec
16776         local last_rec=0
16777
16778         # Create a user
16779         changelog_register || error "first changelog_register failed"
16780
16781         cl_users=(${CL_USERS[mds1]})
16782         cl_user1="${cl_users[0]}"
16783
16784         # generate some changelog records to accumulate on MDT0
16785         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16786         first_rec=$(changelog_users $SINGLEMDS |
16787                         awk '/^current.index:/ { print $NF }')
16788         while (( last_rec < (( first_rec + 65000)) )); do
16789                 createmany -m $DIR/$tdir/$tfile 10000 ||
16790                         error "create $DIR/$tdir/$tfile failed"
16791
16792                 for i in $(seq 0 10000); do
16793                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16794                                 > /dev/null
16795                 done
16796
16797                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16798                         error "unlinkmany failed unlink"
16799                 last_rec=$(changelog_users $SINGLEMDS |
16800                         awk '/^current.index:/ { print $NF }')
16801                 echo last record $last_rec
16802                 (( last_rec == 0 )) && error "no changelog found"
16803         done
16804
16805 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16806         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16807
16808         __changelog_clear mds1 $cl_user1 0 &
16809         pid1=$!
16810         sleep 2
16811         __changelog_clear mds1 $cl_user1 0 ||
16812                 error "fail to cancel record for $cl_user1"
16813         wait $pid1
16814         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16815 }
16816 run_test 160n "Changelog destroy race"
16817
16818 test_160o() {
16819         local mdt="$(facet_svc $SINGLEMDS)"
16820
16821         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16822         remote_mds_nodsh && skip "remote MDS with nodsh"
16823         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16824                 skip "Need MDS version at least 2.14.52"
16825
16826         changelog_register --user test_160o -m unlnk+close+open ||
16827                 error "changelog_register failed"
16828
16829         do_facet $SINGLEMDS $LCTL --device $mdt \
16830                                 changelog_register -u "Tt3_-#" &&
16831                 error "bad symbols in name should fail"
16832
16833         do_facet $SINGLEMDS $LCTL --device $mdt \
16834                                 changelog_register -u test_160o &&
16835                 error "the same name registration should fail"
16836
16837         do_facet $SINGLEMDS $LCTL --device $mdt \
16838                         changelog_register -u test_160toolongname &&
16839                 error "too long name registration should fail"
16840
16841         changelog_chmask "MARK+HSM"
16842         lctl get_param mdd.*.changelog*mask
16843         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16844         changelog_users $SINGLEMDS | grep -q $cl_user ||
16845                 error "User $cl_user not found in changelog_users"
16846         #verify username
16847         echo $cl_user | grep -q test_160o ||
16848                 error "User $cl_user has no specific name 'test160o'"
16849
16850         # change something
16851         changelog_clear 0 || error "changelog_clear failed"
16852         # generate some changelog records to accumulate on MDT0
16853         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16854         touch $DIR/$tdir/$tfile                 # open 1
16855
16856         OPENS=$(changelog_dump | grep -c "OPEN")
16857         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16858
16859         # must be no MKDIR it wasn't set as user mask
16860         MKDIR=$(changelog_dump | grep -c "MKDIR")
16861         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16862
16863         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16864                                 mdd.$mdt.changelog_current_mask -n)
16865         # register maskless user
16866         changelog_register || error "changelog_register failed"
16867         # effective mask should be not changed because it is not minimal
16868         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16869                                 mdd.$mdt.changelog_current_mask -n)
16870         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16871         # set server mask to minimal value
16872         changelog_chmask "MARK"
16873         # check effective mask again, should be treated as DEFMASK now
16874         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16875                                 mdd.$mdt.changelog_current_mask -n)
16876         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16877
16878         do_facet $SINGLEMDS $LCTL --device $mdt \
16879                                 changelog_deregister -u test_160o ||
16880                 error "cannot deregister by name"
16881 }
16882 run_test 160o "changelog user name and mask"
16883
16884 test_160p() {
16885         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16886         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16887                 skip "Need MDS version at least 2.14.51"
16888         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16889         local cl_users
16890         local cl_user1
16891         local entry_count
16892
16893         # Create a user
16894         changelog_register || error "first changelog_register failed"
16895
16896         cl_users=(${CL_USERS[mds1]})
16897         cl_user1="${cl_users[0]}"
16898
16899         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16900         createmany -m $DIR/$tdir/$tfile 50 ||
16901                 error "create $DIR/$tdir/$tfile failed"
16902         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16903         rm -rf $DIR/$tdir
16904
16905         # check changelogs have been generated
16906         entry_count=$(changelog_dump | wc -l)
16907         ((entry_count != 0)) || error "no changelog entries found"
16908
16909         # remove changelog_users and check that orphan entries are removed
16910         stop mds1
16911         local dev=$(mdsdevname 1)
16912         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
16913         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
16914         entry_count=$(changelog_dump | wc -l)
16915         ((entry_count == 0)) ||
16916                 error "found $entry_count changelog entries, expected none"
16917 }
16918 run_test 160p "Changelog orphan cleanup with no users"
16919
16920 test_160q() {
16921         local mdt="$(facet_svc $SINGLEMDS)"
16922         local clu
16923
16924         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16925         remote_mds_nodsh && skip "remote MDS with nodsh"
16926         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16927                 skip "Need MDS version at least 2.14.54"
16928
16929         # set server mask to minimal value like server init does
16930         changelog_chmask "MARK"
16931         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16932                 error "changelog_register failed"
16933         # check effective mask again, should be treated as DEFMASK now
16934         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16935                                 mdd.$mdt.changelog_current_mask -n)
16936         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
16937                 error "changelog_deregister failed"
16938         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16939 }
16940 run_test 160q "changelog effective mask is DEFMASK if not set"
16941
16942 test_160s() {
16943         remote_mds_nodsh && skip "remote MDS with nodsh"
16944         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
16945                 skip "Need MDS version at least 2.14.55"
16946
16947         local mdts=$(comma_list $(mdts_nodes))
16948
16949         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
16950         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
16951                                        fail_val=$((24 * 3600 * 10))
16952
16953         # Create a user which is 10 days old
16954         changelog_register || error "first changelog_register failed"
16955         local cl_users
16956         declare -A cl_user1
16957         local i
16958
16959         # generate some changelog records to accumulate on each MDT
16960         # use all_char because created files should be evenly distributed
16961         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16962                 error "test_mkdir $tdir failed"
16963         for ((i = 0; i < MDSCOUNT; i++)); do
16964                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16965                         error "create $DIR/$tdir/d$i.1 failed"
16966         done
16967
16968         # check changelogs have been generated
16969         local nbcl=$(changelog_dump | wc -l)
16970         (( nbcl > 0 )) || error "no changelogs found"
16971
16972         # reduce the max_idle_indexes value to make sure we exceed it
16973         for param in "changelog_max_idle_indexes=2097446912" \
16974                      "changelog_max_idle_time=2592000" \
16975                      "changelog_gc=1" \
16976                      "changelog_min_gc_interval=2"; do
16977                 local MDT0=$(facet_svc $SINGLEMDS)
16978                 local var="${param%=*}"
16979                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16980
16981                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16982                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16983                         error "unable to set mdd.*.$param"
16984         done
16985
16986         local start=$SECONDS
16987         for i in $(seq $MDSCOUNT); do
16988                 cl_users=(${CL_USERS[mds$i]})
16989                 cl_user1[mds$i]="${cl_users[0]}"
16990
16991                 [[ -n "${cl_user1[mds$i]}" ]] ||
16992                         error "mds$i: no user registered"
16993         done
16994
16995         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
16996         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
16997
16998         # ensure we are past the previous changelog_min_gc_interval set above
16999         local sleep2=$((start + 2 - SECONDS))
17000         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17001
17002         # Generate one more changelog to trigger GC
17003         for ((i = 0; i < MDSCOUNT; i++)); do
17004                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17005                         error "create $DIR/$tdir/d$i.3 failed"
17006         done
17007
17008         # ensure gc thread is done
17009         for node in $(mdts_nodes); do
17010                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17011                         error "$node: GC-thread not done"
17012         done
17013
17014         do_nodes $mdts $LCTL set_param fail_loc=0
17015
17016         for (( i = 1; i <= MDSCOUNT; i++ )); do
17017                 # check cl_user1 is purged
17018                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17019                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17020         done
17021         return 0
17022 }
17023 run_test 160s "changelog garbage collect on idle records * time"
17024
17025 test_161a() {
17026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17027
17028         test_mkdir -c1 $DIR/$tdir
17029         cp /etc/hosts $DIR/$tdir/$tfile
17030         test_mkdir -c1 $DIR/$tdir/foo1
17031         test_mkdir -c1 $DIR/$tdir/foo2
17032         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17033         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17034         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17035         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17036         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
17037         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17038                 $LFS fid2path $DIR $FID
17039                 error "bad link ea"
17040         fi
17041         # middle
17042         rm $DIR/$tdir/foo2/zachary
17043         # last
17044         rm $DIR/$tdir/foo2/thor
17045         # first
17046         rm $DIR/$tdir/$tfile
17047         # rename
17048         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
17049         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
17050                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
17051         rm $DIR/$tdir/foo2/maggie
17052
17053         # overflow the EA
17054         local longname=$tfile.avg_len_is_thirty_two_
17055         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
17056                 error_noexit 'failed to unlink many hardlinks'" EXIT
17057         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
17058                 error "failed to hardlink many files"
17059         links=$($LFS fid2path $DIR $FID | wc -l)
17060         echo -n "${links}/1000 links in link EA"
17061         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
17062 }
17063 run_test 161a "link ea sanity"
17064
17065 test_161b() {
17066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17067         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17068
17069         local MDTIDX=1
17070         local remote_dir=$DIR/$tdir/remote_dir
17071
17072         mkdir -p $DIR/$tdir
17073         $LFS mkdir -i $MDTIDX $remote_dir ||
17074                 error "create remote directory failed"
17075
17076         cp /etc/hosts $remote_dir/$tfile
17077         mkdir -p $remote_dir/foo1
17078         mkdir -p $remote_dir/foo2
17079         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17080         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17081         ln $remote_dir/$tfile $remote_dir/foo1/luna
17082         ln $remote_dir/$tfile $remote_dir/foo2/thor
17083
17084         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17085                      tr -d ']')
17086         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17087                 $LFS fid2path $DIR $FID
17088                 error "bad link ea"
17089         fi
17090         # middle
17091         rm $remote_dir/foo2/zachary
17092         # last
17093         rm $remote_dir/foo2/thor
17094         # first
17095         rm $remote_dir/$tfile
17096         # rename
17097         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17098         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17099         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17100                 $LFS fid2path $DIR $FID
17101                 error "bad link rename"
17102         fi
17103         rm $remote_dir/foo2/maggie
17104
17105         # overflow the EA
17106         local longname=filename_avg_len_is_thirty_two_
17107         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17108                 error "failed to hardlink many files"
17109         links=$($LFS fid2path $DIR $FID | wc -l)
17110         echo -n "${links}/1000 links in link EA"
17111         [[ ${links} -gt 60 ]] ||
17112                 error "expected at least 60 links in link EA"
17113         unlinkmany $remote_dir/foo2/$longname 1000 ||
17114         error "failed to unlink many hardlinks"
17115 }
17116 run_test 161b "link ea sanity under remote directory"
17117
17118 test_161c() {
17119         remote_mds_nodsh && skip "remote MDS with nodsh"
17120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17121         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17122                 skip "Need MDS version at least 2.1.5"
17123
17124         # define CLF_RENAME_LAST 0x0001
17125         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17126         changelog_register || error "changelog_register failed"
17127
17128         rm -rf $DIR/$tdir
17129         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17130         touch $DIR/$tdir/foo_161c
17131         touch $DIR/$tdir/bar_161c
17132         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17133         changelog_dump | grep RENME | tail -n 5
17134         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17135         changelog_clear 0 || error "changelog_clear failed"
17136         if [ x$flags != "x0x1" ]; then
17137                 error "flag $flags is not 0x1"
17138         fi
17139
17140         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17141         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17142         touch $DIR/$tdir/foo_161c
17143         touch $DIR/$tdir/bar_161c
17144         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17145         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17146         changelog_dump | grep RENME | tail -n 5
17147         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17148         changelog_clear 0 || error "changelog_clear failed"
17149         if [ x$flags != "x0x0" ]; then
17150                 error "flag $flags is not 0x0"
17151         fi
17152         echo "rename overwrite a target having nlink > 1," \
17153                 "changelog record has flags of $flags"
17154
17155         # rename doesn't overwrite a target (changelog flag 0x0)
17156         touch $DIR/$tdir/foo_161c
17157         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17158         changelog_dump | grep RENME | tail -n 5
17159         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17160         changelog_clear 0 || error "changelog_clear failed"
17161         if [ x$flags != "x0x0" ]; then
17162                 error "flag $flags is not 0x0"
17163         fi
17164         echo "rename doesn't overwrite a target," \
17165                 "changelog record has flags of $flags"
17166
17167         # define CLF_UNLINK_LAST 0x0001
17168         # unlink a file having nlink = 1 (changelog flag 0x1)
17169         rm -f $DIR/$tdir/foo2_161c
17170         changelog_dump | grep UNLNK | tail -n 5
17171         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17172         changelog_clear 0 || error "changelog_clear failed"
17173         if [ x$flags != "x0x1" ]; then
17174                 error "flag $flags is not 0x1"
17175         fi
17176         echo "unlink a file having nlink = 1," \
17177                 "changelog record has flags of $flags"
17178
17179         # unlink a file having nlink > 1 (changelog flag 0x0)
17180         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17181         rm -f $DIR/$tdir/foobar_161c
17182         changelog_dump | grep UNLNK | tail -n 5
17183         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17184         changelog_clear 0 || error "changelog_clear failed"
17185         if [ x$flags != "x0x0" ]; then
17186                 error "flag $flags is not 0x0"
17187         fi
17188         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17189 }
17190 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17191
17192 test_161d() {
17193         remote_mds_nodsh && skip "remote MDS with nodsh"
17194         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17195
17196         local pid
17197         local fid
17198
17199         changelog_register || error "changelog_register failed"
17200
17201         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17202         # interfer with $MOUNT/.lustre/fid/ access
17203         mkdir $DIR/$tdir
17204         [[ $? -eq 0 ]] || error "mkdir failed"
17205
17206         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17207         $LCTL set_param fail_loc=0x8000140c
17208         # 5s pause
17209         $LCTL set_param fail_val=5
17210
17211         # create file
17212         echo foofoo > $DIR/$tdir/$tfile &
17213         pid=$!
17214
17215         # wait for create to be delayed
17216         sleep 2
17217
17218         ps -p $pid
17219         [[ $? -eq 0 ]] || error "create should be blocked"
17220
17221         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17222         stack_trap "rm -f $tempfile"
17223         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17224         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17225         # some delay may occur during ChangeLog publishing and file read just
17226         # above, that could allow file write to happen finally
17227         [[ -s $tempfile ]] && echo "file should be empty"
17228
17229         $LCTL set_param fail_loc=0
17230
17231         wait $pid
17232         [[ $? -eq 0 ]] || error "create failed"
17233 }
17234 run_test 161d "create with concurrent .lustre/fid access"
17235
17236 check_path() {
17237         local expected="$1"
17238         shift
17239         local fid="$2"
17240
17241         local path
17242         path=$($LFS fid2path "$@")
17243         local rc=$?
17244
17245         if [ $rc -ne 0 ]; then
17246                 error "path looked up of '$expected' failed: rc=$rc"
17247         elif [ "$path" != "$expected" ]; then
17248                 error "path looked up '$path' instead of '$expected'"
17249         else
17250                 echo "FID '$fid' resolves to path '$path' as expected"
17251         fi
17252 }
17253
17254 test_162a() { # was test_162
17255         test_mkdir -p -c1 $DIR/$tdir/d2
17256         touch $DIR/$tdir/d2/$tfile
17257         touch $DIR/$tdir/d2/x1
17258         touch $DIR/$tdir/d2/x2
17259         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17260         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17261         # regular file
17262         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17263         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17264
17265         # softlink
17266         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17267         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17268         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17269
17270         # softlink to wrong file
17271         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17272         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17273         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17274
17275         # hardlink
17276         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17277         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17278         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17279         # fid2path dir/fsname should both work
17280         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17281         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17282
17283         # hardlink count: check that there are 2 links
17284         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17285         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17286
17287         # hardlink indexing: remove the first link
17288         rm $DIR/$tdir/d2/p/q/r/hlink
17289         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17290 }
17291 run_test 162a "path lookup sanity"
17292
17293 test_162b() {
17294         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17295         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17296
17297         mkdir $DIR/$tdir
17298         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17299                                 error "create striped dir failed"
17300
17301         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17302                                         tail -n 1 | awk '{print $2}')
17303         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17304
17305         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17306         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17307
17308         # regular file
17309         for ((i=0;i<5;i++)); do
17310                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17311                         error "get fid for f$i failed"
17312                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17313
17314                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17315                         error "get fid for d$i failed"
17316                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17317         done
17318
17319         return 0
17320 }
17321 run_test 162b "striped directory path lookup sanity"
17322
17323 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17324 test_162c() {
17325         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17326                 skip "Need MDS version at least 2.7.51"
17327
17328         local lpath=$tdir.local
17329         local rpath=$tdir.remote
17330
17331         test_mkdir $DIR/$lpath
17332         test_mkdir $DIR/$rpath
17333
17334         for ((i = 0; i <= 101; i++)); do
17335                 lpath="$lpath/$i"
17336                 mkdir $DIR/$lpath
17337                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17338                         error "get fid for local directory $DIR/$lpath failed"
17339                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17340
17341                 rpath="$rpath/$i"
17342                 test_mkdir $DIR/$rpath
17343                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17344                         error "get fid for remote directory $DIR/$rpath failed"
17345                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17346         done
17347
17348         return 0
17349 }
17350 run_test 162c "fid2path works with paths 100 or more directories deep"
17351
17352 oalr_event_count() {
17353         local event="${1}"
17354         local trace="${2}"
17355
17356         awk -v name="${FSNAME}-OST0000" \
17357             -v event="${event}" \
17358             '$1 == "TRACE" && $2 == event && $3 == name' \
17359             "${trace}" |
17360         wc -l
17361 }
17362
17363 oalr_expect_event_count() {
17364         local event="${1}"
17365         local trace="${2}"
17366         local expect="${3}"
17367         local count
17368
17369         count=$(oalr_event_count "${event}" "${trace}")
17370         if ((count == expect)); then
17371                 return 0
17372         fi
17373
17374         error_noexit "${event} event count was '${count}', expected ${expect}"
17375         cat "${trace}" >&2
17376         exit 1
17377 }
17378
17379 cleanup_165() {
17380         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17381         stop ost1
17382         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17383 }
17384
17385 setup_165() {
17386         sync # Flush previous IOs so we can count log entries.
17387         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17388         stack_trap cleanup_165 EXIT
17389 }
17390
17391 test_165a() {
17392         local trace="/tmp/${tfile}.trace"
17393         local rc
17394         local count
17395
17396         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17397                 skip "OFD access log unsupported"
17398
17399         setup_165
17400         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17401         sleep 5
17402
17403         do_facet ost1 ofd_access_log_reader --list
17404         stop ost1
17405
17406         do_facet ost1 killall -TERM ofd_access_log_reader
17407         wait
17408         rc=$?
17409
17410         if ((rc != 0)); then
17411                 error "ofd_access_log_reader exited with rc = '${rc}'"
17412         fi
17413
17414         # Parse trace file for discovery events:
17415         oalr_expect_event_count alr_log_add "${trace}" 1
17416         oalr_expect_event_count alr_log_eof "${trace}" 1
17417         oalr_expect_event_count alr_log_free "${trace}" 1
17418 }
17419 run_test 165a "ofd access log discovery"
17420
17421 test_165b() {
17422         local trace="/tmp/${tfile}.trace"
17423         local file="${DIR}/${tfile}"
17424         local pfid1
17425         local pfid2
17426         local -a entry
17427         local rc
17428         local count
17429         local size
17430         local flags
17431
17432         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17433                 skip "OFD access log unsupported"
17434
17435         setup_165
17436         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17437         sleep 5
17438
17439         do_facet ost1 ofd_access_log_reader --list
17440
17441         lfs setstripe -c 1 -i 0 "${file}"
17442         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17443                 error "cannot create '${file}'"
17444
17445         sleep 5
17446         do_facet ost1 killall -TERM ofd_access_log_reader
17447         wait
17448         rc=$?
17449
17450         if ((rc != 0)); then
17451                 error "ofd_access_log_reader exited with rc = '${rc}'"
17452         fi
17453
17454         oalr_expect_event_count alr_log_entry "${trace}" 1
17455
17456         pfid1=$($LFS path2fid "${file}")
17457
17458         # 1     2             3   4    5     6   7    8    9     10
17459         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17460         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17461
17462         echo "entry = '${entry[*]}'" >&2
17463
17464         pfid2=${entry[4]}
17465         if [[ "${pfid1}" != "${pfid2}" ]]; then
17466                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17467         fi
17468
17469         size=${entry[8]}
17470         if ((size != 1048576)); then
17471                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17472         fi
17473
17474         flags=${entry[10]}
17475         if [[ "${flags}" != "w" ]]; then
17476                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17477         fi
17478
17479         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17480         sleep 5
17481
17482         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17483                 error "cannot read '${file}'"
17484         sleep 5
17485
17486         do_facet ost1 killall -TERM ofd_access_log_reader
17487         wait
17488         rc=$?
17489
17490         if ((rc != 0)); then
17491                 error "ofd_access_log_reader exited with rc = '${rc}'"
17492         fi
17493
17494         oalr_expect_event_count alr_log_entry "${trace}" 1
17495
17496         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17497         echo "entry = '${entry[*]}'" >&2
17498
17499         pfid2=${entry[4]}
17500         if [[ "${pfid1}" != "${pfid2}" ]]; then
17501                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17502         fi
17503
17504         size=${entry[8]}
17505         if ((size != 524288)); then
17506                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17507         fi
17508
17509         flags=${entry[10]}
17510         if [[ "${flags}" != "r" ]]; then
17511                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17512         fi
17513 }
17514 run_test 165b "ofd access log entries are produced and consumed"
17515
17516 test_165c() {
17517         local trace="/tmp/${tfile}.trace"
17518         local file="${DIR}/${tdir}/${tfile}"
17519
17520         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17521                 skip "OFD access log unsupported"
17522
17523         test_mkdir "${DIR}/${tdir}"
17524
17525         setup_165
17526         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17527         sleep 5
17528
17529         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17530
17531         # 4096 / 64 = 64. Create twice as many entries.
17532         for ((i = 0; i < 128; i++)); do
17533                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17534                         error "cannot create file"
17535         done
17536
17537         sync
17538
17539         do_facet ost1 killall -TERM ofd_access_log_reader
17540         wait
17541         rc=$?
17542         if ((rc != 0)); then
17543                 error "ofd_access_log_reader exited with rc = '${rc}'"
17544         fi
17545
17546         unlinkmany  "${file}-%d" 128
17547 }
17548 run_test 165c "full ofd access logs do not block IOs"
17549
17550 oal_get_read_count() {
17551         local stats="$1"
17552
17553         # STATS lustre-OST0001 alr_read_count 1
17554
17555         do_facet ost1 cat "${stats}" |
17556         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17557              END { print count; }'
17558 }
17559
17560 oal_expect_read_count() {
17561         local stats="$1"
17562         local count
17563         local expect="$2"
17564
17565         # Ask ofd_access_log_reader to write stats.
17566         do_facet ost1 killall -USR1 ofd_access_log_reader
17567
17568         # Allow some time for things to happen.
17569         sleep 1
17570
17571         count=$(oal_get_read_count "${stats}")
17572         if ((count == expect)); then
17573                 return 0
17574         fi
17575
17576         error_noexit "bad read count, got ${count}, expected ${expect}"
17577         do_facet ost1 cat "${stats}" >&2
17578         exit 1
17579 }
17580
17581 test_165d() {
17582         local stats="/tmp/${tfile}.stats"
17583         local file="${DIR}/${tdir}/${tfile}"
17584         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17585
17586         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17587                 skip "OFD access log unsupported"
17588
17589         test_mkdir "${DIR}/${tdir}"
17590
17591         setup_165
17592         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17593         sleep 5
17594
17595         lfs setstripe -c 1 -i 0 "${file}"
17596
17597         do_facet ost1 lctl set_param "${param}=rw"
17598         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17599                 error "cannot create '${file}'"
17600         oal_expect_read_count "${stats}" 1
17601
17602         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17603                 error "cannot read '${file}'"
17604         oal_expect_read_count "${stats}" 2
17605
17606         do_facet ost1 lctl set_param "${param}=r"
17607         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17608                 error "cannot create '${file}'"
17609         oal_expect_read_count "${stats}" 2
17610
17611         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17612                 error "cannot read '${file}'"
17613         oal_expect_read_count "${stats}" 3
17614
17615         do_facet ost1 lctl set_param "${param}=w"
17616         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17617                 error "cannot create '${file}'"
17618         oal_expect_read_count "${stats}" 4
17619
17620         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17621                 error "cannot read '${file}'"
17622         oal_expect_read_count "${stats}" 4
17623
17624         do_facet ost1 lctl set_param "${param}=0"
17625         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17626                 error "cannot create '${file}'"
17627         oal_expect_read_count "${stats}" 4
17628
17629         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17630                 error "cannot read '${file}'"
17631         oal_expect_read_count "${stats}" 4
17632
17633         do_facet ost1 killall -TERM ofd_access_log_reader
17634         wait
17635         rc=$?
17636         if ((rc != 0)); then
17637                 error "ofd_access_log_reader exited with rc = '${rc}'"
17638         fi
17639 }
17640 run_test 165d "ofd_access_log mask works"
17641
17642 test_165e() {
17643         local stats="/tmp/${tfile}.stats"
17644         local file0="${DIR}/${tdir}-0/${tfile}"
17645         local file1="${DIR}/${tdir}-1/${tfile}"
17646
17647         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17648                 skip "OFD access log unsupported"
17649
17650         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17651
17652         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17653         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17654
17655         lfs setstripe -c 1 -i 0 "${file0}"
17656         lfs setstripe -c 1 -i 0 "${file1}"
17657
17658         setup_165
17659         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17660         sleep 5
17661
17662         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17663                 error "cannot create '${file0}'"
17664         sync
17665         oal_expect_read_count "${stats}" 0
17666
17667         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17668                 error "cannot create '${file1}'"
17669         sync
17670         oal_expect_read_count "${stats}" 1
17671
17672         do_facet ost1 killall -TERM ofd_access_log_reader
17673         wait
17674         rc=$?
17675         if ((rc != 0)); then
17676                 error "ofd_access_log_reader exited with rc = '${rc}'"
17677         fi
17678 }
17679 run_test 165e "ofd_access_log MDT index filter works"
17680
17681 test_165f() {
17682         local trace="/tmp/${tfile}.trace"
17683         local rc
17684         local count
17685
17686         setup_165
17687         do_facet ost1 timeout 60 ofd_access_log_reader \
17688                 --exit-on-close --debug=- --trace=- > "${trace}" &
17689         sleep 5
17690         stop ost1
17691
17692         wait
17693         rc=$?
17694
17695         if ((rc != 0)); then
17696                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17697                 cat "${trace}"
17698                 exit 1
17699         fi
17700 }
17701 run_test 165f "ofd_access_log_reader --exit-on-close works"
17702
17703 test_169() {
17704         # do directio so as not to populate the page cache
17705         log "creating a 10 Mb file"
17706         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17707                 error "multiop failed while creating a file"
17708         log "starting reads"
17709         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17710         log "truncating the file"
17711         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17712                 error "multiop failed while truncating the file"
17713         log "killing dd"
17714         kill %+ || true # reads might have finished
17715         echo "wait until dd is finished"
17716         wait
17717         log "removing the temporary file"
17718         rm -rf $DIR/$tfile || error "tmp file removal failed"
17719 }
17720 run_test 169 "parallel read and truncate should not deadlock"
17721
17722 test_170() {
17723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17724
17725         $LCTL clear     # bug 18514
17726         $LCTL debug_daemon start $TMP/${tfile}_log_good
17727         touch $DIR/$tfile
17728         $LCTL debug_daemon stop
17729         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17730                 error "sed failed to read log_good"
17731
17732         $LCTL debug_daemon start $TMP/${tfile}_log_good
17733         rm -rf $DIR/$tfile
17734         $LCTL debug_daemon stop
17735
17736         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17737                error "lctl df log_bad failed"
17738
17739         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17740         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17741
17742         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17743         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17744
17745         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17746                 error "bad_line good_line1 good_line2 are empty"
17747
17748         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17749         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17750         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17751
17752         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17753         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17754         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17755
17756         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17757                 error "bad_line_new good_line_new are empty"
17758
17759         local expected_good=$((good_line1 + good_line2*2))
17760
17761         rm -f $TMP/${tfile}*
17762         # LU-231, short malformed line may not be counted into bad lines
17763         if [ $bad_line -ne $bad_line_new ] &&
17764                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17765                 error "expected $bad_line bad lines, but got $bad_line_new"
17766                 return 1
17767         fi
17768
17769         if [ $expected_good -ne $good_line_new ]; then
17770                 error "expected $expected_good good lines, but got $good_line_new"
17771                 return 2
17772         fi
17773         true
17774 }
17775 run_test 170 "test lctl df to handle corrupted log ====================="
17776
17777 test_171() { # bug20592
17778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17779
17780         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17781         $LCTL set_param fail_loc=0x50e
17782         $LCTL set_param fail_val=3000
17783         multiop_bg_pause $DIR/$tfile O_s || true
17784         local MULTIPID=$!
17785         kill -USR1 $MULTIPID
17786         # cause log dump
17787         sleep 3
17788         wait $MULTIPID
17789         if dmesg | grep "recursive fault"; then
17790                 error "caught a recursive fault"
17791         fi
17792         $LCTL set_param fail_loc=0
17793         true
17794 }
17795 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17796
17797 # it would be good to share it with obdfilter-survey/iokit-libecho code
17798 setup_obdecho_osc () {
17799         local rc=0
17800         local ost_nid=$1
17801         local obdfilter_name=$2
17802         echo "Creating new osc for $obdfilter_name on $ost_nid"
17803         # make sure we can find loopback nid
17804         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17805
17806         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17807                            ${obdfilter_name}_osc_UUID || rc=2; }
17808         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17809                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17810         return $rc
17811 }
17812
17813 cleanup_obdecho_osc () {
17814         local obdfilter_name=$1
17815         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17816         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17817         return 0
17818 }
17819
17820 obdecho_test() {
17821         local OBD=$1
17822         local node=$2
17823         local pages=${3:-64}
17824         local rc=0
17825         local id
17826
17827         local count=10
17828         local obd_size=$(get_obd_size $node $OBD)
17829         local page_size=$(get_page_size $node)
17830         if [[ -n "$obd_size" ]]; then
17831                 local new_count=$((obd_size / (pages * page_size / 1024)))
17832                 [[ $new_count -ge $count ]] || count=$new_count
17833         fi
17834
17835         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17836         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17837                            rc=2; }
17838         if [ $rc -eq 0 ]; then
17839             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17840             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17841         fi
17842         echo "New object id is $id"
17843         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17844                            rc=4; }
17845         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17846                            "test_brw $count w v $pages $id" || rc=4; }
17847         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17848                            rc=4; }
17849         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17850                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17851         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17852                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17853         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17854         return $rc
17855 }
17856
17857 test_180a() {
17858         skip "obdecho on osc is no longer supported"
17859 }
17860 run_test 180a "test obdecho on osc"
17861
17862 test_180b() {
17863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17864         remote_ost_nodsh && skip "remote OST with nodsh"
17865
17866         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17867                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17868                 error "failed to load module obdecho"
17869
17870         local target=$(do_facet ost1 $LCTL dl |
17871                        awk '/obdfilter/ { print $4; exit; }')
17872
17873         if [ -n "$target" ]; then
17874                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17875         else
17876                 do_facet ost1 $LCTL dl
17877                 error "there is no obdfilter target on ost1"
17878         fi
17879 }
17880 run_test 180b "test obdecho directly on obdfilter"
17881
17882 test_180c() { # LU-2598
17883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17884         remote_ost_nodsh && skip "remote OST with nodsh"
17885         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17886                 skip "Need MDS version at least 2.4.0"
17887
17888         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17889                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17890                 error "failed to load module obdecho"
17891
17892         local target=$(do_facet ost1 $LCTL dl |
17893                        awk '/obdfilter/ { print $4; exit; }')
17894
17895         if [ -n "$target" ]; then
17896                 local pages=16384 # 64MB bulk I/O RPC size
17897
17898                 obdecho_test "$target" ost1 "$pages" ||
17899                         error "obdecho_test with pages=$pages failed with $?"
17900         else
17901                 do_facet ost1 $LCTL dl
17902                 error "there is no obdfilter target on ost1"
17903         fi
17904 }
17905 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17906
17907 test_181() { # bug 22177
17908         test_mkdir $DIR/$tdir
17909         # create enough files to index the directory
17910         createmany -o $DIR/$tdir/foobar 4000
17911         # print attributes for debug purpose
17912         lsattr -d .
17913         # open dir
17914         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17915         MULTIPID=$!
17916         # remove the files & current working dir
17917         unlinkmany $DIR/$tdir/foobar 4000
17918         rmdir $DIR/$tdir
17919         kill -USR1 $MULTIPID
17920         wait $MULTIPID
17921         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17922         return 0
17923 }
17924 run_test 181 "Test open-unlinked dir ========================"
17925
17926 test_182a() {
17927         local fcount=1000
17928         local tcount=10
17929
17930         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17931
17932         $LCTL set_param mdc.*.rpc_stats=clear
17933
17934         for (( i = 0; i < $tcount; i++ )) ; do
17935                 mkdir $DIR/$tdir/$i
17936         done
17937
17938         for (( i = 0; i < $tcount; i++ )) ; do
17939                 createmany -o $DIR/$tdir/$i/f- $fcount &
17940         done
17941         wait
17942
17943         for (( i = 0; i < $tcount; i++ )) ; do
17944                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17945         done
17946         wait
17947
17948         $LCTL get_param mdc.*.rpc_stats
17949
17950         rm -rf $DIR/$tdir
17951 }
17952 run_test 182a "Test parallel modify metadata operations from mdc"
17953
17954 test_182b() {
17955         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
17956         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
17957         local dcount=1000
17958         local tcount=10
17959         local stime
17960         local etime
17961         local delta
17962
17963         do_facet mds1 $LCTL list_param \
17964                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
17965                 skip "MDS lacks parallel RPC handling"
17966
17967         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17968
17969         rpc_count=$(do_facet mds1 $LCTL get_param -n \
17970                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
17971
17972         stime=$(date +%s)
17973         createmany -i 0 -d $DIR/$tdir/t- $tcount
17974
17975         for (( i = 0; i < $tcount; i++ )) ; do
17976                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
17977         done
17978         wait
17979         etime=$(date +%s)
17980         delta=$((etime - stime))
17981         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
17982
17983         stime=$(date +%s)
17984         for (( i = 0; i < $tcount; i++ )) ; do
17985                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
17986         done
17987         wait
17988         etime=$(date +%s)
17989         delta=$((etime - stime))
17990         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
17991
17992         rm -rf $DIR/$tdir
17993
17994         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17995
17996         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
17997
17998         stime=$(date +%s)
17999         createmany -i 0 -d $DIR/$tdir/t- $tcount
18000
18001         for (( i = 0; i < $tcount; i++ )) ; do
18002                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18003         done
18004         wait
18005         etime=$(date +%s)
18006         delta=$((etime - stime))
18007         echo "Time for file creation $delta sec for 1 RPC sent at a time"
18008
18009         stime=$(date +%s)
18010         for (( i = 0; i < $tcount; i++ )) ; do
18011                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
18012         done
18013         wait
18014         etime=$(date +%s)
18015         delta=$((etime - stime))
18016         echo "Time for file removal $delta sec for 1 RPC sent at a time"
18017
18018         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
18019 }
18020 run_test 182b "Test parallel modify metadata operations from osp"
18021
18022 test_183() { # LU-2275
18023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18024         remote_mds_nodsh && skip "remote MDS with nodsh"
18025         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18026                 skip "Need MDS version at least 2.3.56"
18027
18028         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18029         echo aaa > $DIR/$tdir/$tfile
18030
18031 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18032         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18033
18034         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18035         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18036
18037         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18038
18039         # Flush negative dentry cache
18040         touch $DIR/$tdir/$tfile
18041
18042         # We are not checking for any leaked references here, they'll
18043         # become evident next time we do cleanup with module unload.
18044         rm -rf $DIR/$tdir
18045 }
18046 run_test 183 "No crash or request leak in case of strange dispositions ========"
18047
18048 # test suite 184 is for LU-2016, LU-2017
18049 test_184a() {
18050         check_swap_layouts_support
18051
18052         dir0=$DIR/$tdir/$testnum
18053         test_mkdir -p -c1 $dir0
18054         ref1=/etc/passwd
18055         ref2=/etc/group
18056         file1=$dir0/f1
18057         file2=$dir0/f2
18058         $LFS setstripe -c1 $file1
18059         cp $ref1 $file1
18060         $LFS setstripe -c2 $file2
18061         cp $ref2 $file2
18062         gen1=$($LFS getstripe -g $file1)
18063         gen2=$($LFS getstripe -g $file2)
18064
18065         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18066         gen=$($LFS getstripe -g $file1)
18067         [[ $gen1 != $gen ]] ||
18068                 error "Layout generation on $file1 does not change"
18069         gen=$($LFS getstripe -g $file2)
18070         [[ $gen2 != $gen ]] ||
18071                 error "Layout generation on $file2 does not change"
18072
18073         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
18074         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18075
18076         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18077 }
18078 run_test 184a "Basic layout swap"
18079
18080 test_184b() {
18081         check_swap_layouts_support
18082
18083         dir0=$DIR/$tdir/$testnum
18084         mkdir -p $dir0 || error "creating dir $dir0"
18085         file1=$dir0/f1
18086         file2=$dir0/f2
18087         file3=$dir0/f3
18088         dir1=$dir0/d1
18089         dir2=$dir0/d2
18090         mkdir $dir1 $dir2
18091         $LFS setstripe -c1 $file1
18092         $LFS setstripe -c2 $file2
18093         $LFS setstripe -c1 $file3
18094         chown $RUNAS_ID $file3
18095         gen1=$($LFS getstripe -g $file1)
18096         gen2=$($LFS getstripe -g $file2)
18097
18098         $LFS swap_layouts $dir1 $dir2 &&
18099                 error "swap of directories layouts should fail"
18100         $LFS swap_layouts $dir1 $file1 &&
18101                 error "swap of directory and file layouts should fail"
18102         $RUNAS $LFS swap_layouts $file1 $file2 &&
18103                 error "swap of file we cannot write should fail"
18104         $LFS swap_layouts $file1 $file3 &&
18105                 error "swap of file with different owner should fail"
18106         /bin/true # to clear error code
18107 }
18108 run_test 184b "Forbidden layout swap (will generate errors)"
18109
18110 test_184c() {
18111         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18112         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18113         check_swap_layouts_support
18114         check_swap_layout_no_dom $DIR
18115
18116         local dir0=$DIR/$tdir/$testnum
18117         mkdir -p $dir0 || error "creating dir $dir0"
18118
18119         local ref1=$dir0/ref1
18120         local ref2=$dir0/ref2
18121         local file1=$dir0/file1
18122         local file2=$dir0/file2
18123         # create a file large enough for the concurrent test
18124         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18125         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18126         echo "ref file size: ref1($(stat -c %s $ref1))," \
18127              "ref2($(stat -c %s $ref2))"
18128
18129         cp $ref2 $file2
18130         dd if=$ref1 of=$file1 bs=16k &
18131         local DD_PID=$!
18132
18133         # Make sure dd starts to copy file, but wait at most 5 seconds
18134         local loops=0
18135         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18136
18137         $LFS swap_layouts $file1 $file2
18138         local rc=$?
18139         wait $DD_PID
18140         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18141         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18142
18143         # how many bytes copied before swapping layout
18144         local copied=$(stat -c %s $file2)
18145         local remaining=$(stat -c %s $ref1)
18146         remaining=$((remaining - copied))
18147         echo "Copied $copied bytes before swapping layout..."
18148
18149         cmp -n $copied $file1 $ref2 | grep differ &&
18150                 error "Content mismatch [0, $copied) of ref2 and file1"
18151         cmp -n $copied $file2 $ref1 ||
18152                 error "Content mismatch [0, $copied) of ref1 and file2"
18153         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18154                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18155
18156         # clean up
18157         rm -f $ref1 $ref2 $file1 $file2
18158 }
18159 run_test 184c "Concurrent write and layout swap"
18160
18161 test_184d() {
18162         check_swap_layouts_support
18163         check_swap_layout_no_dom $DIR
18164         [ -z "$(which getfattr 2>/dev/null)" ] &&
18165                 skip_env "no getfattr command"
18166
18167         local file1=$DIR/$tdir/$tfile-1
18168         local file2=$DIR/$tdir/$tfile-2
18169         local file3=$DIR/$tdir/$tfile-3
18170         local lovea1
18171         local lovea2
18172
18173         mkdir -p $DIR/$tdir
18174         touch $file1 || error "create $file1 failed"
18175         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18176                 error "create $file2 failed"
18177         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18178                 error "create $file3 failed"
18179         lovea1=$(get_layout_param $file1)
18180
18181         $LFS swap_layouts $file2 $file3 ||
18182                 error "swap $file2 $file3 layouts failed"
18183         $LFS swap_layouts $file1 $file2 ||
18184                 error "swap $file1 $file2 layouts failed"
18185
18186         lovea2=$(get_layout_param $file2)
18187         echo "$lovea1"
18188         echo "$lovea2"
18189         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18190
18191         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18192         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18193 }
18194 run_test 184d "allow stripeless layouts swap"
18195
18196 test_184e() {
18197         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18198                 skip "Need MDS version at least 2.6.94"
18199         check_swap_layouts_support
18200         check_swap_layout_no_dom $DIR
18201         [ -z "$(which getfattr 2>/dev/null)" ] &&
18202                 skip_env "no getfattr command"
18203
18204         local file1=$DIR/$tdir/$tfile-1
18205         local file2=$DIR/$tdir/$tfile-2
18206         local file3=$DIR/$tdir/$tfile-3
18207         local lovea
18208
18209         mkdir -p $DIR/$tdir
18210         touch $file1 || error "create $file1 failed"
18211         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18212                 error "create $file2 failed"
18213         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18214                 error "create $file3 failed"
18215
18216         $LFS swap_layouts $file1 $file2 ||
18217                 error "swap $file1 $file2 layouts failed"
18218
18219         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18220         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18221
18222         echo 123 > $file1 || error "Should be able to write into $file1"
18223
18224         $LFS swap_layouts $file1 $file3 ||
18225                 error "swap $file1 $file3 layouts failed"
18226
18227         echo 123 > $file1 || error "Should be able to write into $file1"
18228
18229         rm -rf $file1 $file2 $file3
18230 }
18231 run_test 184e "Recreate layout after stripeless layout swaps"
18232
18233 test_184f() {
18234         # Create a file with name longer than sizeof(struct stat) ==
18235         # 144 to see if we can get chars from the file name to appear
18236         # in the returned striping. Note that 'f' == 0x66.
18237         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18238
18239         mkdir -p $DIR/$tdir
18240         mcreate $DIR/$tdir/$file
18241         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18242                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18243         fi
18244 }
18245 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18246
18247 test_185() { # LU-2441
18248         # LU-3553 - no volatile file support in old servers
18249         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18250                 skip "Need MDS version at least 2.3.60"
18251
18252         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18253         touch $DIR/$tdir/spoo
18254         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18255         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18256                 error "cannot create/write a volatile file"
18257         [ "$FILESET" == "" ] &&
18258         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18259                 error "FID is still valid after close"
18260
18261         multiop_bg_pause $DIR/$tdir vVw4096_c
18262         local multi_pid=$!
18263
18264         local OLD_IFS=$IFS
18265         IFS=":"
18266         local fidv=($fid)
18267         IFS=$OLD_IFS
18268         # assume that the next FID for this client is sequential, since stdout
18269         # is unfortunately eaten by multiop_bg_pause
18270         local n=$((${fidv[1]} + 1))
18271         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18272         if [ "$FILESET" == "" ]; then
18273                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18274                         error "FID is missing before close"
18275         fi
18276         kill -USR1 $multi_pid
18277         # 1 second delay, so if mtime change we will see it
18278         sleep 1
18279         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18280         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18281 }
18282 run_test 185 "Volatile file support"
18283
18284 function create_check_volatile() {
18285         local idx=$1
18286         local tgt
18287
18288         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18289         local PID=$!
18290         sleep 1
18291         local FID=$(cat /tmp/${tfile}.fid)
18292         [ "$FID" == "" ] && error "can't get FID for volatile"
18293         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18294         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18295         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18296         kill -USR1 $PID
18297         wait
18298         sleep 1
18299         cancel_lru_locks mdc # flush opencache
18300         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18301         return 0
18302 }
18303
18304 test_185a(){
18305         # LU-12516 - volatile creation via .lustre
18306         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18307                 skip "Need MDS version at least 2.3.55"
18308
18309         create_check_volatile 0
18310         [ $MDSCOUNT -lt 2 ] && return 0
18311
18312         # DNE case
18313         create_check_volatile 1
18314
18315         return 0
18316 }
18317 run_test 185a "Volatile file creation in .lustre/fid/"
18318
18319 test_187a() {
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         local file=$dir0/file1
18328         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18329         local dv1=$($LFS data_version $file)
18330         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18331         local dv2=$($LFS data_version $file)
18332         [[ $dv1 != $dv2 ]] ||
18333                 error "data version did not change on write $dv1 == $dv2"
18334
18335         # clean up
18336         rm -f $file1
18337 }
18338 run_test 187a "Test data version change"
18339
18340 test_187b() {
18341         remote_mds_nodsh && skip "remote MDS with nodsh"
18342         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18343                 skip "Need MDS version at least 2.3.0"
18344
18345         local dir0=$DIR/$tdir/$testnum
18346         mkdir -p $dir0 || error "creating dir $dir0"
18347
18348         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18349         [[ ${DV[0]} != ${DV[1]} ]] ||
18350                 error "data version did not change on write"\
18351                       " ${DV[0]} == ${DV[1]}"
18352
18353         # clean up
18354         rm -f $file1
18355 }
18356 run_test 187b "Test data version change on volatile file"
18357
18358 test_200() {
18359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18360         remote_mgs_nodsh && skip "remote MGS with nodsh"
18361         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18362
18363         local POOL=${POOL:-cea1}
18364         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18365         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18366         # Pool OST targets
18367         local first_ost=0
18368         local last_ost=$(($OSTCOUNT - 1))
18369         local ost_step=2
18370         local ost_list=$(seq $first_ost $ost_step $last_ost)
18371         local ost_range="$first_ost $last_ost $ost_step"
18372         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18373         local file_dir=$POOL_ROOT/file_tst
18374         local subdir=$test_path/subdir
18375         local rc=0
18376
18377         while : ; do
18378                 # former test_200a test_200b
18379                 pool_add $POOL                          || { rc=$? ; break; }
18380                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18381                 # former test_200c test_200d
18382                 mkdir -p $test_path
18383                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18384                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18385                 mkdir -p $subdir
18386                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18387                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18388                                                         || { rc=$? ; break; }
18389                 # former test_200e test_200f
18390                 local files=$((OSTCOUNT*3))
18391                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18392                                                         || { rc=$? ; break; }
18393                 pool_create_files $POOL $file_dir $files "$ost_list" \
18394                                                         || { rc=$? ; break; }
18395                 # former test_200g test_200h
18396                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18397                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18398
18399                 # former test_201a test_201b test_201c
18400                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18401
18402                 local f=$test_path/$tfile
18403                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18404                 pool_remove $POOL $f                    || { rc=$? ; break; }
18405                 break
18406         done
18407
18408         destroy_test_pools
18409
18410         return $rc
18411 }
18412 run_test 200 "OST pools"
18413
18414 # usage: default_attr <count | size | offset>
18415 default_attr() {
18416         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18417 }
18418
18419 # usage: check_default_stripe_attr
18420 check_default_stripe_attr() {
18421         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18422         case $1 in
18423         --stripe-count|-c)
18424                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18425         --stripe-size|-S)
18426                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18427         --stripe-index|-i)
18428                 EXPECTED=-1;;
18429         *)
18430                 error "unknown getstripe attr '$1'"
18431         esac
18432
18433         [ $ACTUAL == $EXPECTED ] ||
18434                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18435 }
18436
18437 test_204a() {
18438         test_mkdir $DIR/$tdir
18439         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18440
18441         check_default_stripe_attr --stripe-count
18442         check_default_stripe_attr --stripe-size
18443         check_default_stripe_attr --stripe-index
18444 }
18445 run_test 204a "Print default stripe attributes"
18446
18447 test_204b() {
18448         test_mkdir $DIR/$tdir
18449         $LFS setstripe --stripe-count 1 $DIR/$tdir
18450
18451         check_default_stripe_attr --stripe-size
18452         check_default_stripe_attr --stripe-index
18453 }
18454 run_test 204b "Print default stripe size and offset"
18455
18456 test_204c() {
18457         test_mkdir $DIR/$tdir
18458         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18459
18460         check_default_stripe_attr --stripe-count
18461         check_default_stripe_attr --stripe-index
18462 }
18463 run_test 204c "Print default stripe count and offset"
18464
18465 test_204d() {
18466         test_mkdir $DIR/$tdir
18467         $LFS setstripe --stripe-index 0 $DIR/$tdir
18468
18469         check_default_stripe_attr --stripe-count
18470         check_default_stripe_attr --stripe-size
18471 }
18472 run_test 204d "Print default stripe count and size"
18473
18474 test_204e() {
18475         test_mkdir $DIR/$tdir
18476         $LFS setstripe -d $DIR/$tdir
18477
18478         check_default_stripe_attr --stripe-count --raw
18479         check_default_stripe_attr --stripe-size --raw
18480         check_default_stripe_attr --stripe-index --raw
18481 }
18482 run_test 204e "Print raw stripe attributes"
18483
18484 test_204f() {
18485         test_mkdir $DIR/$tdir
18486         $LFS setstripe --stripe-count 1 $DIR/$tdir
18487
18488         check_default_stripe_attr --stripe-size --raw
18489         check_default_stripe_attr --stripe-index --raw
18490 }
18491 run_test 204f "Print raw stripe size and offset"
18492
18493 test_204g() {
18494         test_mkdir $DIR/$tdir
18495         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18496
18497         check_default_stripe_attr --stripe-count --raw
18498         check_default_stripe_attr --stripe-index --raw
18499 }
18500 run_test 204g "Print raw stripe count and offset"
18501
18502 test_204h() {
18503         test_mkdir $DIR/$tdir
18504         $LFS setstripe --stripe-index 0 $DIR/$tdir
18505
18506         check_default_stripe_attr --stripe-count --raw
18507         check_default_stripe_attr --stripe-size --raw
18508 }
18509 run_test 204h "Print raw stripe count and size"
18510
18511 # Figure out which job scheduler is being used, if any,
18512 # or use a fake one
18513 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18514         JOBENV=SLURM_JOB_ID
18515 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18516         JOBENV=LSB_JOBID
18517 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18518         JOBENV=PBS_JOBID
18519 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18520         JOBENV=LOADL_STEP_ID
18521 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18522         JOBENV=JOB_ID
18523 else
18524         $LCTL list_param jobid_name > /dev/null 2>&1
18525         if [ $? -eq 0 ]; then
18526                 JOBENV=nodelocal
18527         else
18528                 JOBENV=FAKE_JOBID
18529         fi
18530 fi
18531 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18532
18533 verify_jobstats() {
18534         local cmd=($1)
18535         shift
18536         local facets="$@"
18537
18538 # we don't really need to clear the stats for this test to work, since each
18539 # command has a unique jobid, but it makes debugging easier if needed.
18540 #       for facet in $facets; do
18541 #               local dev=$(convert_facet2label $facet)
18542 #               # clear old jobstats
18543 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18544 #       done
18545
18546         # use a new JobID for each test, or we might see an old one
18547         [ "$JOBENV" = "FAKE_JOBID" ] &&
18548                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18549
18550         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18551
18552         [ "$JOBENV" = "nodelocal" ] && {
18553                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18554                 $LCTL set_param jobid_name=$FAKE_JOBID
18555                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18556         }
18557
18558         log "Test: ${cmd[*]}"
18559         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18560
18561         if [ $JOBENV = "FAKE_JOBID" ]; then
18562                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18563         else
18564                 ${cmd[*]}
18565         fi
18566
18567         # all files are created on OST0000
18568         for facet in $facets; do
18569                 local stats="*.$(convert_facet2label $facet).job_stats"
18570
18571                 # strip out libtool wrappers for in-tree executables
18572                 if (( $(do_facet $facet lctl get_param $stats |
18573                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18574                         do_facet $facet lctl get_param $stats
18575                         error "No jobstats for $JOBVAL found on $facet::$stats"
18576                 fi
18577         done
18578 }
18579
18580 jobstats_set() {
18581         local new_jobenv=$1
18582
18583         set_persistent_param_and_check client "jobid_var" \
18584                 "$FSNAME.sys.jobid_var" $new_jobenv
18585 }
18586
18587 test_205a() { # Job stats
18588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18589         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18590                 skip "Need MDS version with at least 2.7.1"
18591         remote_mgs_nodsh && skip "remote MGS with nodsh"
18592         remote_mds_nodsh && skip "remote MDS with nodsh"
18593         remote_ost_nodsh && skip "remote OST with nodsh"
18594         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18595                 skip "Server doesn't support jobstats"
18596         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18597
18598         local old_jobenv=$($LCTL get_param -n jobid_var)
18599         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18600
18601         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18602                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18603         else
18604                 stack_trap "do_facet mgs $PERM_CMD \
18605                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18606         fi
18607         changelog_register
18608
18609         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18610                                 mdt.*.job_cleanup_interval | head -n 1)
18611         local new_interval=5
18612         do_facet $SINGLEMDS \
18613                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18614         stack_trap "do_facet $SINGLEMDS \
18615                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18616         local start=$SECONDS
18617
18618         local cmd
18619         # mkdir
18620         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18621         verify_jobstats "$cmd" "$SINGLEMDS"
18622         # rmdir
18623         cmd="rmdir $DIR/$tdir"
18624         verify_jobstats "$cmd" "$SINGLEMDS"
18625         # mkdir on secondary MDT
18626         if [ $MDSCOUNT -gt 1 ]; then
18627                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18628                 verify_jobstats "$cmd" "mds2"
18629         fi
18630         # mknod
18631         cmd="mknod $DIR/$tfile c 1 3"
18632         verify_jobstats "$cmd" "$SINGLEMDS"
18633         # unlink
18634         cmd="rm -f $DIR/$tfile"
18635         verify_jobstats "$cmd" "$SINGLEMDS"
18636         # create all files on OST0000 so verify_jobstats can find OST stats
18637         # open & close
18638         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18639         verify_jobstats "$cmd" "$SINGLEMDS"
18640         # setattr
18641         cmd="touch $DIR/$tfile"
18642         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18643         # write
18644         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18645         verify_jobstats "$cmd" "ost1"
18646         # read
18647         cancel_lru_locks osc
18648         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18649         verify_jobstats "$cmd" "ost1"
18650         # truncate
18651         cmd="$TRUNCATE $DIR/$tfile 0"
18652         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18653         # rename
18654         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18655         verify_jobstats "$cmd" "$SINGLEMDS"
18656         # jobstats expiry - sleep until old stats should be expired
18657         local left=$((new_interval + 5 - (SECONDS - start)))
18658         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18659                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18660                         "0" $left
18661         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18662         verify_jobstats "$cmd" "$SINGLEMDS"
18663         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18664             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18665
18666         # Ensure that jobid are present in changelog (if supported by MDS)
18667         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18668                 changelog_dump | tail -10
18669                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18670                 [ $jobids -eq 9 ] ||
18671                         error "Wrong changelog jobid count $jobids != 9"
18672
18673                 # LU-5862
18674                 JOBENV="disable"
18675                 jobstats_set $JOBENV
18676                 touch $DIR/$tfile
18677                 changelog_dump | grep $tfile
18678                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18679                 [ $jobids -eq 0 ] ||
18680                         error "Unexpected jobids when jobid_var=$JOBENV"
18681         fi
18682
18683         # test '%j' access to environment variable - if supported
18684         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18685                 JOBENV="JOBCOMPLEX"
18686                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18687
18688                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18689         fi
18690
18691         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18692                 JOBENV="JOBCOMPLEX"
18693                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18694
18695                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18696         fi
18697
18698         # test '%j' access to per-session jobid - if supported
18699         if lctl list_param jobid_this_session > /dev/null 2>&1
18700         then
18701                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18702                 lctl set_param jobid_this_session=$USER
18703
18704                 JOBENV="JOBCOMPLEX"
18705                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18706
18707                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18708         fi
18709 }
18710 run_test 205a "Verify job stats"
18711
18712 # LU-13117, LU-13597
18713 test_205b() {
18714         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18715                 skip "Need MDS version at least 2.13.54.91"
18716
18717         job_stats="mdt.*.job_stats"
18718         $LCTL set_param $job_stats=clear
18719         # Setting jobid_var to USER might not be supported
18720         $LCTL set_param jobid_var=USER || true
18721         $LCTL set_param jobid_name="%e.%u"
18722         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18723         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18724                 grep "job_id:.*foolish" &&
18725                         error "Unexpected jobid found"
18726         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18727                 grep "open:.*min.*max.*sum" ||
18728                         error "wrong job_stats format found"
18729 }
18730 run_test 205b "Verify job stats jobid and output format"
18731
18732 # LU-13733
18733 test_205c() {
18734         $LCTL set_param llite.*.stats=0
18735         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18736         $LCTL get_param llite.*.stats
18737         $LCTL get_param llite.*.stats | grep \
18738                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18739                         error "wrong client stats format found"
18740 }
18741 run_test 205c "Verify client stats format"
18742
18743 # LU-1480, LU-1773 and LU-1657
18744 test_206() {
18745         mkdir -p $DIR/$tdir
18746         $LFS setstripe -c -1 $DIR/$tdir
18747 #define OBD_FAIL_LOV_INIT 0x1403
18748         $LCTL set_param fail_loc=0xa0001403
18749         $LCTL set_param fail_val=1
18750         touch $DIR/$tdir/$tfile || true
18751 }
18752 run_test 206 "fail lov_init_raid0() doesn't lbug"
18753
18754 test_207a() {
18755         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18756         local fsz=`stat -c %s $DIR/$tfile`
18757         cancel_lru_locks mdc
18758
18759         # do not return layout in getattr intent
18760 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18761         $LCTL set_param fail_loc=0x170
18762         local sz=`stat -c %s $DIR/$tfile`
18763
18764         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18765
18766         rm -rf $DIR/$tfile
18767 }
18768 run_test 207a "can refresh layout at glimpse"
18769
18770 test_207b() {
18771         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18772         local cksum=`md5sum $DIR/$tfile`
18773         local fsz=`stat -c %s $DIR/$tfile`
18774         cancel_lru_locks mdc
18775         cancel_lru_locks osc
18776
18777         # do not return layout in getattr intent
18778 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18779         $LCTL set_param fail_loc=0x171
18780
18781         # it will refresh layout after the file is opened but before read issues
18782         echo checksum is "$cksum"
18783         echo "$cksum" |md5sum -c --quiet || error "file differs"
18784
18785         rm -rf $DIR/$tfile
18786 }
18787 run_test 207b "can refresh layout at open"
18788
18789 test_208() {
18790         # FIXME: in this test suite, only RD lease is used. This is okay
18791         # for now as only exclusive open is supported. After generic lease
18792         # is done, this test suite should be revised. - Jinshan
18793
18794         remote_mds_nodsh && skip "remote MDS with nodsh"
18795         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18796                 skip "Need MDS version at least 2.4.52"
18797
18798         echo "==== test 1: verify get lease work"
18799         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18800
18801         echo "==== test 2: verify lease can be broken by upcoming open"
18802         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18803         local PID=$!
18804         sleep 2
18805
18806         $MULTIOP $DIR/$tfile oO_RDWR:c
18807         kill -USR1 $PID && wait $PID || error "break lease error"
18808
18809         echo "==== test 3: verify lease can't be granted if an open already exists"
18810         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18811         local PID=$!
18812         sleep 2
18813
18814         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18815         kill -USR1 $PID && wait $PID || error "open file error"
18816
18817         echo "==== test 4: lease can sustain over recovery"
18818         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18819         PID=$!
18820         sleep 2
18821
18822         fail mds1
18823
18824         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18825
18826         echo "==== test 5: lease broken can't be regained by replay"
18827         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18828         PID=$!
18829         sleep 2
18830
18831         # open file to break lease and then recovery
18832         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18833         fail mds1
18834
18835         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18836
18837         rm -f $DIR/$tfile
18838 }
18839 run_test 208 "Exclusive open"
18840
18841 test_209() {
18842         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18843                 skip_env "must have disp_stripe"
18844
18845         touch $DIR/$tfile
18846         sync; sleep 5; sync;
18847
18848         echo 3 > /proc/sys/vm/drop_caches
18849         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18850                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18851         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18852
18853         # open/close 500 times
18854         for i in $(seq 500); do
18855                 cat $DIR/$tfile
18856         done
18857
18858         echo 3 > /proc/sys/vm/drop_caches
18859         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18860                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18861         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18862
18863         echo "before: $req_before, after: $req_after"
18864         [ $((req_after - req_before)) -ge 300 ] &&
18865                 error "open/close requests are not freed"
18866         return 0
18867 }
18868 run_test 209 "read-only open/close requests should be freed promptly"
18869
18870 test_210() {
18871         local pid
18872
18873         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18874         pid=$!
18875         sleep 1
18876
18877         $LFS getstripe $DIR/$tfile
18878         kill -USR1 $pid
18879         wait $pid || error "multiop failed"
18880
18881         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18882         pid=$!
18883         sleep 1
18884
18885         $LFS getstripe $DIR/$tfile
18886         kill -USR1 $pid
18887         wait $pid || error "multiop failed"
18888 }
18889 run_test 210 "lfs getstripe does not break leases"
18890
18891 test_212() {
18892         size=`date +%s`
18893         size=$((size % 8192 + 1))
18894         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18895         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18896         rm -f $DIR/f212 $DIR/f212.xyz
18897 }
18898 run_test 212 "Sendfile test ============================================"
18899
18900 test_213() {
18901         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18902         cancel_lru_locks osc
18903         lctl set_param fail_loc=0x8000040f
18904         # generate a read lock
18905         cat $DIR/$tfile > /dev/null
18906         # write to the file, it will try to cancel the above read lock.
18907         cat /etc/hosts >> $DIR/$tfile
18908 }
18909 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18910
18911 test_214() { # for bug 20133
18912         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18913         for (( i=0; i < 340; i++ )) ; do
18914                 touch $DIR/$tdir/d214c/a$i
18915         done
18916
18917         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18918         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18919         ls $DIR/d214c || error "ls $DIR/d214c failed"
18920         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18921         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18922 }
18923 run_test 214 "hash-indexed directory test - bug 20133"
18924
18925 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18926 create_lnet_proc_files() {
18927         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18928 }
18929
18930 # counterpart of create_lnet_proc_files
18931 remove_lnet_proc_files() {
18932         rm -f $TMP/lnet_$1.sys
18933 }
18934
18935 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18936 # 3rd arg as regexp for body
18937 check_lnet_proc_stats() {
18938         local l=$(cat "$TMP/lnet_$1" |wc -l)
18939         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18940
18941         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18942 }
18943
18944 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18945 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18946 # optional and can be regexp for 2nd line (lnet.routes case)
18947 check_lnet_proc_entry() {
18948         local blp=2          # blp stands for 'position of 1st line of body'
18949         [ -z "$5" ] || blp=3 # lnet.routes case
18950
18951         local l=$(cat "$TMP/lnet_$1" |wc -l)
18952         # subtracting one from $blp because the body can be empty
18953         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18954
18955         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18956                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18957
18958         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18959                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18960
18961         # bail out if any unexpected line happened
18962         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18963         [ "$?" != 0 ] || error "$2 misformatted"
18964 }
18965
18966 test_215() { # for bugs 18102, 21079, 21517
18967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18968
18969         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18970         local P='[1-9][0-9]*'           # positive numeric
18971         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18972         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18973         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18974         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18975
18976         local L1 # regexp for 1st line
18977         local L2 # regexp for 2nd line (optional)
18978         local BR # regexp for the rest (body)
18979
18980         # lnet.stats should look as 11 space-separated non-negative numerics
18981         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18982         create_lnet_proc_files "stats"
18983         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18984         remove_lnet_proc_files "stats"
18985
18986         # lnet.routes should look like this:
18987         # Routing disabled/enabled
18988         # net hops priority state router
18989         # where net is a string like tcp0, hops > 0, priority >= 0,
18990         # state is up/down,
18991         # router is a string like 192.168.1.1@tcp2
18992         L1="^Routing (disabled|enabled)$"
18993         L2="^net +hops +priority +state +router$"
18994         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18995         create_lnet_proc_files "routes"
18996         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18997         remove_lnet_proc_files "routes"
18998
18999         # lnet.routers should look like this:
19000         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
19001         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
19002         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
19003         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
19004         L1="^ref +rtr_ref +alive +router$"
19005         BR="^$P +$P +(up|down) +$NID$"
19006         create_lnet_proc_files "routers"
19007         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
19008         remove_lnet_proc_files "routers"
19009
19010         # lnet.peers should look like this:
19011         # nid refs state last max rtr min tx min queue
19012         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
19013         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
19014         # numeric (0 or >0 or <0), queue >= 0.
19015         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
19016         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
19017         create_lnet_proc_files "peers"
19018         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
19019         remove_lnet_proc_files "peers"
19020
19021         # lnet.buffers  should look like this:
19022         # pages count credits min
19023         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
19024         L1="^pages +count +credits +min$"
19025         BR="^ +$N +$N +$I +$I$"
19026         create_lnet_proc_files "buffers"
19027         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
19028         remove_lnet_proc_files "buffers"
19029
19030         # lnet.nis should look like this:
19031         # nid status alive refs peer rtr max tx min
19032         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
19033         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
19034         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
19035         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
19036         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
19037         create_lnet_proc_files "nis"
19038         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
19039         remove_lnet_proc_files "nis"
19040
19041         # can we successfully write to lnet.stats?
19042         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
19043 }
19044 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
19045
19046 test_216() { # bug 20317
19047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19048         remote_ost_nodsh && skip "remote OST with nodsh"
19049
19050         local node
19051         local facets=$(get_facets OST)
19052         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19053
19054         save_lustre_params client "osc.*.contention_seconds" > $p
19055         save_lustre_params $facets \
19056                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
19057         save_lustre_params $facets \
19058                 "ldlm.namespaces.filter-*.contended_locks" >> $p
19059         save_lustre_params $facets \
19060                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
19061         clear_stats osc.*.osc_stats
19062
19063         # agressive lockless i/o settings
19064         do_nodes $(comma_list $(osts_nodes)) \
19065                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
19066                         ldlm.namespaces.filter-*.contended_locks=0 \
19067                         ldlm.namespaces.filter-*.contention_seconds=60"
19068         lctl set_param -n osc.*.contention_seconds=60
19069
19070         $DIRECTIO write $DIR/$tfile 0 10 4096
19071         $CHECKSTAT -s 40960 $DIR/$tfile
19072
19073         # disable lockless i/o
19074         do_nodes $(comma_list $(osts_nodes)) \
19075                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
19076                         ldlm.namespaces.filter-*.contended_locks=32 \
19077                         ldlm.namespaces.filter-*.contention_seconds=0"
19078         lctl set_param -n osc.*.contention_seconds=0
19079         clear_stats osc.*.osc_stats
19080
19081         dd if=/dev/zero of=$DIR/$tfile count=0
19082         $CHECKSTAT -s 0 $DIR/$tfile
19083
19084         restore_lustre_params <$p
19085         rm -f $p
19086         rm $DIR/$tfile
19087 }
19088 run_test 216 "check lockless direct write updates file size and kms correctly"
19089
19090 test_217() { # bug 22430
19091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19092
19093         local node
19094         local nid
19095
19096         for node in $(nodes_list); do
19097                 nid=$(host_nids_address $node $NETTYPE)
19098                 if [[ $nid = *-* ]] ; then
19099                         echo "lctl ping $(h2nettype $nid)"
19100                         lctl ping $(h2nettype $nid)
19101                 else
19102                         echo "skipping $node (no hyphen detected)"
19103                 fi
19104         done
19105 }
19106 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19107
19108 test_218() {
19109        # do directio so as not to populate the page cache
19110        log "creating a 10 Mb file"
19111        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19112        log "starting reads"
19113        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19114        log "truncating the file"
19115        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19116        log "killing dd"
19117        kill %+ || true # reads might have finished
19118        echo "wait until dd is finished"
19119        wait
19120        log "removing the temporary file"
19121        rm -rf $DIR/$tfile || error "tmp file removal failed"
19122 }
19123 run_test 218 "parallel read and truncate should not deadlock"
19124
19125 test_219() {
19126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19127
19128         # write one partial page
19129         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19130         # set no grant so vvp_io_commit_write will do sync write
19131         $LCTL set_param fail_loc=0x411
19132         # write a full page at the end of file
19133         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19134
19135         $LCTL set_param fail_loc=0
19136         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19137         $LCTL set_param fail_loc=0x411
19138         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19139
19140         # LU-4201
19141         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19142         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19143 }
19144 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19145
19146 test_220() { #LU-325
19147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19148         remote_ost_nodsh && skip "remote OST with nodsh"
19149         remote_mds_nodsh && skip "remote MDS with nodsh"
19150         remote_mgs_nodsh && skip "remote MGS with nodsh"
19151
19152         local OSTIDX=0
19153
19154         # create on MDT0000 so the last_id and next_id are correct
19155         mkdir_on_mdt0 $DIR/$tdir
19156         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19157         OST=${OST%_UUID}
19158
19159         # on the mdt's osc
19160         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19161         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19162                         osp.$mdtosc_proc1.prealloc_last_id)
19163         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19164                         osp.$mdtosc_proc1.prealloc_next_id)
19165
19166         $LFS df -i
19167
19168         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19169         #define OBD_FAIL_OST_ENOINO              0x229
19170         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19171         create_pool $FSNAME.$TESTNAME || return 1
19172         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19173
19174         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19175
19176         MDSOBJS=$((last_id - next_id))
19177         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19178
19179         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19180         echo "OST still has $count kbytes free"
19181
19182         echo "create $MDSOBJS files @next_id..."
19183         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19184
19185         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19186                         osp.$mdtosc_proc1.prealloc_last_id)
19187         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19188                         osp.$mdtosc_proc1.prealloc_next_id)
19189
19190         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19191         $LFS df -i
19192
19193         echo "cleanup..."
19194
19195         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19196         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19197
19198         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19199                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19200         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19201                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19202         echo "unlink $MDSOBJS files @$next_id..."
19203         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19204 }
19205 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19206
19207 test_221() {
19208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19209
19210         dd if=`which date` of=$MOUNT/date oflag=sync
19211         chmod +x $MOUNT/date
19212
19213         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19214         $LCTL set_param fail_loc=0x80001401
19215
19216         $MOUNT/date > /dev/null
19217         rm -f $MOUNT/date
19218 }
19219 run_test 221 "make sure fault and truncate race to not cause OOM"
19220
19221 test_222a () {
19222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19223
19224         rm -rf $DIR/$tdir
19225         test_mkdir $DIR/$tdir
19226         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19227         createmany -o $DIR/$tdir/$tfile 10
19228         cancel_lru_locks mdc
19229         cancel_lru_locks osc
19230         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19231         $LCTL set_param fail_loc=0x31a
19232         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19233         $LCTL set_param fail_loc=0
19234         rm -r $DIR/$tdir
19235 }
19236 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19237
19238 test_222b () {
19239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19240
19241         rm -rf $DIR/$tdir
19242         test_mkdir $DIR/$tdir
19243         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19244         createmany -o $DIR/$tdir/$tfile 10
19245         cancel_lru_locks mdc
19246         cancel_lru_locks osc
19247         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19248         $LCTL set_param fail_loc=0x31a
19249         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19250         $LCTL set_param fail_loc=0
19251 }
19252 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19253
19254 test_223 () {
19255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19256
19257         rm -rf $DIR/$tdir
19258         test_mkdir $DIR/$tdir
19259         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19260         createmany -o $DIR/$tdir/$tfile 10
19261         cancel_lru_locks mdc
19262         cancel_lru_locks osc
19263         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19264         $LCTL set_param fail_loc=0x31b
19265         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19266         $LCTL set_param fail_loc=0
19267         rm -r $DIR/$tdir
19268 }
19269 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19270
19271 test_224a() { # LU-1039, MRP-303
19272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19273         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19274         $LCTL set_param fail_loc=0x508
19275         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19276         $LCTL set_param fail_loc=0
19277         df $DIR
19278 }
19279 run_test 224a "Don't panic on bulk IO failure"
19280
19281 test_224bd_sub() { # LU-1039, MRP-303
19282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19283         local timeout=$1
19284
19285         shift
19286         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19287
19288         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19289
19290         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19291         cancel_lru_locks osc
19292         set_checksums 0
19293         stack_trap "set_checksums $ORIG_CSUM" EXIT
19294         local at_max_saved=0
19295
19296         # adaptive timeouts may prevent seeing the issue
19297         if at_is_enabled; then
19298                 at_max_saved=$(at_max_get mds)
19299                 at_max_set 0 mds client
19300                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19301         fi
19302
19303         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19304         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19305         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19306
19307         do_facet ost1 $LCTL set_param fail_loc=0
19308         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19309         df $DIR
19310 }
19311
19312 test_224b() {
19313         test_224bd_sub 3 error "dd failed"
19314 }
19315 run_test 224b "Don't panic on bulk IO failure"
19316
19317 test_224c() { # LU-6441
19318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19319         remote_mds_nodsh && skip "remote MDS with nodsh"
19320
19321         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19322         save_writethrough $p
19323         set_cache writethrough on
19324
19325         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19326         local at_max=$($LCTL get_param -n at_max)
19327         local timeout=$($LCTL get_param -n timeout)
19328         local test_at="at_max"
19329         local param_at="$FSNAME.sys.at_max"
19330         local test_timeout="timeout"
19331         local param_timeout="$FSNAME.sys.timeout"
19332
19333         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19334
19335         set_persistent_param_and_check client "$test_at" "$param_at" 0
19336         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19337
19338         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19339         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19340         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19341         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19342         sync
19343         do_facet ost1 "$LCTL set_param fail_loc=0"
19344
19345         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19346         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19347                 $timeout
19348
19349         $LCTL set_param -n $pages_per_rpc
19350         restore_lustre_params < $p
19351         rm -f $p
19352 }
19353 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19354
19355 test_224d() { # LU-11169
19356         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19357 }
19358 run_test 224d "Don't corrupt data on bulk IO timeout"
19359
19360 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19361 test_225a () {
19362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19363         if [ -z ${MDSSURVEY} ]; then
19364                 skip_env "mds-survey not found"
19365         fi
19366         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19367                 skip "Need MDS version at least 2.2.51"
19368
19369         local mds=$(facet_host $SINGLEMDS)
19370         local target=$(do_nodes $mds 'lctl dl' |
19371                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19372
19373         local cmd1="file_count=1000 thrhi=4"
19374         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19375         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19376         local cmd="$cmd1 $cmd2 $cmd3"
19377
19378         rm -f ${TMP}/mds_survey*
19379         echo + $cmd
19380         eval $cmd || error "mds-survey with zero-stripe failed"
19381         cat ${TMP}/mds_survey*
19382         rm -f ${TMP}/mds_survey*
19383 }
19384 run_test 225a "Metadata survey sanity with zero-stripe"
19385
19386 test_225b () {
19387         if [ -z ${MDSSURVEY} ]; then
19388                 skip_env "mds-survey not found"
19389         fi
19390         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19391                 skip "Need MDS version at least 2.2.51"
19392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19393         remote_mds_nodsh && skip "remote MDS with nodsh"
19394         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19395                 skip_env "Need to mount OST to test"
19396         fi
19397
19398         local mds=$(facet_host $SINGLEMDS)
19399         local target=$(do_nodes $mds 'lctl dl' |
19400                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19401
19402         local cmd1="file_count=1000 thrhi=4"
19403         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19404         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19405         local cmd="$cmd1 $cmd2 $cmd3"
19406
19407         rm -f ${TMP}/mds_survey*
19408         echo + $cmd
19409         eval $cmd || error "mds-survey with stripe_count failed"
19410         cat ${TMP}/mds_survey*
19411         rm -f ${TMP}/mds_survey*
19412 }
19413 run_test 225b "Metadata survey sanity with stripe_count = 1"
19414
19415 mcreate_path2fid () {
19416         local mode=$1
19417         local major=$2
19418         local minor=$3
19419         local name=$4
19420         local desc=$5
19421         local path=$DIR/$tdir/$name
19422         local fid
19423         local rc
19424         local fid_path
19425
19426         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19427                 error "cannot create $desc"
19428
19429         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19430         rc=$?
19431         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19432
19433         fid_path=$($LFS fid2path $MOUNT $fid)
19434         rc=$?
19435         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19436
19437         [ "$path" == "$fid_path" ] ||
19438                 error "fid2path returned $fid_path, expected $path"
19439
19440         echo "pass with $path and $fid"
19441 }
19442
19443 test_226a () {
19444         rm -rf $DIR/$tdir
19445         mkdir -p $DIR/$tdir
19446
19447         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19448         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19449         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19450         mcreate_path2fid 0040666 0 0 dir "directory"
19451         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19452         mcreate_path2fid 0100666 0 0 file "regular file"
19453         mcreate_path2fid 0120666 0 0 link "symbolic link"
19454         mcreate_path2fid 0140666 0 0 sock "socket"
19455 }
19456 run_test 226a "call path2fid and fid2path on files of all type"
19457
19458 test_226b () {
19459         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19460
19461         local MDTIDX=1
19462
19463         rm -rf $DIR/$tdir
19464         mkdir -p $DIR/$tdir
19465         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19466                 error "create remote directory failed"
19467         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19468         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19469                                 "character special file (null)"
19470         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19471                                 "character special file (no device)"
19472         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19473         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19474                                 "block special file (loop)"
19475         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19476         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19477         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19478 }
19479 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19480
19481 test_226c () {
19482         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19483         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19484                 skip "Need MDS version at least 2.13.55"
19485
19486         local submnt=/mnt/submnt
19487         local srcfile=/etc/passwd
19488         local dstfile=$submnt/passwd
19489         local path
19490         local fid
19491
19492         rm -rf $DIR/$tdir
19493         rm -rf $submnt
19494         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19495                 error "create remote directory failed"
19496         mkdir -p $submnt || error "create $submnt failed"
19497         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19498                 error "mount $submnt failed"
19499         stack_trap "umount $submnt" EXIT
19500
19501         cp $srcfile $dstfile
19502         fid=$($LFS path2fid $dstfile)
19503         path=$($LFS fid2path $submnt "$fid")
19504         [ "$path" = "$dstfile" ] ||
19505                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19506 }
19507 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19508
19509 # LU-1299 Executing or running ldd on a truncated executable does not
19510 # cause an out-of-memory condition.
19511 test_227() {
19512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19513         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19514
19515         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19516         chmod +x $MOUNT/date
19517
19518         $MOUNT/date > /dev/null
19519         ldd $MOUNT/date > /dev/null
19520         rm -f $MOUNT/date
19521 }
19522 run_test 227 "running truncated executable does not cause OOM"
19523
19524 # LU-1512 try to reuse idle OI blocks
19525 test_228a() {
19526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19527         remote_mds_nodsh && skip "remote MDS with nodsh"
19528         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19529
19530         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19531         local myDIR=$DIR/$tdir
19532
19533         mkdir -p $myDIR
19534         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19535         $LCTL set_param fail_loc=0x80001002
19536         createmany -o $myDIR/t- 10000
19537         $LCTL set_param fail_loc=0
19538         # The guard is current the largest FID holder
19539         touch $myDIR/guard
19540         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19541                     tr -d '[')
19542         local IDX=$(($SEQ % 64))
19543
19544         do_facet $SINGLEMDS sync
19545         # Make sure journal flushed.
19546         sleep 6
19547         local blk1=$(do_facet $SINGLEMDS \
19548                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19549                      grep Blockcount | awk '{print $4}')
19550
19551         # Remove old files, some OI blocks will become idle.
19552         unlinkmany $myDIR/t- 10000
19553         # Create new files, idle OI blocks should be reused.
19554         createmany -o $myDIR/t- 2000
19555         do_facet $SINGLEMDS sync
19556         # Make sure journal flushed.
19557         sleep 6
19558         local blk2=$(do_facet $SINGLEMDS \
19559                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19560                      grep Blockcount | awk '{print $4}')
19561
19562         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19563 }
19564 run_test 228a "try to reuse idle OI blocks"
19565
19566 test_228b() {
19567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19568         remote_mds_nodsh && skip "remote MDS with nodsh"
19569         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19570
19571         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19572         local myDIR=$DIR/$tdir
19573
19574         mkdir -p $myDIR
19575         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19576         $LCTL set_param fail_loc=0x80001002
19577         createmany -o $myDIR/t- 10000
19578         $LCTL set_param fail_loc=0
19579         # The guard is current the largest FID holder
19580         touch $myDIR/guard
19581         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19582                     tr -d '[')
19583         local IDX=$(($SEQ % 64))
19584
19585         do_facet $SINGLEMDS sync
19586         # Make sure journal flushed.
19587         sleep 6
19588         local blk1=$(do_facet $SINGLEMDS \
19589                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19590                      grep Blockcount | awk '{print $4}')
19591
19592         # Remove old files, some OI blocks will become idle.
19593         unlinkmany $myDIR/t- 10000
19594
19595         # stop the MDT
19596         stop $SINGLEMDS || error "Fail to stop MDT."
19597         # remount the MDT
19598         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
19599                 error "Fail to start MDT."
19600
19601         df $MOUNT || error "Fail to df."
19602         # Create new files, idle OI blocks should be reused.
19603         createmany -o $myDIR/t- 2000
19604         do_facet $SINGLEMDS sync
19605         # Make sure journal flushed.
19606         sleep 6
19607         local blk2=$(do_facet $SINGLEMDS \
19608                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19609                      grep Blockcount | awk '{print $4}')
19610
19611         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19612 }
19613 run_test 228b "idle OI blocks can be reused after MDT restart"
19614
19615 #LU-1881
19616 test_228c() {
19617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19618         remote_mds_nodsh && skip "remote MDS with nodsh"
19619         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19620
19621         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19622         local myDIR=$DIR/$tdir
19623
19624         mkdir -p $myDIR
19625         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19626         $LCTL set_param fail_loc=0x80001002
19627         # 20000 files can guarantee there are index nodes in the OI file
19628         createmany -o $myDIR/t- 20000
19629         $LCTL set_param fail_loc=0
19630         # The guard is current the largest FID holder
19631         touch $myDIR/guard
19632         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19633                     tr -d '[')
19634         local IDX=$(($SEQ % 64))
19635
19636         do_facet $SINGLEMDS sync
19637         # Make sure journal flushed.
19638         sleep 6
19639         local blk1=$(do_facet $SINGLEMDS \
19640                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19641                      grep Blockcount | awk '{print $4}')
19642
19643         # Remove old files, some OI blocks will become idle.
19644         unlinkmany $myDIR/t- 20000
19645         rm -f $myDIR/guard
19646         # The OI file should become empty now
19647
19648         # Create new files, idle OI blocks should be reused.
19649         createmany -o $myDIR/t- 2000
19650         do_facet $SINGLEMDS sync
19651         # Make sure journal flushed.
19652         sleep 6
19653         local blk2=$(do_facet $SINGLEMDS \
19654                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19655                      grep Blockcount | awk '{print $4}')
19656
19657         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19658 }
19659 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19660
19661 test_229() { # LU-2482, LU-3448
19662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19663         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19664         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19665                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19666
19667         rm -f $DIR/$tfile
19668
19669         # Create a file with a released layout and stripe count 2.
19670         $MULTIOP $DIR/$tfile H2c ||
19671                 error "failed to create file with released layout"
19672
19673         $LFS getstripe -v $DIR/$tfile
19674
19675         local pattern=$($LFS getstripe -L $DIR/$tfile)
19676         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19677
19678         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19679                 error "getstripe"
19680         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19681         stat $DIR/$tfile || error "failed to stat released file"
19682
19683         chown $RUNAS_ID $DIR/$tfile ||
19684                 error "chown $RUNAS_ID $DIR/$tfile failed"
19685
19686         chgrp $RUNAS_ID $DIR/$tfile ||
19687                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19688
19689         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19690         rm $DIR/$tfile || error "failed to remove released file"
19691 }
19692 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19693
19694 test_230a() {
19695         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19696         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19697         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19698                 skip "Need MDS version at least 2.11.52"
19699
19700         local MDTIDX=1
19701
19702         test_mkdir $DIR/$tdir
19703         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19704         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19705         [ $mdt_idx -ne 0 ] &&
19706                 error "create local directory on wrong MDT $mdt_idx"
19707
19708         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19709                         error "create remote directory failed"
19710         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19711         [ $mdt_idx -ne $MDTIDX ] &&
19712                 error "create remote directory on wrong MDT $mdt_idx"
19713
19714         createmany -o $DIR/$tdir/test_230/t- 10 ||
19715                 error "create files on remote directory failed"
19716         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19717         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19718         rm -r $DIR/$tdir || error "unlink remote directory failed"
19719 }
19720 run_test 230a "Create remote directory and files under the remote directory"
19721
19722 test_230b() {
19723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19724         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19725         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19726                 skip "Need MDS version at least 2.11.52"
19727
19728         local MDTIDX=1
19729         local mdt_index
19730         local i
19731         local file
19732         local pid
19733         local stripe_count
19734         local migrate_dir=$DIR/$tdir/migrate_dir
19735         local other_dir=$DIR/$tdir/other_dir
19736
19737         test_mkdir $DIR/$tdir
19738         test_mkdir -i0 -c1 $migrate_dir
19739         test_mkdir -i0 -c1 $other_dir
19740         for ((i=0; i<10; i++)); do
19741                 mkdir -p $migrate_dir/dir_${i}
19742                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19743                         error "create files under remote dir failed $i"
19744         done
19745
19746         cp /etc/passwd $migrate_dir/$tfile
19747         cp /etc/passwd $other_dir/$tfile
19748         chattr +SAD $migrate_dir
19749         chattr +SAD $migrate_dir/$tfile
19750
19751         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19752         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19753         local old_dir_mode=$(stat -c%f $migrate_dir)
19754         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19755
19756         mkdir -p $migrate_dir/dir_default_stripe2
19757         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19758         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19759
19760         mkdir -p $other_dir
19761         ln $migrate_dir/$tfile $other_dir/luna
19762         ln $migrate_dir/$tfile $migrate_dir/sofia
19763         ln $other_dir/$tfile $migrate_dir/david
19764         ln -s $migrate_dir/$tfile $other_dir/zachary
19765         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19766         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19767
19768         local len
19769         local lnktgt
19770
19771         # inline symlink
19772         for len in 58 59 60; do
19773                 lnktgt=$(str_repeat 'l' $len)
19774                 touch $migrate_dir/$lnktgt
19775                 ln -s $lnktgt $migrate_dir/${len}char_ln
19776         done
19777
19778         # PATH_MAX
19779         for len in 4094 4095; do
19780                 lnktgt=$(str_repeat 'l' $len)
19781                 ln -s $lnktgt $migrate_dir/${len}char_ln
19782         done
19783
19784         # NAME_MAX
19785         for len in 254 255; do
19786                 touch $migrate_dir/$(str_repeat 'l' $len)
19787         done
19788
19789         $LFS migrate -m $MDTIDX $migrate_dir ||
19790                 error "fails on migrating remote dir to MDT1"
19791
19792         echo "migratate to MDT1, then checking.."
19793         for ((i = 0; i < 10; i++)); do
19794                 for file in $(find $migrate_dir/dir_${i}); do
19795                         mdt_index=$($LFS getstripe -m $file)
19796                         # broken symlink getstripe will fail
19797                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19798                                 error "$file is not on MDT${MDTIDX}"
19799                 done
19800         done
19801
19802         # the multiple link file should still in MDT0
19803         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19804         [ $mdt_index == 0 ] ||
19805                 error "$file is not on MDT${MDTIDX}"
19806
19807         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19808         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19809                 error " expect $old_dir_flag get $new_dir_flag"
19810
19811         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19812         [ "$old_file_flag" = "$new_file_flag" ] ||
19813                 error " expect $old_file_flag get $new_file_flag"
19814
19815         local new_dir_mode=$(stat -c%f $migrate_dir)
19816         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19817                 error "expect mode $old_dir_mode get $new_dir_mode"
19818
19819         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19820         [ "$old_file_mode" = "$new_file_mode" ] ||
19821                 error "expect mode $old_file_mode get $new_file_mode"
19822
19823         diff /etc/passwd $migrate_dir/$tfile ||
19824                 error "$tfile different after migration"
19825
19826         diff /etc/passwd $other_dir/luna ||
19827                 error "luna different after migration"
19828
19829         diff /etc/passwd $migrate_dir/sofia ||
19830                 error "sofia different after migration"
19831
19832         diff /etc/passwd $migrate_dir/david ||
19833                 error "david different after migration"
19834
19835         diff /etc/passwd $other_dir/zachary ||
19836                 error "zachary different after migration"
19837
19838         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19839                 error "${tfile}_ln different after migration"
19840
19841         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19842                 error "${tfile}_ln_other different after migration"
19843
19844         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19845         [ $stripe_count = 2 ] ||
19846                 error "dir strpe_count $d != 2 after migration."
19847
19848         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19849         [ $stripe_count = 2 ] ||
19850                 error "file strpe_count $d != 2 after migration."
19851
19852         #migrate back to MDT0
19853         MDTIDX=0
19854
19855         $LFS migrate -m $MDTIDX $migrate_dir ||
19856                 error "fails on migrating remote dir to MDT0"
19857
19858         echo "migrate back to MDT0, checking.."
19859         for file in $(find $migrate_dir); do
19860                 mdt_index=$($LFS getstripe -m $file)
19861                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19862                         error "$file is not on MDT${MDTIDX}"
19863         done
19864
19865         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19866         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19867                 error " expect $old_dir_flag get $new_dir_flag"
19868
19869         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19870         [ "$old_file_flag" = "$new_file_flag" ] ||
19871                 error " expect $old_file_flag get $new_file_flag"
19872
19873         local new_dir_mode=$(stat -c%f $migrate_dir)
19874         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19875                 error "expect mode $old_dir_mode get $new_dir_mode"
19876
19877         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19878         [ "$old_file_mode" = "$new_file_mode" ] ||
19879                 error "expect mode $old_file_mode get $new_file_mode"
19880
19881         diff /etc/passwd ${migrate_dir}/$tfile ||
19882                 error "$tfile different after migration"
19883
19884         diff /etc/passwd ${other_dir}/luna ||
19885                 error "luna different after migration"
19886
19887         diff /etc/passwd ${migrate_dir}/sofia ||
19888                 error "sofia different after migration"
19889
19890         diff /etc/passwd ${other_dir}/zachary ||
19891                 error "zachary different after migration"
19892
19893         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19894                 error "${tfile}_ln different after migration"
19895
19896         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19897                 error "${tfile}_ln_other different after migration"
19898
19899         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19900         [ $stripe_count = 2 ] ||
19901                 error "dir strpe_count $d != 2 after migration."
19902
19903         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19904         [ $stripe_count = 2 ] ||
19905                 error "file strpe_count $d != 2 after migration."
19906
19907         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19908 }
19909 run_test 230b "migrate directory"
19910
19911 test_230c() {
19912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19913         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19914         remote_mds_nodsh && skip "remote MDS with nodsh"
19915         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19916                 skip "Need MDS version at least 2.11.52"
19917
19918         local MDTIDX=1
19919         local total=3
19920         local mdt_index
19921         local file
19922         local migrate_dir=$DIR/$tdir/migrate_dir
19923
19924         #If migrating directory fails in the middle, all entries of
19925         #the directory is still accessiable.
19926         test_mkdir $DIR/$tdir
19927         test_mkdir -i0 -c1 $migrate_dir
19928         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19929         stat $migrate_dir
19930         createmany -o $migrate_dir/f $total ||
19931                 error "create files under ${migrate_dir} failed"
19932
19933         # fail after migrating top dir, and this will fail only once, so the
19934         # first sub file migration will fail (currently f3), others succeed.
19935         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19936         do_facet mds1 lctl set_param fail_loc=0x1801
19937         local t=$(ls $migrate_dir | wc -l)
19938         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19939                 error "migrate should fail"
19940         local u=$(ls $migrate_dir | wc -l)
19941         [ "$u" == "$t" ] || error "$u != $t during migration"
19942
19943         # add new dir/file should succeed
19944         mkdir $migrate_dir/dir ||
19945                 error "mkdir failed under migrating directory"
19946         touch $migrate_dir/file ||
19947                 error "create file failed under migrating directory"
19948
19949         # add file with existing name should fail
19950         for file in $migrate_dir/f*; do
19951                 stat $file > /dev/null || error "stat $file failed"
19952                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19953                         error "open(O_CREAT|O_EXCL) $file should fail"
19954                 $MULTIOP $file m && error "create $file should fail"
19955                 touch $DIR/$tdir/remote_dir/$tfile ||
19956                         error "touch $tfile failed"
19957                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19958                         error "link $file should fail"
19959                 mdt_index=$($LFS getstripe -m $file)
19960                 if [ $mdt_index == 0 ]; then
19961                         # file failed to migrate is not allowed to rename to
19962                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19963                                 error "rename to $file should fail"
19964                 else
19965                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19966                                 error "rename to $file failed"
19967                 fi
19968                 echo hello >> $file || error "write $file failed"
19969         done
19970
19971         # resume migration with different options should fail
19972         $LFS migrate -m 0 $migrate_dir &&
19973                 error "migrate -m 0 $migrate_dir should fail"
19974
19975         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19976                 error "migrate -c 2 $migrate_dir should fail"
19977
19978         # resume migration should succeed
19979         $LFS migrate -m $MDTIDX $migrate_dir ||
19980                 error "migrate $migrate_dir failed"
19981
19982         echo "Finish migration, then checking.."
19983         for file in $(find $migrate_dir); do
19984                 mdt_index=$($LFS getstripe -m $file)
19985                 [ $mdt_index == $MDTIDX ] ||
19986                         error "$file is not on MDT${MDTIDX}"
19987         done
19988
19989         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19990 }
19991 run_test 230c "check directory accessiblity if migration failed"
19992
19993 test_230d() {
19994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19995         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19996         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19997                 skip "Need MDS version at least 2.11.52"
19998         # LU-11235
19999         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
20000
20001         local migrate_dir=$DIR/$tdir/migrate_dir
20002         local old_index
20003         local new_index
20004         local old_count
20005         local new_count
20006         local new_hash
20007         local mdt_index
20008         local i
20009         local j
20010
20011         old_index=$((RANDOM % MDSCOUNT))
20012         old_count=$((MDSCOUNT - old_index))
20013         new_index=$((RANDOM % MDSCOUNT))
20014         new_count=$((MDSCOUNT - new_index))
20015         new_hash=1 # for all_char
20016
20017         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
20018         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
20019
20020         test_mkdir $DIR/$tdir
20021         test_mkdir -i $old_index -c $old_count $migrate_dir
20022
20023         for ((i=0; i<100; i++)); do
20024                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
20025                 createmany -o $migrate_dir/dir_${i}/f 100 ||
20026                         error "create files under remote dir failed $i"
20027         done
20028
20029         echo -n "Migrate from MDT$old_index "
20030         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
20031         echo -n "to MDT$new_index"
20032         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
20033         echo
20034
20035         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
20036         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
20037                 error "migrate remote dir error"
20038
20039         echo "Finish migration, then checking.."
20040         for file in $(find $migrate_dir -maxdepth 1); do
20041                 mdt_index=$($LFS getstripe -m $file)
20042                 if [ $mdt_index -lt $new_index ] ||
20043                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
20044                         error "$file is on MDT$mdt_index"
20045                 fi
20046         done
20047
20048         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20049 }
20050 run_test 230d "check migrate big directory"
20051
20052 test_230e() {
20053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20054         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20055         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20056                 skip "Need MDS version at least 2.11.52"
20057
20058         local i
20059         local j
20060         local a_fid
20061         local b_fid
20062
20063         mkdir_on_mdt0 $DIR/$tdir
20064         mkdir $DIR/$tdir/migrate_dir
20065         mkdir $DIR/$tdir/other_dir
20066         touch $DIR/$tdir/migrate_dir/a
20067         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
20068         ls $DIR/$tdir/other_dir
20069
20070         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20071                 error "migrate dir fails"
20072
20073         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20074         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20075
20076         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20077         [ $mdt_index == 0 ] || error "a is not on MDT0"
20078
20079         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
20080                 error "migrate dir fails"
20081
20082         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
20083         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
20084
20085         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20086         [ $mdt_index == 1 ] || error "a is not on MDT1"
20087
20088         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
20089         [ $mdt_index == 1 ] || error "b is not on MDT1"
20090
20091         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20092         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
20093
20094         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
20095
20096         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20097 }
20098 run_test 230e "migrate mulitple local link files"
20099
20100 test_230f() {
20101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20102         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20103         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20104                 skip "Need MDS version at least 2.11.52"
20105
20106         local a_fid
20107         local ln_fid
20108
20109         mkdir -p $DIR/$tdir
20110         mkdir $DIR/$tdir/migrate_dir
20111         $LFS mkdir -i1 $DIR/$tdir/other_dir
20112         touch $DIR/$tdir/migrate_dir/a
20113         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20114         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20115         ls $DIR/$tdir/other_dir
20116
20117         # a should be migrated to MDT1, since no other links on MDT0
20118         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20119                 error "#1 migrate dir fails"
20120         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20121         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20122         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20123         [ $mdt_index == 1 ] || error "a is not on MDT1"
20124
20125         # a should stay on MDT1, because it is a mulitple link file
20126         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20127                 error "#2 migrate dir fails"
20128         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20129         [ $mdt_index == 1 ] || error "a is not on MDT1"
20130
20131         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20132                 error "#3 migrate dir fails"
20133
20134         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20135         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20136         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20137
20138         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20139         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20140
20141         # a should be migrated to MDT0, since no other links on MDT1
20142         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20143                 error "#4 migrate dir fails"
20144         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20145         [ $mdt_index == 0 ] || error "a is not on MDT0"
20146
20147         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20148 }
20149 run_test 230f "migrate mulitple remote link files"
20150
20151 test_230g() {
20152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20153         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20154         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20155                 skip "Need MDS version at least 2.11.52"
20156
20157         mkdir -p $DIR/$tdir/migrate_dir
20158
20159         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20160                 error "migrating dir to non-exist MDT succeeds"
20161         true
20162 }
20163 run_test 230g "migrate dir to non-exist MDT"
20164
20165 test_230h() {
20166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20167         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20168         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20169                 skip "Need MDS version at least 2.11.52"
20170
20171         local mdt_index
20172
20173         mkdir -p $DIR/$tdir/migrate_dir
20174
20175         $LFS migrate -m1 $DIR &&
20176                 error "migrating mountpoint1 should fail"
20177
20178         $LFS migrate -m1 $DIR/$tdir/.. &&
20179                 error "migrating mountpoint2 should fail"
20180
20181         # same as mv
20182         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20183                 error "migrating $tdir/migrate_dir/.. should fail"
20184
20185         true
20186 }
20187 run_test 230h "migrate .. and root"
20188
20189 test_230i() {
20190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20191         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20192         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20193                 skip "Need MDS version at least 2.11.52"
20194
20195         mkdir -p $DIR/$tdir/migrate_dir
20196
20197         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20198                 error "migration fails with a tailing slash"
20199
20200         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20201                 error "migration fails with two tailing slashes"
20202 }
20203 run_test 230i "lfs migrate -m tolerates trailing slashes"
20204
20205 test_230j() {
20206         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20207         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20208                 skip "Need MDS version at least 2.11.52"
20209
20210         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20211         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20212                 error "create $tfile failed"
20213         cat /etc/passwd > $DIR/$tdir/$tfile
20214
20215         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20216
20217         cmp /etc/passwd $DIR/$tdir/$tfile ||
20218                 error "DoM file mismatch after migration"
20219 }
20220 run_test 230j "DoM file data not changed after dir migration"
20221
20222 test_230k() {
20223         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20224         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20225                 skip "Need MDS version at least 2.11.56"
20226
20227         local total=20
20228         local files_on_starting_mdt=0
20229
20230         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20231         $LFS getdirstripe $DIR/$tdir
20232         for i in $(seq $total); do
20233                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20234                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20235                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20236         done
20237
20238         echo "$files_on_starting_mdt files on MDT0"
20239
20240         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20241         $LFS getdirstripe $DIR/$tdir
20242
20243         files_on_starting_mdt=0
20244         for i in $(seq $total); do
20245                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20246                         error "file $tfile.$i mismatch after migration"
20247                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20248                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20249         done
20250
20251         echo "$files_on_starting_mdt files on MDT1 after migration"
20252         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20253
20254         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20255         $LFS getdirstripe $DIR/$tdir
20256
20257         files_on_starting_mdt=0
20258         for i in $(seq $total); do
20259                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20260                         error "file $tfile.$i mismatch after 2nd migration"
20261                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20262                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20263         done
20264
20265         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20266         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20267
20268         true
20269 }
20270 run_test 230k "file data not changed after dir migration"
20271
20272 test_230l() {
20273         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20274         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20275                 skip "Need MDS version at least 2.11.56"
20276
20277         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20278         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20279                 error "create files under remote dir failed $i"
20280         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20281 }
20282 run_test 230l "readdir between MDTs won't crash"
20283
20284 test_230m() {
20285         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20286         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20287                 skip "Need MDS version at least 2.11.56"
20288
20289         local MDTIDX=1
20290         local mig_dir=$DIR/$tdir/migrate_dir
20291         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20292         local shortstr="b"
20293         local val
20294
20295         echo "Creating files and dirs with xattrs"
20296         test_mkdir $DIR/$tdir
20297         test_mkdir -i0 -c1 $mig_dir
20298         mkdir $mig_dir/dir
20299         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20300                 error "cannot set xattr attr1 on dir"
20301         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20302                 error "cannot set xattr attr2 on dir"
20303         touch $mig_dir/dir/f0
20304         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20305                 error "cannot set xattr attr1 on file"
20306         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20307                 error "cannot set xattr attr2 on file"
20308         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20309         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20310         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20311         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20312         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20313         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20314         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20315         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20316         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20317
20318         echo "Migrating to MDT1"
20319         $LFS migrate -m $MDTIDX $mig_dir ||
20320                 error "fails on migrating dir to MDT1"
20321
20322         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20323         echo "Checking xattrs"
20324         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20325         [ "$val" = $longstr ] ||
20326                 error "expecting xattr1 $longstr on dir, found $val"
20327         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20328         [ "$val" = $shortstr ] ||
20329                 error "expecting xattr2 $shortstr on dir, found $val"
20330         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20331         [ "$val" = $longstr ] ||
20332                 error "expecting xattr1 $longstr on file, found $val"
20333         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20334         [ "$val" = $shortstr ] ||
20335                 error "expecting xattr2 $shortstr on file, found $val"
20336 }
20337 run_test 230m "xattrs not changed after dir migration"
20338
20339 test_230n() {
20340         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20341         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20342                 skip "Need MDS version at least 2.13.53"
20343
20344         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20345         cat /etc/hosts > $DIR/$tdir/$tfile
20346         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20347         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20348
20349         cmp /etc/hosts $DIR/$tdir/$tfile ||
20350                 error "File data mismatch after migration"
20351 }
20352 run_test 230n "Dir migration with mirrored file"
20353
20354 test_230o() {
20355         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20356         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20357                 skip "Need MDS version at least 2.13.52"
20358
20359         local mdts=$(comma_list $(mdts_nodes))
20360         local timeout=100
20361         local restripe_status
20362         local delta
20363         local i
20364
20365         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20366
20367         # in case "crush" hash type is not set
20368         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20369
20370         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20371                            mdt.*MDT0000.enable_dir_restripe)
20372         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20373         stack_trap "do_nodes $mdts $LCTL set_param \
20374                     mdt.*.enable_dir_restripe=$restripe_status"
20375
20376         mkdir $DIR/$tdir
20377         createmany -m $DIR/$tdir/f 100 ||
20378                 error "create files under remote dir failed $i"
20379         createmany -d $DIR/$tdir/d 100 ||
20380                 error "create dirs under remote dir failed $i"
20381
20382         for i in $(seq 2 $MDSCOUNT); do
20383                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20384                 $LFS setdirstripe -c $i $DIR/$tdir ||
20385                         error "split -c $i $tdir failed"
20386                 wait_update $HOSTNAME \
20387                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20388                         error "dir split not finished"
20389                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20390                         awk '/migrate/ {sum += $2} END { print sum }')
20391                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20392                 # delta is around total_files/stripe_count
20393                 (( $delta < 200 / (i - 1) + 4 )) ||
20394                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20395         done
20396 }
20397 run_test 230o "dir split"
20398
20399 test_230p() {
20400         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20401         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20402                 skip "Need MDS version at least 2.13.52"
20403
20404         local mdts=$(comma_list $(mdts_nodes))
20405         local timeout=100
20406         local restripe_status
20407         local delta
20408         local c
20409
20410         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20411
20412         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20413
20414         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20415                            mdt.*MDT0000.enable_dir_restripe)
20416         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20417         stack_trap "do_nodes $mdts $LCTL set_param \
20418                     mdt.*.enable_dir_restripe=$restripe_status"
20419
20420         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20421         createmany -m $DIR/$tdir/f 100 ||
20422                 error "create files under remote dir failed"
20423         createmany -d $DIR/$tdir/d 100 ||
20424                 error "create dirs under remote dir failed"
20425
20426         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20427                 local mdt_hash="crush"
20428
20429                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20430                 $LFS setdirstripe -c $c $DIR/$tdir ||
20431                         error "split -c $c $tdir failed"
20432                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20433                         mdt_hash="$mdt_hash,fixed"
20434                 elif [ $c -eq 1 ]; then
20435                         mdt_hash="none"
20436                 fi
20437                 wait_update $HOSTNAME \
20438                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20439                         error "dir merge not finished"
20440                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20441                         awk '/migrate/ {sum += $2} END { print sum }')
20442                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20443                 # delta is around total_files/stripe_count
20444                 (( delta < 200 / c + 4 )) ||
20445                         error "$delta files migrated >= $((200 / c + 4))"
20446         done
20447 }
20448 run_test 230p "dir merge"
20449
20450 test_230q() {
20451         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20452         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20453                 skip "Need MDS version at least 2.13.52"
20454
20455         local mdts=$(comma_list $(mdts_nodes))
20456         local saved_threshold=$(do_facet mds1 \
20457                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20458         local saved_delta=$(do_facet mds1 \
20459                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20460         local threshold=100
20461         local delta=2
20462         local total=0
20463         local stripe_count=0
20464         local stripe_index
20465         local nr_files
20466         local create
20467
20468         # test with fewer files on ZFS
20469         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20470
20471         stack_trap "do_nodes $mdts $LCTL set_param \
20472                     mdt.*.dir_split_count=$saved_threshold"
20473         stack_trap "do_nodes $mdts $LCTL set_param \
20474                     mdt.*.dir_split_delta=$saved_delta"
20475         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20476         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20477         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20478         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20479         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20480         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20481
20482         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20483         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20484
20485         create=$((threshold * 3 / 2))
20486         while [ $stripe_count -lt $MDSCOUNT ]; do
20487                 createmany -m $DIR/$tdir/f $total $create ||
20488                         error "create sub files failed"
20489                 stat $DIR/$tdir > /dev/null
20490                 total=$((total + create))
20491                 stripe_count=$((stripe_count + delta))
20492                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20493
20494                 wait_update $HOSTNAME \
20495                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20496                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20497
20498                 wait_update $HOSTNAME \
20499                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20500                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20501
20502                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20503                 echo "$nr_files/$total files on MDT$stripe_index after split"
20504                 # allow 10% margin of imbalance with crush hash
20505                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20506                         error "$nr_files files on MDT$stripe_index after split"
20507
20508                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20509                 [ $nr_files -eq $total ] ||
20510                         error "total sub files $nr_files != $total"
20511         done
20512
20513         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20514
20515         echo "fixed layout directory won't auto split"
20516         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20517         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20518                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20519         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20520                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20521 }
20522 run_test 230q "dir auto split"
20523
20524 test_230r() {
20525         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20526         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20527         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20528                 skip "Need MDS version at least 2.13.54"
20529
20530         # maximum amount of local locks:
20531         # parent striped dir - 2 locks
20532         # new stripe in parent to migrate to - 1 lock
20533         # source and target - 2 locks
20534         # Total 5 locks for regular file
20535         mkdir -p $DIR/$tdir
20536         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20537         touch $DIR/$tdir/dir1/eee
20538
20539         # create 4 hardlink for 4 more locks
20540         # Total: 9 locks > RS_MAX_LOCKS (8)
20541         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20542         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20543         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20544         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20545         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20546         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20547         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20548         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20549
20550         cancel_lru_locks mdc
20551
20552         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20553                 error "migrate dir fails"
20554
20555         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20556 }
20557 run_test 230r "migrate with too many local locks"
20558
20559 test_230s() {
20560         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
20561                 skip "Need MDS version at least 2.14.52"
20562
20563         local mdts=$(comma_list $(mdts_nodes))
20564         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20565                                 mdt.*MDT0000.enable_dir_restripe)
20566
20567         stack_trap "do_nodes $mdts $LCTL set_param \
20568                     mdt.*.enable_dir_restripe=$restripe_status"
20569
20570         local st
20571         for st in 0 1; do
20572                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20573                 test_mkdir $DIR/$tdir
20574                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20575                         error "$LFS mkdir should return EEXIST if target exists"
20576                 rmdir $DIR/$tdir
20577         done
20578 }
20579 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20580
20581 test_230t()
20582 {
20583         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20584         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20585                 skip "Need MDS version at least 2.14.50"
20586
20587         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20588         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20589         $LFS project -p 1 -s $DIR/$tdir ||
20590                 error "set $tdir project id failed"
20591         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20592                 error "set subdir project id failed"
20593         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20594 }
20595 run_test 230t "migrate directory with project ID set"
20596
20597 test_230u()
20598 {
20599         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20600         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20601                 skip "Need MDS version at least 2.14.53"
20602
20603         local count
20604
20605         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20606         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20607         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20608         for i in $(seq 0 $((MDSCOUNT - 1))); do
20609                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20610                 echo "$count dirs migrated to MDT$i"
20611         done
20612         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20613         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20614 }
20615 run_test 230u "migrate directory by QOS"
20616
20617 test_230v()
20618 {
20619         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20620         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20621                 skip "Need MDS version at least 2.14.53"
20622
20623         local count
20624
20625         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20626         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20627         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20628         for i in $(seq 0 $((MDSCOUNT - 1))); do
20629                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20630                 echo "$count subdirs migrated to MDT$i"
20631                 (( i == 3 )) && (( count > 0 )) &&
20632                         error "subdir shouldn't be migrated to MDT3"
20633         done
20634         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20635         (( count == 3 )) || error "dirs migrated to $count MDTs"
20636 }
20637 run_test 230v "subdir migrated to the MDT where its parent is located"
20638
20639 test_230w() {
20640         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20641         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20642                 skip "Need MDS version at least 2.14.53"
20643
20644         mkdir -p $DIR/$tdir/sub || error "mkdir failed"
20645
20646         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
20647                 error "migrate failed"
20648
20649         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
20650                 error "$tdir stripe count mismatch"
20651
20652         (( $($LFS getdirstripe -c $DIR/$tdir/sub) == 0 )) ||
20653                 error "$tdir/sub is striped"
20654 }
20655 run_test 230w "non-recursive mode dir migration"
20656
20657 test_231a()
20658 {
20659         # For simplicity this test assumes that max_pages_per_rpc
20660         # is the same across all OSCs
20661         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20662         local bulk_size=$((max_pages * PAGE_SIZE))
20663         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20664                                        head -n 1)
20665
20666         mkdir -p $DIR/$tdir
20667         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20668                 error "failed to set stripe with -S ${brw_size}M option"
20669
20670         # clear the OSC stats
20671         $LCTL set_param osc.*.stats=0 &>/dev/null
20672         stop_writeback
20673
20674         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20675         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20676                 oflag=direct &>/dev/null || error "dd failed"
20677
20678         sync; sleep 1; sync # just to be safe
20679         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20680         if [ x$nrpcs != "x1" ]; then
20681                 $LCTL get_param osc.*.stats
20682                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20683         fi
20684
20685         start_writeback
20686         # Drop the OSC cache, otherwise we will read from it
20687         cancel_lru_locks osc
20688
20689         # clear the OSC stats
20690         $LCTL set_param osc.*.stats=0 &>/dev/null
20691
20692         # Client reads $bulk_size.
20693         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20694                 iflag=direct &>/dev/null || error "dd failed"
20695
20696         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20697         if [ x$nrpcs != "x1" ]; then
20698                 $LCTL get_param osc.*.stats
20699                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20700         fi
20701 }
20702 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20703
20704 test_231b() {
20705         mkdir -p $DIR/$tdir
20706         local i
20707         for i in {0..1023}; do
20708                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20709                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20710                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20711         done
20712         sync
20713 }
20714 run_test 231b "must not assert on fully utilized OST request buffer"
20715
20716 test_232a() {
20717         mkdir -p $DIR/$tdir
20718         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20719
20720         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20721         do_facet ost1 $LCTL set_param fail_loc=0x31c
20722
20723         # ignore dd failure
20724         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20725
20726         do_facet ost1 $LCTL set_param fail_loc=0
20727         umount_client $MOUNT || error "umount failed"
20728         mount_client $MOUNT || error "mount failed"
20729         stop ost1 || error "cannot stop ost1"
20730         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20731 }
20732 run_test 232a "failed lock should not block umount"
20733
20734 test_232b() {
20735         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20736                 skip "Need MDS version at least 2.10.58"
20737
20738         mkdir -p $DIR/$tdir
20739         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20740         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20741         sync
20742         cancel_lru_locks osc
20743
20744         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20745         do_facet ost1 $LCTL set_param fail_loc=0x31c
20746
20747         # ignore failure
20748         $LFS data_version $DIR/$tdir/$tfile || true
20749
20750         do_facet ost1 $LCTL set_param fail_loc=0
20751         umount_client $MOUNT || error "umount failed"
20752         mount_client $MOUNT || error "mount failed"
20753         stop ost1 || error "cannot stop ost1"
20754         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20755 }
20756 run_test 232b "failed data version lock should not block umount"
20757
20758 test_233a() {
20759         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20760                 skip "Need MDS version at least 2.3.64"
20761         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20762
20763         local fid=$($LFS path2fid $MOUNT)
20764
20765         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20766                 error "cannot access $MOUNT using its FID '$fid'"
20767 }
20768 run_test 233a "checking that OBF of the FS root succeeds"
20769
20770 test_233b() {
20771         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20772                 skip "Need MDS version at least 2.5.90"
20773         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20774
20775         local fid=$($LFS path2fid $MOUNT/.lustre)
20776
20777         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20778                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20779
20780         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20781         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20782                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20783 }
20784 run_test 233b "checking that OBF of the FS .lustre succeeds"
20785
20786 test_234() {
20787         local p="$TMP/sanityN-$TESTNAME.parameters"
20788         save_lustre_params client "llite.*.xattr_cache" > $p
20789         lctl set_param llite.*.xattr_cache 1 ||
20790                 skip_env "xattr cache is not supported"
20791
20792         mkdir -p $DIR/$tdir || error "mkdir failed"
20793         touch $DIR/$tdir/$tfile || error "touch failed"
20794         # OBD_FAIL_LLITE_XATTR_ENOMEM
20795         $LCTL set_param fail_loc=0x1405
20796         getfattr -n user.attr $DIR/$tdir/$tfile &&
20797                 error "getfattr should have failed with ENOMEM"
20798         $LCTL set_param fail_loc=0x0
20799         rm -rf $DIR/$tdir
20800
20801         restore_lustre_params < $p
20802         rm -f $p
20803 }
20804 run_test 234 "xattr cache should not crash on ENOMEM"
20805
20806 test_235() {
20807         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20808                 skip "Need MDS version at least 2.4.52"
20809
20810         flock_deadlock $DIR/$tfile
20811         local RC=$?
20812         case $RC in
20813                 0)
20814                 ;;
20815                 124) error "process hangs on a deadlock"
20816                 ;;
20817                 *) error "error executing flock_deadlock $DIR/$tfile"
20818                 ;;
20819         esac
20820 }
20821 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20822
20823 #LU-2935
20824 test_236() {
20825         check_swap_layouts_support
20826
20827         local ref1=/etc/passwd
20828         local ref2=/etc/group
20829         local file1=$DIR/$tdir/f1
20830         local file2=$DIR/$tdir/f2
20831
20832         test_mkdir -c1 $DIR/$tdir
20833         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20834         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20835         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20836         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20837         local fd=$(free_fd)
20838         local cmd="exec $fd<>$file2"
20839         eval $cmd
20840         rm $file2
20841         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20842                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20843         cmd="exec $fd>&-"
20844         eval $cmd
20845         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20846
20847         #cleanup
20848         rm -rf $DIR/$tdir
20849 }
20850 run_test 236 "Layout swap on open unlinked file"
20851
20852 # LU-4659 linkea consistency
20853 test_238() {
20854         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20855                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20856                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20857                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20858
20859         touch $DIR/$tfile
20860         ln $DIR/$tfile $DIR/$tfile.lnk
20861         touch $DIR/$tfile.new
20862         mv $DIR/$tfile.new $DIR/$tfile
20863         local fid1=$($LFS path2fid $DIR/$tfile)
20864         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20865         local path1=$($LFS fid2path $FSNAME "$fid1")
20866         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20867         local path2=$($LFS fid2path $FSNAME "$fid2")
20868         [ $tfile.lnk == $path2 ] ||
20869                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20870         rm -f $DIR/$tfile*
20871 }
20872 run_test 238 "Verify linkea consistency"
20873
20874 test_239A() { # was test_239
20875         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20876                 skip "Need MDS version at least 2.5.60"
20877
20878         local list=$(comma_list $(mdts_nodes))
20879
20880         mkdir -p $DIR/$tdir
20881         createmany -o $DIR/$tdir/f- 5000
20882         unlinkmany $DIR/$tdir/f- 5000
20883         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20884                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20885         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20886                         osp.*MDT*.sync_in_flight" | calc_sum)
20887         [ "$changes" -eq 0 ] || error "$changes not synced"
20888 }
20889 run_test 239A "osp_sync test"
20890
20891 test_239a() { #LU-5297
20892         remote_mds_nodsh && skip "remote MDS with nodsh"
20893
20894         touch $DIR/$tfile
20895         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20896         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20897         chgrp $RUNAS_GID $DIR/$tfile
20898         wait_delete_completed
20899 }
20900 run_test 239a "process invalid osp sync record correctly"
20901
20902 test_239b() { #LU-5297
20903         remote_mds_nodsh && skip "remote MDS with nodsh"
20904
20905         touch $DIR/$tfile1
20906         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20907         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20908         chgrp $RUNAS_GID $DIR/$tfile1
20909         wait_delete_completed
20910         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20911         touch $DIR/$tfile2
20912         chgrp $RUNAS_GID $DIR/$tfile2
20913         wait_delete_completed
20914 }
20915 run_test 239b "process osp sync record with ENOMEM error correctly"
20916
20917 test_240() {
20918         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20919         remote_mds_nodsh && skip "remote MDS with nodsh"
20920
20921         mkdir -p $DIR/$tdir
20922
20923         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20924                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20925         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20926                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20927
20928         umount_client $MOUNT || error "umount failed"
20929         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20930         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20931         mount_client $MOUNT || error "failed to mount client"
20932
20933         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20934         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20935 }
20936 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20937
20938 test_241_bio() {
20939         local count=$1
20940         local bsize=$2
20941
20942         for LOOP in $(seq $count); do
20943                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20944                 cancel_lru_locks $OSC || true
20945         done
20946 }
20947
20948 test_241_dio() {
20949         local count=$1
20950         local bsize=$2
20951
20952         for LOOP in $(seq $1); do
20953                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20954                         2>/dev/null
20955         done
20956 }
20957
20958 test_241a() { # was test_241
20959         local bsize=$PAGE_SIZE
20960
20961         (( bsize < 40960 )) && bsize=40960
20962         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20963         ls -la $DIR/$tfile
20964         cancel_lru_locks $OSC
20965         test_241_bio 1000 $bsize &
20966         PID=$!
20967         test_241_dio 1000 $bsize
20968         wait $PID
20969 }
20970 run_test 241a "bio vs dio"
20971
20972 test_241b() {
20973         local bsize=$PAGE_SIZE
20974
20975         (( bsize < 40960 )) && bsize=40960
20976         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20977         ls -la $DIR/$tfile
20978         test_241_dio 1000 $bsize &
20979         PID=$!
20980         test_241_dio 1000 $bsize
20981         wait $PID
20982 }
20983 run_test 241b "dio vs dio"
20984
20985 test_242() {
20986         remote_mds_nodsh && skip "remote MDS with nodsh"
20987
20988         mkdir_on_mdt0 $DIR/$tdir
20989         touch $DIR/$tdir/$tfile
20990
20991         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20992         do_facet mds1 lctl set_param fail_loc=0x105
20993         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20994
20995         do_facet mds1 lctl set_param fail_loc=0
20996         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20997 }
20998 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20999
21000 test_243()
21001 {
21002         test_mkdir $DIR/$tdir
21003         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
21004 }
21005 run_test 243 "various group lock tests"
21006
21007 test_244a()
21008 {
21009         test_mkdir $DIR/$tdir
21010         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
21011         sendfile_grouplock $DIR/$tdir/$tfile || \
21012                 error "sendfile+grouplock failed"
21013         rm -rf $DIR/$tdir
21014 }
21015 run_test 244a "sendfile with group lock tests"
21016
21017 test_244b()
21018 {
21019         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21020
21021         local threads=50
21022         local size=$((1024*1024))
21023
21024         test_mkdir $DIR/$tdir
21025         for i in $(seq 1 $threads); do
21026                 local file=$DIR/$tdir/file_$((i / 10))
21027                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
21028                 local pids[$i]=$!
21029         done
21030         for i in $(seq 1 $threads); do
21031                 wait ${pids[$i]}
21032         done
21033 }
21034 run_test 244b "multi-threaded write with group lock"
21035
21036 test_245a() {
21037         local flagname="multi_mod_rpcs"
21038         local connect_data_name="max_mod_rpcs"
21039         local out
21040
21041         # check if multiple modify RPCs flag is set
21042         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
21043                 grep "connect_flags:")
21044         echo "$out"
21045
21046         echo "$out" | grep -qw $flagname
21047         if [ $? -ne 0 ]; then
21048                 echo "connect flag $flagname is not set"
21049                 return
21050         fi
21051
21052         # check if multiple modify RPCs data is set
21053         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
21054         echo "$out"
21055
21056         echo "$out" | grep -qw $connect_data_name ||
21057                 error "import should have connect data $connect_data_name"
21058 }
21059 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
21060
21061 test_245b() {
21062         local flagname="multi_mod_rpcs"
21063         local connect_data_name="max_mod_rpcs"
21064         local out
21065
21066         remote_mds_nodsh && skip "remote MDS with nodsh"
21067         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
21068
21069         # check if multiple modify RPCs flag is set
21070         out=$(do_facet mds1 \
21071               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
21072               grep "connect_flags:")
21073         echo "$out"
21074
21075         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
21076
21077         # check if multiple modify RPCs data is set
21078         out=$(do_facet mds1 \
21079               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
21080
21081         [[ "$out" =~ $connect_data_name ]] ||
21082                 {
21083                         echo "$out"
21084                         error "missing connect data $connect_data_name"
21085                 }
21086 }
21087 run_test 245b "check osp connection flag/data: multiple modify RPCs"
21088
21089 cleanup_247() {
21090         local submount=$1
21091
21092         trap 0
21093         umount_client $submount
21094         rmdir $submount
21095 }
21096
21097 test_247a() {
21098         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21099                 grep -q subtree ||
21100                 skip_env "Fileset feature is not supported"
21101
21102         local submount=${MOUNT}_$tdir
21103
21104         mkdir $MOUNT/$tdir
21105         mkdir -p $submount || error "mkdir $submount failed"
21106         FILESET="$FILESET/$tdir" mount_client $submount ||
21107                 error "mount $submount failed"
21108         trap "cleanup_247 $submount" EXIT
21109         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21110         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21111                 error "read $MOUNT/$tdir/$tfile failed"
21112         cleanup_247 $submount
21113 }
21114 run_test 247a "mount subdir as fileset"
21115
21116 test_247b() {
21117         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21118                 skip_env "Fileset feature is not supported"
21119
21120         local submount=${MOUNT}_$tdir
21121
21122         rm -rf $MOUNT/$tdir
21123         mkdir -p $submount || error "mkdir $submount failed"
21124         SKIP_FILESET=1
21125         FILESET="$FILESET/$tdir" mount_client $submount &&
21126                 error "mount $submount should fail"
21127         rmdir $submount
21128 }
21129 run_test 247b "mount subdir that dose not exist"
21130
21131 test_247c() {
21132         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21133                 skip_env "Fileset feature is not supported"
21134
21135         local submount=${MOUNT}_$tdir
21136
21137         mkdir -p $MOUNT/$tdir/dir1
21138         mkdir -p $submount || error "mkdir $submount failed"
21139         trap "cleanup_247 $submount" EXIT
21140         FILESET="$FILESET/$tdir" mount_client $submount ||
21141                 error "mount $submount failed"
21142         local fid=$($LFS path2fid $MOUNT/)
21143         $LFS fid2path $submount $fid && error "fid2path should fail"
21144         cleanup_247 $submount
21145 }
21146 run_test 247c "running fid2path outside subdirectory root"
21147
21148 test_247d() {
21149         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21150                 skip "Fileset feature is not supported"
21151
21152         local submount=${MOUNT}_$tdir
21153
21154         mkdir -p $MOUNT/$tdir/dir1
21155         mkdir -p $submount || error "mkdir $submount failed"
21156         FILESET="$FILESET/$tdir" mount_client $submount ||
21157                 error "mount $submount failed"
21158         trap "cleanup_247 $submount" EXIT
21159
21160         local td=$submount/dir1
21161         local fid=$($LFS path2fid $td)
21162         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21163
21164         # check that we get the same pathname back
21165         local rootpath
21166         local found
21167         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21168                 echo "$rootpath $fid"
21169                 found=$($LFS fid2path $rootpath "$fid")
21170                 [ -n "$found" ] || error "fid2path should succeed"
21171                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21172         done
21173         # check wrong root path format
21174         rootpath=$submount"_wrong"
21175         found=$($LFS fid2path $rootpath "$fid")
21176         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21177
21178         cleanup_247 $submount
21179 }
21180 run_test 247d "running fid2path inside subdirectory root"
21181
21182 # LU-8037
21183 test_247e() {
21184         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21185                 grep -q subtree ||
21186                 skip "Fileset feature is not supported"
21187
21188         local submount=${MOUNT}_$tdir
21189
21190         mkdir $MOUNT/$tdir
21191         mkdir -p $submount || error "mkdir $submount failed"
21192         FILESET="$FILESET/.." mount_client $submount &&
21193                 error "mount $submount should fail"
21194         rmdir $submount
21195 }
21196 run_test 247e "mount .. as fileset"
21197
21198 test_247f() {
21199         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21200         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21201                 skip "Need at least version 2.13.52"
21202         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21203                 skip "Need at least version 2.14.50"
21204         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21205                 grep -q subtree ||
21206                 skip "Fileset feature is not supported"
21207
21208         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21209         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21210                 error "mkdir remote failed"
21211         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21212                 error "mkdir remote/subdir failed"
21213         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21214                 error "mkdir striped failed"
21215         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21216
21217         local submount=${MOUNT}_$tdir
21218
21219         mkdir -p $submount || error "mkdir $submount failed"
21220         stack_trap "rmdir $submount"
21221
21222         local dir
21223         local stat
21224         local fileset=$FILESET
21225         local mdts=$(comma_list $(mdts_nodes))
21226
21227         stat=$(do_facet mds1 $LCTL get_param -n \
21228                 mdt.*MDT0000.enable_remote_subdir_mount)
21229         stack_trap "do_nodes $mdts $LCTL set_param \
21230                 mdt.*.enable_remote_subdir_mount=$stat"
21231
21232         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21233         stack_trap "umount_client $submount"
21234         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21235                 error "mount remote dir $dir should fail"
21236
21237         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21238                 $tdir/striped/. ; do
21239                 FILESET="$fileset/$dir" mount_client $submount ||
21240                         error "mount $dir failed"
21241                 umount_client $submount
21242         done
21243
21244         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21245         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21246                 error "mount $tdir/remote failed"
21247 }
21248 run_test 247f "mount striped or remote directory as fileset"
21249
21250 test_247g() {
21251         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21252         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21253                 skip "Need at least version 2.14.50"
21254
21255         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21256                 error "mkdir $tdir failed"
21257         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21258
21259         local submount=${MOUNT}_$tdir
21260
21261         mkdir -p $submount || error "mkdir $submount failed"
21262         stack_trap "rmdir $submount"
21263
21264         FILESET="$fileset/$tdir" mount_client $submount ||
21265                 error "mount $dir failed"
21266         stack_trap "umount $submount"
21267
21268         local mdts=$(comma_list $(mdts_nodes))
21269
21270         local nrpcs
21271
21272         stat $submount > /dev/null
21273         cancel_lru_locks $MDC
21274         stat $submount > /dev/null
21275         stat $submount/$tfile > /dev/null
21276         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21277         stat $submount/$tfile > /dev/null
21278         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21279                 awk '/getattr/ {sum += $2} END {print sum}')
21280
21281         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21282 }
21283 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21284
21285 test_248a() {
21286         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21287         [ -z "$fast_read_sav" ] && skip "no fast read support"
21288
21289         # create a large file for fast read verification
21290         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21291
21292         # make sure the file is created correctly
21293         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21294                 { rm -f $DIR/$tfile; skip "file creation error"; }
21295
21296         echo "Test 1: verify that fast read is 4 times faster on cache read"
21297
21298         # small read with fast read enabled
21299         $LCTL set_param -n llite.*.fast_read=1
21300         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21301                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21302                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21303         # small read with fast read disabled
21304         $LCTL set_param -n llite.*.fast_read=0
21305         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21306                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21307                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21308
21309         # verify that fast read is 4 times faster for cache read
21310         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21311                 error_not_in_vm "fast read was not 4 times faster: " \
21312                            "$t_fast vs $t_slow"
21313
21314         echo "Test 2: verify the performance between big and small read"
21315         $LCTL set_param -n llite.*.fast_read=1
21316
21317         # 1k non-cache read
21318         cancel_lru_locks osc
21319         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21320                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21321                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21322
21323         # 1M non-cache read
21324         cancel_lru_locks osc
21325         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21326                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21327                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21328
21329         # verify that big IO is not 4 times faster than small IO
21330         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21331                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21332
21333         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21334         rm -f $DIR/$tfile
21335 }
21336 run_test 248a "fast read verification"
21337
21338 test_248b() {
21339         # Default short_io_bytes=16384, try both smaller and larger sizes.
21340         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21341         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21342         echo "bs=53248 count=113 normal buffered write"
21343         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21344                 error "dd of initial data file failed"
21345         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21346
21347         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21348         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21349                 error "dd with sync normal writes failed"
21350         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21351
21352         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21353         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21354                 error "dd with sync small writes failed"
21355         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21356
21357         cancel_lru_locks osc
21358
21359         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21360         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21361         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21362         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21363                 iflag=direct || error "dd with O_DIRECT small read failed"
21364         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21365         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21366                 error "compare $TMP/$tfile.1 failed"
21367
21368         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21369         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21370
21371         # just to see what the maximum tunable value is, and test parsing
21372         echo "test invalid parameter 2MB"
21373         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21374                 error "too-large short_io_bytes allowed"
21375         echo "test maximum parameter 512KB"
21376         # if we can set a larger short_io_bytes, run test regardless of version
21377         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21378                 # older clients may not allow setting it this large, that's OK
21379                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21380                         skip "Need at least client version 2.13.50"
21381                 error "medium short_io_bytes failed"
21382         fi
21383         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21384         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21385
21386         echo "test large parameter 64KB"
21387         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21388         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21389
21390         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21391         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21392                 error "dd with sync large writes failed"
21393         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21394
21395         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21396         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21397         num=$((113 * 4096 / PAGE_SIZE))
21398         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21399         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21400                 error "dd with O_DIRECT large writes failed"
21401         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21402                 error "compare $DIR/$tfile.3 failed"
21403
21404         cancel_lru_locks osc
21405
21406         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21407         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21408                 error "dd with O_DIRECT large read failed"
21409         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21410                 error "compare $TMP/$tfile.2 failed"
21411
21412         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21413         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21414                 error "dd with O_DIRECT large read failed"
21415         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21416                 error "compare $TMP/$tfile.3 failed"
21417 }
21418 run_test 248b "test short_io read and write for both small and large sizes"
21419
21420 test_249() { # LU-7890
21421         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21422                 skip "Need at least version 2.8.54"
21423
21424         rm -f $DIR/$tfile
21425         $LFS setstripe -c 1 $DIR/$tfile
21426         # Offset 2T == 4k * 512M
21427         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21428                 error "dd to 2T offset failed"
21429 }
21430 run_test 249 "Write above 2T file size"
21431
21432 test_250() {
21433         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21434          && skip "no 16TB file size limit on ZFS"
21435
21436         $LFS setstripe -c 1 $DIR/$tfile
21437         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21438         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21439         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21440         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21441                 conv=notrunc,fsync && error "append succeeded"
21442         return 0
21443 }
21444 run_test 250 "Write above 16T limit"
21445
21446 test_251() {
21447         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21448
21449         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21450         #Skip once - writing the first stripe will succeed
21451         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21452         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21453                 error "short write happened"
21454
21455         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21456         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21457                 error "short read happened"
21458
21459         rm -f $DIR/$tfile
21460 }
21461 run_test 251 "Handling short read and write correctly"
21462
21463 test_252() {
21464         remote_mds_nodsh && skip "remote MDS with nodsh"
21465         remote_ost_nodsh && skip "remote OST with nodsh"
21466         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21467                 skip_env "ldiskfs only test"
21468         fi
21469
21470         local tgt
21471         local dev
21472         local out
21473         local uuid
21474         local num
21475         local gen
21476
21477         # check lr_reader on OST0000
21478         tgt=ost1
21479         dev=$(facet_device $tgt)
21480         out=$(do_facet $tgt $LR_READER $dev)
21481         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21482         echo "$out"
21483         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21484         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21485                 error "Invalid uuid returned by $LR_READER on target $tgt"
21486         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21487
21488         # check lr_reader -c on MDT0000
21489         tgt=mds1
21490         dev=$(facet_device $tgt)
21491         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21492                 skip "$LR_READER does not support additional options"
21493         fi
21494         out=$(do_facet $tgt $LR_READER -c $dev)
21495         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21496         echo "$out"
21497         num=$(echo "$out" | grep -c "mdtlov")
21498         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21499                 error "Invalid number of mdtlov clients returned by $LR_READER"
21500         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21501
21502         # check lr_reader -cr on MDT0000
21503         out=$(do_facet $tgt $LR_READER -cr $dev)
21504         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21505         echo "$out"
21506         echo "$out" | grep -q "^reply_data:$" ||
21507                 error "$LR_READER should have returned 'reply_data' section"
21508         num=$(echo "$out" | grep -c "client_generation")
21509         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21510 }
21511 run_test 252 "check lr_reader tool"
21512
21513 test_253() {
21514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21515         remote_mds_nodsh && skip "remote MDS with nodsh"
21516         remote_mgs_nodsh && skip "remote MGS with nodsh"
21517
21518         local ostidx=0
21519         local rc=0
21520         local ost_name=$(ostname_from_index $ostidx)
21521
21522         # on the mdt's osc
21523         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21524         do_facet $SINGLEMDS $LCTL get_param -n \
21525                 osp.$mdtosc_proc1.reserved_mb_high ||
21526                 skip  "remote MDS does not support reserved_mb_high"
21527
21528         rm -rf $DIR/$tdir
21529         wait_mds_ost_sync
21530         wait_delete_completed
21531         mkdir $DIR/$tdir
21532
21533         pool_add $TESTNAME || error "Pool creation failed"
21534         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21535
21536         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21537                 error "Setstripe failed"
21538
21539         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21540
21541         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21542                     grep "watermarks")
21543         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21544
21545         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21546                         osp.$mdtosc_proc1.prealloc_status)
21547         echo "prealloc_status $oa_status"
21548
21549         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21550                 error "File creation should fail"
21551
21552         #object allocation was stopped, but we still able to append files
21553         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21554                 oflag=append || error "Append failed"
21555
21556         rm -f $DIR/$tdir/$tfile.0
21557
21558         # For this test, we want to delete the files we created to go out of
21559         # space but leave the watermark, so we remain nearly out of space
21560         ost_watermarks_enospc_delete_files $tfile $ostidx
21561
21562         wait_delete_completed
21563
21564         sleep_maxage
21565
21566         for i in $(seq 10 12); do
21567                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21568                         2>/dev/null || error "File creation failed after rm"
21569         done
21570
21571         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21572                         osp.$mdtosc_proc1.prealloc_status)
21573         echo "prealloc_status $oa_status"
21574
21575         if (( oa_status != 0 )); then
21576                 error "Object allocation still disable after rm"
21577         fi
21578 }
21579 run_test 253 "Check object allocation limit"
21580
21581 test_254() {
21582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21583         remote_mds_nodsh && skip "remote MDS with nodsh"
21584
21585         local mdt=$(facet_svc $SINGLEMDS)
21586
21587         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21588                 skip "MDS does not support changelog_size"
21589
21590         local cl_user
21591
21592         changelog_register || error "changelog_register failed"
21593
21594         changelog_clear 0 || error "changelog_clear failed"
21595
21596         local size1=$(do_facet $SINGLEMDS \
21597                       $LCTL get_param -n mdd.$mdt.changelog_size)
21598         echo "Changelog size $size1"
21599
21600         rm -rf $DIR/$tdir
21601         $LFS mkdir -i 0 $DIR/$tdir
21602         # change something
21603         mkdir -p $DIR/$tdir/pics/2008/zachy
21604         touch $DIR/$tdir/pics/2008/zachy/timestamp
21605         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21606         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21607         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21608         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21609         rm $DIR/$tdir/pics/desktop.jpg
21610
21611         local size2=$(do_facet $SINGLEMDS \
21612                       $LCTL get_param -n mdd.$mdt.changelog_size)
21613         echo "Changelog size after work $size2"
21614
21615         (( $size2 > $size1 )) ||
21616                 error "new Changelog size=$size2 less than old size=$size1"
21617 }
21618 run_test 254 "Check changelog size"
21619
21620 ladvise_no_type()
21621 {
21622         local type=$1
21623         local file=$2
21624
21625         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21626                 awk -F: '{print $2}' | grep $type > /dev/null
21627         if [ $? -ne 0 ]; then
21628                 return 0
21629         fi
21630         return 1
21631 }
21632
21633 ladvise_no_ioctl()
21634 {
21635         local file=$1
21636
21637         lfs ladvise -a willread $file > /dev/null 2>&1
21638         if [ $? -eq 0 ]; then
21639                 return 1
21640         fi
21641
21642         lfs ladvise -a willread $file 2>&1 |
21643                 grep "Inappropriate ioctl for device" > /dev/null
21644         if [ $? -eq 0 ]; then
21645                 return 0
21646         fi
21647         return 1
21648 }
21649
21650 percent() {
21651         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21652 }
21653
21654 # run a random read IO workload
21655 # usage: random_read_iops <filename> <filesize> <iosize>
21656 random_read_iops() {
21657         local file=$1
21658         local fsize=$2
21659         local iosize=${3:-4096}
21660
21661         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21662                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21663 }
21664
21665 drop_file_oss_cache() {
21666         local file="$1"
21667         local nodes="$2"
21668
21669         $LFS ladvise -a dontneed $file 2>/dev/null ||
21670                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21671 }
21672
21673 ladvise_willread_performance()
21674 {
21675         local repeat=10
21676         local average_origin=0
21677         local average_cache=0
21678         local average_ladvise=0
21679
21680         for ((i = 1; i <= $repeat; i++)); do
21681                 echo "Iter $i/$repeat: reading without willread hint"
21682                 cancel_lru_locks osc
21683                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21684                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21685                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21686                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21687
21688                 cancel_lru_locks osc
21689                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21690                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21691                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21692
21693                 cancel_lru_locks osc
21694                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21695                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21696                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21697                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21698                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21699         done
21700         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21701         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21702         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21703
21704         speedup_cache=$(percent $average_cache $average_origin)
21705         speedup_ladvise=$(percent $average_ladvise $average_origin)
21706
21707         echo "Average uncached read: $average_origin"
21708         echo "Average speedup with OSS cached read: " \
21709                 "$average_cache = +$speedup_cache%"
21710         echo "Average speedup with ladvise willread: " \
21711                 "$average_ladvise = +$speedup_ladvise%"
21712
21713         local lowest_speedup=20
21714         if (( ${average_cache%.*} < $lowest_speedup )); then
21715                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
21716                      " got $average_cache%. Skipping ladvise willread check."
21717                 return 0
21718         fi
21719
21720         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21721         # it is still good to run until then to exercise 'ladvise willread'
21722         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21723                 [ "$ost1_FSTYPE" = "zfs" ] &&
21724                 echo "osd-zfs does not support dontneed or drop_caches" &&
21725                 return 0
21726
21727         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21728         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
21729                 error_not_in_vm "Speedup with willread is less than " \
21730                         "$lowest_speedup%, got $average_ladvise%"
21731 }
21732
21733 test_255a() {
21734         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21735                 skip "lustre < 2.8.54 does not support ladvise "
21736         remote_ost_nodsh && skip "remote OST with nodsh"
21737
21738         stack_trap "rm -f $DIR/$tfile"
21739         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21740
21741         ladvise_no_type willread $DIR/$tfile &&
21742                 skip "willread ladvise is not supported"
21743
21744         ladvise_no_ioctl $DIR/$tfile &&
21745                 skip "ladvise ioctl is not supported"
21746
21747         local size_mb=100
21748         local size=$((size_mb * 1048576))
21749         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21750                 error "dd to $DIR/$tfile failed"
21751
21752         lfs ladvise -a willread $DIR/$tfile ||
21753                 error "Ladvise failed with no range argument"
21754
21755         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21756                 error "Ladvise failed with no -l or -e argument"
21757
21758         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21759                 error "Ladvise failed with only -e argument"
21760
21761         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21762                 error "Ladvise failed with only -l argument"
21763
21764         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21765                 error "End offset should not be smaller than start offset"
21766
21767         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21768                 error "End offset should not be equal to start offset"
21769
21770         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21771                 error "Ladvise failed with overflowing -s argument"
21772
21773         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21774                 error "Ladvise failed with overflowing -e argument"
21775
21776         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21777                 error "Ladvise failed with overflowing -l argument"
21778
21779         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21780                 error "Ladvise succeeded with conflicting -l and -e arguments"
21781
21782         echo "Synchronous ladvise should wait"
21783         local delay=4
21784 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21785         do_nodes $(comma_list $(osts_nodes)) \
21786                 $LCTL set_param fail_val=$delay fail_loc=0x237
21787
21788         local start_ts=$SECONDS
21789         lfs ladvise -a willread $DIR/$tfile ||
21790                 error "Ladvise failed with no range argument"
21791         local end_ts=$SECONDS
21792         local inteval_ts=$((end_ts - start_ts))
21793
21794         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21795                 error "Synchronous advice didn't wait reply"
21796         fi
21797
21798         echo "Asynchronous ladvise shouldn't wait"
21799         local start_ts=$SECONDS
21800         lfs ladvise -a willread -b $DIR/$tfile ||
21801                 error "Ladvise failed with no range argument"
21802         local end_ts=$SECONDS
21803         local inteval_ts=$((end_ts - start_ts))
21804
21805         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21806                 error "Asynchronous advice blocked"
21807         fi
21808
21809         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21810         ladvise_willread_performance
21811 }
21812 run_test 255a "check 'lfs ladvise -a willread'"
21813
21814 facet_meminfo() {
21815         local facet=$1
21816         local info=$2
21817
21818         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21819 }
21820
21821 test_255b() {
21822         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21823                 skip "lustre < 2.8.54 does not support ladvise "
21824         remote_ost_nodsh && skip "remote OST with nodsh"
21825
21826         stack_trap "rm -f $DIR/$tfile"
21827         lfs setstripe -c 1 -i 0 $DIR/$tfile
21828
21829         ladvise_no_type dontneed $DIR/$tfile &&
21830                 skip "dontneed ladvise is not supported"
21831
21832         ladvise_no_ioctl $DIR/$tfile &&
21833                 skip "ladvise ioctl is not supported"
21834
21835         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21836                 [ "$ost1_FSTYPE" = "zfs" ] &&
21837                 skip "zfs-osd does not support 'ladvise dontneed'"
21838
21839         local size_mb=100
21840         local size=$((size_mb * 1048576))
21841         # In order to prevent disturbance of other processes, only check 3/4
21842         # of the memory usage
21843         local kibibytes=$((size_mb * 1024 * 3 / 4))
21844
21845         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21846                 error "dd to $DIR/$tfile failed"
21847
21848         #force write to complete before dropping OST cache & checking memory
21849         sync
21850
21851         local total=$(facet_meminfo ost1 MemTotal)
21852         echo "Total memory: $total KiB"
21853
21854         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21855         local before_read=$(facet_meminfo ost1 Cached)
21856         echo "Cache used before read: $before_read KiB"
21857
21858         lfs ladvise -a willread $DIR/$tfile ||
21859                 error "Ladvise willread failed"
21860         local after_read=$(facet_meminfo ost1 Cached)
21861         echo "Cache used after read: $after_read KiB"
21862
21863         lfs ladvise -a dontneed $DIR/$tfile ||
21864                 error "Ladvise dontneed again failed"
21865         local no_read=$(facet_meminfo ost1 Cached)
21866         echo "Cache used after dontneed ladvise: $no_read KiB"
21867
21868         if [ $total -lt $((before_read + kibibytes)) ]; then
21869                 echo "Memory is too small, abort checking"
21870                 return 0
21871         fi
21872
21873         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21874                 error "Ladvise willread should use more memory" \
21875                         "than $kibibytes KiB"
21876         fi
21877
21878         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21879                 error "Ladvise dontneed should release more memory" \
21880                         "than $kibibytes KiB"
21881         fi
21882 }
21883 run_test 255b "check 'lfs ladvise -a dontneed'"
21884
21885 test_255c() {
21886         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21887                 skip "lustre < 2.10.50 does not support lockahead"
21888
21889         local ost1_imp=$(get_osc_import_name client ost1)
21890         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21891                          cut -d'.' -f2)
21892         local count
21893         local new_count
21894         local difference
21895         local i
21896         local rc
21897
21898         test_mkdir -p $DIR/$tdir
21899         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21900
21901         #test 10 returns only success/failure
21902         i=10
21903         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21904         rc=$?
21905         if [ $rc -eq 255 ]; then
21906                 error "Ladvise test${i} failed, ${rc}"
21907         fi
21908
21909         #test 11 counts lock enqueue requests, all others count new locks
21910         i=11
21911         count=$(do_facet ost1 \
21912                 $LCTL get_param -n ost.OSS.ost.stats)
21913         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21914
21915         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21916         rc=$?
21917         if [ $rc -eq 255 ]; then
21918                 error "Ladvise test${i} failed, ${rc}"
21919         fi
21920
21921         new_count=$(do_facet ost1 \
21922                 $LCTL get_param -n ost.OSS.ost.stats)
21923         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21924                    awk '{ print $2 }')
21925
21926         difference="$((new_count - count))"
21927         if [ $difference -ne $rc ]; then
21928                 error "Ladvise test${i}, bad enqueue count, returned " \
21929                       "${rc}, actual ${difference}"
21930         fi
21931
21932         for i in $(seq 12 21); do
21933                 # If we do not do this, we run the risk of having too many
21934                 # locks and starting lock cancellation while we are checking
21935                 # lock counts.
21936                 cancel_lru_locks osc
21937
21938                 count=$($LCTL get_param -n \
21939                        ldlm.namespaces.$imp_name.lock_unused_count)
21940
21941                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21942                 rc=$?
21943                 if [ $rc -eq 255 ]; then
21944                         error "Ladvise test ${i} failed, ${rc}"
21945                 fi
21946
21947                 new_count=$($LCTL get_param -n \
21948                        ldlm.namespaces.$imp_name.lock_unused_count)
21949                 difference="$((new_count - count))"
21950
21951                 # Test 15 output is divided by 100 to map down to valid return
21952                 if [ $i -eq 15 ]; then
21953                         rc="$((rc * 100))"
21954                 fi
21955
21956                 if [ $difference -ne $rc ]; then
21957                         error "Ladvise test ${i}, bad lock count, returned " \
21958                               "${rc}, actual ${difference}"
21959                 fi
21960         done
21961
21962         #test 22 returns only success/failure
21963         i=22
21964         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21965         rc=$?
21966         if [ $rc -eq 255 ]; then
21967                 error "Ladvise test${i} failed, ${rc}"
21968         fi
21969 }
21970 run_test 255c "suite of ladvise lockahead tests"
21971
21972 test_256() {
21973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21974         remote_mds_nodsh && skip "remote MDS with nodsh"
21975         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21976         changelog_users $SINGLEMDS | grep "^cl" &&
21977                 skip "active changelog user"
21978
21979         local cl_user
21980         local cat_sl
21981         local mdt_dev
21982
21983         mdt_dev=$(facet_device $SINGLEMDS)
21984         echo $mdt_dev
21985
21986         changelog_register || error "changelog_register failed"
21987
21988         rm -rf $DIR/$tdir
21989         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
21990
21991         changelog_clear 0 || error "changelog_clear failed"
21992
21993         # change something
21994         touch $DIR/$tdir/{1..10}
21995
21996         # stop the MDT
21997         stop $SINGLEMDS || error "Fail to stop MDT"
21998
21999         # remount the MDT
22000         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22001                 error "Fail to start MDT"
22002
22003         #after mount new plainllog is used
22004         touch $DIR/$tdir/{11..19}
22005         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
22006         stack_trap "rm -f $tmpfile"
22007         cat_sl=$(do_facet $SINGLEMDS "sync; \
22008                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22009                  llog_reader $tmpfile | grep -c type=1064553b")
22010         do_facet $SINGLEMDS llog_reader $tmpfile
22011
22012         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
22013
22014         changelog_clear 0 || error "changelog_clear failed"
22015
22016         cat_sl=$(do_facet $SINGLEMDS "sync; \
22017                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22018                  llog_reader $tmpfile | grep -c type=1064553b")
22019
22020         if (( cat_sl == 2 )); then
22021                 error "Empty plain llog was not deleted from changelog catalog"
22022         elif (( cat_sl != 1 )); then
22023                 error "Active plain llog shouldn't be deleted from catalog"
22024         fi
22025 }
22026 run_test 256 "Check llog delete for empty and not full state"
22027
22028 test_257() {
22029         remote_mds_nodsh && skip "remote MDS with nodsh"
22030         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22031                 skip "Need MDS version at least 2.8.55"
22032
22033         test_mkdir $DIR/$tdir
22034
22035         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
22036                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
22037         stat $DIR/$tdir
22038
22039 #define OBD_FAIL_MDS_XATTR_REP                  0x161
22040         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22041         local facet=mds$((mdtidx + 1))
22042         set_nodes_failloc $(facet_active_host $facet) 0x80000161
22043         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
22044
22045         stop $facet || error "stop MDS failed"
22046         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
22047                 error "start MDS fail"
22048         wait_recovery_complete $facet
22049 }
22050 run_test 257 "xattr locks are not lost"
22051
22052 # Verify we take the i_mutex when security requires it
22053 test_258a() {
22054 #define OBD_FAIL_IMUTEX_SEC 0x141c
22055         $LCTL set_param fail_loc=0x141c
22056         touch $DIR/$tfile
22057         chmod u+s $DIR/$tfile
22058         chmod a+rwx $DIR/$tfile
22059         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22060         RC=$?
22061         if [ $RC -ne 0 ]; then
22062                 error "error, failed to take i_mutex, rc=$?"
22063         fi
22064         rm -f $DIR/$tfile
22065 }
22066 run_test 258a "verify i_mutex security behavior when suid attributes is set"
22067
22068 # Verify we do NOT take the i_mutex in the normal case
22069 test_258b() {
22070 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
22071         $LCTL set_param fail_loc=0x141d
22072         touch $DIR/$tfile
22073         chmod a+rwx $DIR
22074         chmod a+rw $DIR/$tfile
22075         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22076         RC=$?
22077         if [ $RC -ne 0 ]; then
22078                 error "error, took i_mutex unnecessarily, rc=$?"
22079         fi
22080         rm -f $DIR/$tfile
22081
22082 }
22083 run_test 258b "verify i_mutex security behavior"
22084
22085 test_259() {
22086         local file=$DIR/$tfile
22087         local before
22088         local after
22089
22090         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22091
22092         stack_trap "rm -f $file" EXIT
22093
22094         wait_delete_completed
22095         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22096         echo "before: $before"
22097
22098         $LFS setstripe -i 0 -c 1 $file
22099         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
22100         sync_all_data
22101         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22102         echo "after write: $after"
22103
22104 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22105         do_facet ost1 $LCTL set_param fail_loc=0x2301
22106         $TRUNCATE $file 0
22107         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22108         echo "after truncate: $after"
22109
22110         stop ost1
22111         do_facet ost1 $LCTL set_param fail_loc=0
22112         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22113         sleep 2
22114         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22115         echo "after restart: $after"
22116         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22117                 error "missing truncate?"
22118
22119         return 0
22120 }
22121 run_test 259 "crash at delayed truncate"
22122
22123 test_260() {
22124 #define OBD_FAIL_MDC_CLOSE               0x806
22125         $LCTL set_param fail_loc=0x80000806
22126         touch $DIR/$tfile
22127
22128 }
22129 run_test 260 "Check mdc_close fail"
22130
22131 ### Data-on-MDT sanity tests ###
22132 test_270a() {
22133         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22134                 skip "Need MDS version at least 2.10.55 for DoM"
22135
22136         # create DoM file
22137         local dom=$DIR/$tdir/dom_file
22138         local tmp=$DIR/$tdir/tmp_file
22139
22140         mkdir_on_mdt0 $DIR/$tdir
22141
22142         # basic checks for DoM component creation
22143         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22144                 error "Can set MDT layout to non-first entry"
22145
22146         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22147                 error "Can define multiple entries as MDT layout"
22148
22149         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22150
22151         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22152         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22153         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22154
22155         local mdtidx=$($LFS getstripe -m $dom)
22156         local mdtname=MDT$(printf %04x $mdtidx)
22157         local facet=mds$((mdtidx + 1))
22158         local space_check=1
22159
22160         # Skip free space checks with ZFS
22161         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22162
22163         # write
22164         sync
22165         local size_tmp=$((65536 * 3))
22166         local mdtfree1=$(do_facet $facet \
22167                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22168
22169         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22170         # check also direct IO along write
22171         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22172         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22173         sync
22174         cmp $tmp $dom || error "file data is different"
22175         [ $(stat -c%s $dom) == $size_tmp ] ||
22176                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22177         if [ $space_check == 1 ]; then
22178                 local mdtfree2=$(do_facet $facet \
22179                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22180
22181                 # increase in usage from by $size_tmp
22182                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22183                         error "MDT free space wrong after write: " \
22184                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22185         fi
22186
22187         # truncate
22188         local size_dom=10000
22189
22190         $TRUNCATE $dom $size_dom
22191         [ $(stat -c%s $dom) == $size_dom ] ||
22192                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22193         if [ $space_check == 1 ]; then
22194                 mdtfree1=$(do_facet $facet \
22195                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22196                 # decrease in usage from $size_tmp to new $size_dom
22197                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22198                   $(((size_tmp - size_dom) / 1024)) ] ||
22199                         error "MDT free space is wrong after truncate: " \
22200                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22201         fi
22202
22203         # append
22204         cat $tmp >> $dom
22205         sync
22206         size_dom=$((size_dom + size_tmp))
22207         [ $(stat -c%s $dom) == $size_dom ] ||
22208                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22209         if [ $space_check == 1 ]; then
22210                 mdtfree2=$(do_facet $facet \
22211                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22212                 # increase in usage by $size_tmp from previous
22213                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22214                         error "MDT free space is wrong after append: " \
22215                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22216         fi
22217
22218         # delete
22219         rm $dom
22220         if [ $space_check == 1 ]; then
22221                 mdtfree1=$(do_facet $facet \
22222                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22223                 # decrease in usage by $size_dom from previous
22224                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22225                         error "MDT free space is wrong after removal: " \
22226                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22227         fi
22228
22229         # combined striping
22230         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22231                 error "Can't create DoM + OST striping"
22232
22233         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22234         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22235         # check also direct IO along write
22236         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22237         sync
22238         cmp $tmp $dom || error "file data is different"
22239         [ $(stat -c%s $dom) == $size_tmp ] ||
22240                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22241         rm $dom $tmp
22242
22243         return 0
22244 }
22245 run_test 270a "DoM: basic functionality tests"
22246
22247 test_270b() {
22248         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22249                 skip "Need MDS version at least 2.10.55"
22250
22251         local dom=$DIR/$tdir/dom_file
22252         local max_size=1048576
22253
22254         mkdir -p $DIR/$tdir
22255         $LFS setstripe -E $max_size -L mdt $dom
22256
22257         # truncate over the limit
22258         $TRUNCATE $dom $(($max_size + 1)) &&
22259                 error "successful truncate over the maximum size"
22260         # write over the limit
22261         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22262                 error "successful write over the maximum size"
22263         # append over the limit
22264         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22265         echo "12345" >> $dom && error "successful append over the maximum size"
22266         rm $dom
22267
22268         return 0
22269 }
22270 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22271
22272 test_270c() {
22273         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22274                 skip "Need MDS version at least 2.10.55"
22275
22276         mkdir -p $DIR/$tdir
22277         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22278
22279         # check files inherit DoM EA
22280         touch $DIR/$tdir/first
22281         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22282                 error "bad pattern"
22283         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22284                 error "bad stripe count"
22285         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22286                 error "bad stripe size"
22287
22288         # check directory inherits DoM EA and uses it as default
22289         mkdir $DIR/$tdir/subdir
22290         touch $DIR/$tdir/subdir/second
22291         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22292                 error "bad pattern in sub-directory"
22293         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22294                 error "bad stripe count in sub-directory"
22295         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22296                 error "bad stripe size in sub-directory"
22297         return 0
22298 }
22299 run_test 270c "DoM: DoM EA inheritance tests"
22300
22301 test_270d() {
22302         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22303                 skip "Need MDS version at least 2.10.55"
22304
22305         mkdir -p $DIR/$tdir
22306         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22307
22308         # inherit default DoM striping
22309         mkdir $DIR/$tdir/subdir
22310         touch $DIR/$tdir/subdir/f1
22311
22312         # change default directory striping
22313         $LFS setstripe -c 1 $DIR/$tdir/subdir
22314         touch $DIR/$tdir/subdir/f2
22315         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22316                 error "wrong default striping in file 2"
22317         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22318                 error "bad pattern in file 2"
22319         return 0
22320 }
22321 run_test 270d "DoM: change striping from DoM to RAID0"
22322
22323 test_270e() {
22324         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22325                 skip "Need MDS version at least 2.10.55"
22326
22327         mkdir -p $DIR/$tdir/dom
22328         mkdir -p $DIR/$tdir/norm
22329         DOMFILES=20
22330         NORMFILES=10
22331         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22332         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22333
22334         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22335         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22336
22337         # find DoM files by layout
22338         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22339         [ $NUM -eq  $DOMFILES ] ||
22340                 error "lfs find -L: found $NUM, expected $DOMFILES"
22341         echo "Test 1: lfs find 20 DOM files by layout: OK"
22342
22343         # there should be 1 dir with default DOM striping
22344         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22345         [ $NUM -eq  1 ] ||
22346                 error "lfs find -L: found $NUM, expected 1 dir"
22347         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22348
22349         # find DoM files by stripe size
22350         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22351         [ $NUM -eq  $DOMFILES ] ||
22352                 error "lfs find -S: found $NUM, expected $DOMFILES"
22353         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22354
22355         # find files by stripe offset except DoM files
22356         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22357         [ $NUM -eq  $NORMFILES ] ||
22358                 error "lfs find -i: found $NUM, expected $NORMFILES"
22359         echo "Test 5: lfs find no DOM files by stripe index: OK"
22360         return 0
22361 }
22362 run_test 270e "DoM: lfs find with DoM files test"
22363
22364 test_270f() {
22365         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22366                 skip "Need MDS version at least 2.10.55"
22367
22368         local mdtname=${FSNAME}-MDT0000-mdtlov
22369         local dom=$DIR/$tdir/dom_file
22370         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22371                                                 lod.$mdtname.dom_stripesize)
22372         local dom_limit=131072
22373
22374         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22375         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22376                                                 lod.$mdtname.dom_stripesize)
22377         [ ${dom_limit} -eq ${dom_current} ] ||
22378                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22379
22380         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22381         $LFS setstripe -d $DIR/$tdir
22382         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22383                 error "Can't set directory default striping"
22384
22385         # exceed maximum stripe size
22386         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22387                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22388         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22389                 error "Able to create DoM component size more than LOD limit"
22390
22391         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22392         dom_current=$(do_facet mds1 $LCTL get_param -n \
22393                                                 lod.$mdtname.dom_stripesize)
22394         [ 0 -eq ${dom_current} ] ||
22395                 error "Can't set zero DoM stripe limit"
22396         rm $dom
22397
22398         # attempt to create DoM file on server with disabled DoM should
22399         # remove DoM entry from layout and be succeed
22400         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22401                 error "Can't create DoM file (DoM is disabled)"
22402         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22403                 error "File has DoM component while DoM is disabled"
22404         rm $dom
22405
22406         # attempt to create DoM file with only DoM stripe should return error
22407         $LFS setstripe -E $dom_limit -L mdt $dom &&
22408                 error "Able to create DoM-only file while DoM is disabled"
22409
22410         # too low values to be aligned with smallest stripe size 64K
22411         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22412         dom_current=$(do_facet mds1 $LCTL get_param -n \
22413                                                 lod.$mdtname.dom_stripesize)
22414         [ 30000 -eq ${dom_current} ] &&
22415                 error "Can set too small DoM stripe limit"
22416
22417         # 64K is a minimal stripe size in Lustre, expect limit of that size
22418         [ 65536 -eq ${dom_current} ] ||
22419                 error "Limit is not set to 64K but ${dom_current}"
22420
22421         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22422         dom_current=$(do_facet mds1 $LCTL get_param -n \
22423                                                 lod.$mdtname.dom_stripesize)
22424         echo $dom_current
22425         [ 2147483648 -eq ${dom_current} ] &&
22426                 error "Can set too large DoM stripe limit"
22427
22428         do_facet mds1 $LCTL set_param -n \
22429                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22430         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22431                 error "Can't create DoM component size after limit change"
22432         do_facet mds1 $LCTL set_param -n \
22433                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22434         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22435                 error "Can't create DoM file after limit decrease"
22436         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22437                 error "Can create big DoM component after limit decrease"
22438         touch ${dom}_def ||
22439                 error "Can't create file with old default layout"
22440
22441         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22442         return 0
22443 }
22444 run_test 270f "DoM: maximum DoM stripe size checks"
22445
22446 test_270g() {
22447         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22448                 skip "Need MDS version at least 2.13.52"
22449         local dom=$DIR/$tdir/$tfile
22450
22451         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22452         local lodname=${FSNAME}-MDT0000-mdtlov
22453
22454         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22455         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22456         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22457         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22458
22459         local dom_limit=1024
22460         local dom_threshold="50%"
22461
22462         $LFS setstripe -d $DIR/$tdir
22463         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22464                 error "Can't set directory default striping"
22465
22466         do_facet mds1 $LCTL set_param -n \
22467                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22468         # set 0 threshold and create DOM file to change tunable stripesize
22469         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22470         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22471                 error "Failed to create $dom file"
22472         # now tunable dom_cur_stripesize should reach maximum
22473         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22474                                         lod.${lodname}.dom_stripesize_cur_kb)
22475         [[ $dom_current == $dom_limit ]] ||
22476                 error "Current DOM stripesize is not maximum"
22477         rm $dom
22478
22479         # set threshold for further tests
22480         do_facet mds1 $LCTL set_param -n \
22481                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22482         echo "DOM threshold is $dom_threshold free space"
22483         local dom_def
22484         local dom_set
22485         # Spoof bfree to exceed threshold
22486         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22487         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22488         for spfree in 40 20 0 15 30 55; do
22489                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22490                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22491                         error "Failed to create $dom file"
22492                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22493                                         lod.${lodname}.dom_stripesize_cur_kb)
22494                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22495                 [[ $dom_def != $dom_current ]] ||
22496                         error "Default stripe size was not changed"
22497                 if (( spfree > 0 )) ; then
22498                         dom_set=$($LFS getstripe -S $dom)
22499                         (( dom_set == dom_def * 1024 )) ||
22500                                 error "DOM component size is still old"
22501                 else
22502                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22503                                 error "DoM component is set with no free space"
22504                 fi
22505                 rm $dom
22506                 dom_current=$dom_def
22507         done
22508 }
22509 run_test 270g "DoM: default DoM stripe size depends on free space"
22510
22511 test_270h() {
22512         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22513                 skip "Need MDS version at least 2.13.53"
22514
22515         local mdtname=${FSNAME}-MDT0000-mdtlov
22516         local dom=$DIR/$tdir/$tfile
22517         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22518
22519         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22520         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22521
22522         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22523         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22524                 error "can't create OST file"
22525         # mirrored file with DOM entry in the second mirror
22526         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22527                 error "can't create mirror with DoM component"
22528
22529         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22530
22531         # DOM component in the middle and has other enries in the same mirror,
22532         # should succeed but lost DoM component
22533         $LFS setstripe --copy=${dom}_1 $dom ||
22534                 error "Can't create file from OST|DOM mirror layout"
22535         # check new file has no DoM layout after all
22536         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22537                 error "File has DoM component while DoM is disabled"
22538 }
22539 run_test 270h "DoM: DoM stripe removal when disabled on server"
22540
22541 test_270i() {
22542         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22543                 skip "Need MDS version at least 2.14.54"
22544
22545         mkdir $DIR/$tdir
22546         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22547                 error "setstripe should fail" || true
22548 }
22549 run_test 270i "DoM: setting invalid DoM striping should fail"
22550
22551 test_271a() {
22552         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22553                 skip "Need MDS version at least 2.10.55"
22554
22555         local dom=$DIR/$tdir/dom
22556
22557         mkdir -p $DIR/$tdir
22558
22559         $LFS setstripe -E 1024K -L mdt $dom
22560
22561         lctl set_param -n mdc.*.stats=clear
22562         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22563         cat $dom > /dev/null
22564         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22565         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22566         ls $dom
22567         rm -f $dom
22568 }
22569 run_test 271a "DoM: data is cached for read after write"
22570
22571 test_271b() {
22572         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22573                 skip "Need MDS version at least 2.10.55"
22574
22575         local dom=$DIR/$tdir/dom
22576
22577         mkdir -p $DIR/$tdir
22578
22579         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22580
22581         lctl set_param -n mdc.*.stats=clear
22582         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22583         cancel_lru_locks mdc
22584         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22585         # second stat to check size is cached on client
22586         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22587         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22588         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22589         rm -f $dom
22590 }
22591 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22592
22593 test_271ba() {
22594         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22595                 skip "Need MDS version at least 2.10.55"
22596
22597         local dom=$DIR/$tdir/dom
22598
22599         mkdir -p $DIR/$tdir
22600
22601         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22602
22603         lctl set_param -n mdc.*.stats=clear
22604         lctl set_param -n osc.*.stats=clear
22605         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22606         cancel_lru_locks mdc
22607         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22608         # second stat to check size is cached on client
22609         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22610         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22611         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22612         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22613         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22614         rm -f $dom
22615 }
22616 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22617
22618
22619 get_mdc_stats() {
22620         local mdtidx=$1
22621         local param=$2
22622         local mdt=MDT$(printf %04x $mdtidx)
22623
22624         if [ -z $param ]; then
22625                 lctl get_param -n mdc.*$mdt*.stats
22626         else
22627                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22628         fi
22629 }
22630
22631 test_271c() {
22632         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22633                 skip "Need MDS version at least 2.10.55"
22634
22635         local dom=$DIR/$tdir/dom
22636
22637         mkdir -p $DIR/$tdir
22638
22639         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22640
22641         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22642         local facet=mds$((mdtidx + 1))
22643
22644         cancel_lru_locks mdc
22645         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22646         createmany -o $dom 1000
22647         lctl set_param -n mdc.*.stats=clear
22648         smalliomany -w $dom 1000 200
22649         get_mdc_stats $mdtidx
22650         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22651         # Each file has 1 open, 1 IO enqueues, total 2000
22652         # but now we have also +1 getxattr for security.capability, total 3000
22653         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22654         unlinkmany $dom 1000
22655
22656         cancel_lru_locks mdc
22657         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22658         createmany -o $dom 1000
22659         lctl set_param -n mdc.*.stats=clear
22660         smalliomany -w $dom 1000 200
22661         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22662         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22663         # for OPEN and IO lock.
22664         [ $((enq - enq_2)) -ge 1000 ] ||
22665                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22666         unlinkmany $dom 1000
22667         return 0
22668 }
22669 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22670
22671 cleanup_271def_tests() {
22672         trap 0
22673         rm -f $1
22674 }
22675
22676 test_271d() {
22677         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22678                 skip "Need MDS version at least 2.10.57"
22679
22680         local dom=$DIR/$tdir/dom
22681         local tmp=$TMP/$tfile
22682         trap "cleanup_271def_tests $tmp" EXIT
22683
22684         mkdir -p $DIR/$tdir
22685
22686         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22687
22688         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22689
22690         cancel_lru_locks mdc
22691         dd if=/dev/urandom of=$tmp bs=1000 count=1
22692         dd if=$tmp of=$dom bs=1000 count=1
22693         cancel_lru_locks mdc
22694
22695         cat /etc/hosts >> $tmp
22696         lctl set_param -n mdc.*.stats=clear
22697
22698         # append data to the same file it should update local page
22699         echo "Append to the same page"
22700         cat /etc/hosts >> $dom
22701         local num=$(get_mdc_stats $mdtidx ost_read)
22702         local ra=$(get_mdc_stats $mdtidx req_active)
22703         local rw=$(get_mdc_stats $mdtidx req_waittime)
22704
22705         [ -z $num ] || error "$num READ RPC occured"
22706         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22707         echo "... DONE"
22708
22709         # compare content
22710         cmp $tmp $dom || error "file miscompare"
22711
22712         cancel_lru_locks mdc
22713         lctl set_param -n mdc.*.stats=clear
22714
22715         echo "Open and read file"
22716         cat $dom > /dev/null
22717         local num=$(get_mdc_stats $mdtidx ost_read)
22718         local ra=$(get_mdc_stats $mdtidx req_active)
22719         local rw=$(get_mdc_stats $mdtidx req_waittime)
22720
22721         [ -z $num ] || error "$num READ RPC occured"
22722         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22723         echo "... DONE"
22724
22725         # compare content
22726         cmp $tmp $dom || error "file miscompare"
22727
22728         return 0
22729 }
22730 run_test 271d "DoM: read on open (1K file in reply buffer)"
22731
22732 test_271f() {
22733         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22734                 skip "Need MDS version at least 2.10.57"
22735
22736         local dom=$DIR/$tdir/dom
22737         local tmp=$TMP/$tfile
22738         trap "cleanup_271def_tests $tmp" EXIT
22739
22740         mkdir -p $DIR/$tdir
22741
22742         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22743
22744         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22745
22746         cancel_lru_locks mdc
22747         dd if=/dev/urandom of=$tmp bs=265000 count=1
22748         dd if=$tmp of=$dom bs=265000 count=1
22749         cancel_lru_locks mdc
22750         cat /etc/hosts >> $tmp
22751         lctl set_param -n mdc.*.stats=clear
22752
22753         echo "Append to the same page"
22754         cat /etc/hosts >> $dom
22755         local num=$(get_mdc_stats $mdtidx ost_read)
22756         local ra=$(get_mdc_stats $mdtidx req_active)
22757         local rw=$(get_mdc_stats $mdtidx req_waittime)
22758
22759         [ -z $num ] || error "$num READ RPC occured"
22760         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22761         echo "... DONE"
22762
22763         # compare content
22764         cmp $tmp $dom || error "file miscompare"
22765
22766         cancel_lru_locks mdc
22767         lctl set_param -n mdc.*.stats=clear
22768
22769         echo "Open and read file"
22770         cat $dom > /dev/null
22771         local num=$(get_mdc_stats $mdtidx ost_read)
22772         local ra=$(get_mdc_stats $mdtidx req_active)
22773         local rw=$(get_mdc_stats $mdtidx req_waittime)
22774
22775         [ -z $num ] && num=0
22776         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22777         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22778         echo "... DONE"
22779
22780         # compare content
22781         cmp $tmp $dom || error "file miscompare"
22782
22783         return 0
22784 }
22785 run_test 271f "DoM: read on open (200K file and read tail)"
22786
22787 test_271g() {
22788         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22789                 skip "Skipping due to old client or server version"
22790
22791         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22792         # to get layout
22793         $CHECKSTAT -t file $DIR1/$tfile
22794
22795         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22796         MULTIOP_PID=$!
22797         sleep 1
22798         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22799         $LCTL set_param fail_loc=0x80000314
22800         rm $DIR1/$tfile || error "Unlink fails"
22801         RC=$?
22802         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22803         [ $RC -eq 0 ] || error "Failed write to stale object"
22804 }
22805 run_test 271g "Discard DoM data vs client flush race"
22806
22807 test_272a() {
22808         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22809                 skip "Need MDS version at least 2.11.50"
22810
22811         local dom=$DIR/$tdir/dom
22812         mkdir -p $DIR/$tdir
22813
22814         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22815         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22816                 error "failed to write data into $dom"
22817         local old_md5=$(md5sum $dom)
22818
22819         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22820                 error "failed to migrate to the same DoM component"
22821
22822         local new_md5=$(md5sum $dom)
22823
22824         [ "$old_md5" == "$new_md5" ] ||
22825                 error "md5sum differ: $old_md5, $new_md5"
22826
22827         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22828                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22829 }
22830 run_test 272a "DoM migration: new layout with the same DOM component"
22831
22832 test_272b() {
22833         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22834                 skip "Need MDS version at least 2.11.50"
22835
22836         local dom=$DIR/$tdir/dom
22837         mkdir -p $DIR/$tdir
22838         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22839
22840         local mdtidx=$($LFS getstripe -m $dom)
22841         local mdtname=MDT$(printf %04x $mdtidx)
22842         local facet=mds$((mdtidx + 1))
22843
22844         local mdtfree1=$(do_facet $facet \
22845                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22846         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22847                 error "failed to write data into $dom"
22848         local old_md5=$(md5sum $dom)
22849         cancel_lru_locks mdc
22850         local mdtfree1=$(do_facet $facet \
22851                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22852
22853         $LFS migrate -c2 $dom ||
22854                 error "failed to migrate to the new composite layout"
22855         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22856                 error "MDT stripe was not removed"
22857
22858         cancel_lru_locks mdc
22859         local new_md5=$(md5sum $dom)
22860         [ "$old_md5" == "$new_md5" ] ||
22861                 error "$old_md5 != $new_md5"
22862
22863         # Skip free space checks with ZFS
22864         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22865                 local mdtfree2=$(do_facet $facet \
22866                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22867                 [ $mdtfree2 -gt $mdtfree1 ] ||
22868                         error "MDT space is not freed after migration"
22869         fi
22870         return 0
22871 }
22872 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22873
22874 test_272c() {
22875         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22876                 skip "Need MDS version at least 2.11.50"
22877
22878         local dom=$DIR/$tdir/$tfile
22879         mkdir -p $DIR/$tdir
22880         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22881
22882         local mdtidx=$($LFS getstripe -m $dom)
22883         local mdtname=MDT$(printf %04x $mdtidx)
22884         local facet=mds$((mdtidx + 1))
22885
22886         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22887                 error "failed to write data into $dom"
22888         local old_md5=$(md5sum $dom)
22889         cancel_lru_locks mdc
22890         local mdtfree1=$(do_facet $facet \
22891                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22892
22893         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22894                 error "failed to migrate to the new composite layout"
22895         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22896                 error "MDT stripe was not removed"
22897
22898         cancel_lru_locks mdc
22899         local new_md5=$(md5sum $dom)
22900         [ "$old_md5" == "$new_md5" ] ||
22901                 error "$old_md5 != $new_md5"
22902
22903         # Skip free space checks with ZFS
22904         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22905                 local mdtfree2=$(do_facet $facet \
22906                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22907                 [ $mdtfree2 -gt $mdtfree1 ] ||
22908                         error "MDS space is not freed after migration"
22909         fi
22910         return 0
22911 }
22912 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22913
22914 test_272d() {
22915         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22916                 skip "Need MDS version at least 2.12.55"
22917
22918         local dom=$DIR/$tdir/$tfile
22919         mkdir -p $DIR/$tdir
22920         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22921
22922         local mdtidx=$($LFS getstripe -m $dom)
22923         local mdtname=MDT$(printf %04x $mdtidx)
22924         local facet=mds$((mdtidx + 1))
22925
22926         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22927                 error "failed to write data into $dom"
22928         local old_md5=$(md5sum $dom)
22929         cancel_lru_locks mdc
22930         local mdtfree1=$(do_facet $facet \
22931                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22932
22933         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22934                 error "failed mirroring to the new composite layout"
22935         $LFS mirror resync $dom ||
22936                 error "failed mirror resync"
22937         $LFS mirror split --mirror-id 1 -d $dom ||
22938                 error "failed mirror split"
22939
22940         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22941                 error "MDT stripe was not removed"
22942
22943         cancel_lru_locks mdc
22944         local new_md5=$(md5sum $dom)
22945         [ "$old_md5" == "$new_md5" ] ||
22946                 error "$old_md5 != $new_md5"
22947
22948         # Skip free space checks with ZFS
22949         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22950                 local mdtfree2=$(do_facet $facet \
22951                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22952                 [ $mdtfree2 -gt $mdtfree1 ] ||
22953                         error "MDS space is not freed after DOM mirror deletion"
22954         fi
22955         return 0
22956 }
22957 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22958
22959 test_272e() {
22960         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22961                 skip "Need MDS version at least 2.12.55"
22962
22963         local dom=$DIR/$tdir/$tfile
22964         mkdir -p $DIR/$tdir
22965         $LFS setstripe -c 2 $dom
22966
22967         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22968                 error "failed to write data into $dom"
22969         local old_md5=$(md5sum $dom)
22970         cancel_lru_locks
22971
22972         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22973                 error "failed mirroring to the DOM layout"
22974         $LFS mirror resync $dom ||
22975                 error "failed mirror resync"
22976         $LFS mirror split --mirror-id 1 -d $dom ||
22977                 error "failed mirror split"
22978
22979         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22980                 error "MDT stripe wasn't set"
22981
22982         cancel_lru_locks
22983         local new_md5=$(md5sum $dom)
22984         [ "$old_md5" == "$new_md5" ] ||
22985                 error "$old_md5 != $new_md5"
22986
22987         return 0
22988 }
22989 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22990
22991 test_272f() {
22992         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22993                 skip "Need MDS version at least 2.12.55"
22994
22995         local dom=$DIR/$tdir/$tfile
22996         mkdir -p $DIR/$tdir
22997         $LFS setstripe -c 2 $dom
22998
22999         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23000                 error "failed to write data into $dom"
23001         local old_md5=$(md5sum $dom)
23002         cancel_lru_locks
23003
23004         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
23005                 error "failed migrating to the DOM file"
23006
23007         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23008                 error "MDT stripe wasn't set"
23009
23010         cancel_lru_locks
23011         local new_md5=$(md5sum $dom)
23012         [ "$old_md5" != "$new_md5" ] &&
23013                 error "$old_md5 != $new_md5"
23014
23015         return 0
23016 }
23017 run_test 272f "DoM migration: OST-striped file to DOM file"
23018
23019 test_273a() {
23020         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23021                 skip "Need MDS version at least 2.11.50"
23022
23023         # Layout swap cannot be done if either file has DOM component,
23024         # this will never be supported, migration should be used instead
23025
23026         local dom=$DIR/$tdir/$tfile
23027         mkdir -p $DIR/$tdir
23028
23029         $LFS setstripe -c2 ${dom}_plain
23030         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
23031         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
23032                 error "can swap layout with DoM component"
23033         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
23034                 error "can swap layout with DoM component"
23035
23036         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
23037         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
23038                 error "can swap layout with DoM component"
23039         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
23040                 error "can swap layout with DoM component"
23041         return 0
23042 }
23043 run_test 273a "DoM: layout swapping should fail with DOM"
23044
23045 test_273b() {
23046         mkdir -p $DIR/$tdir
23047         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
23048
23049 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
23050         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
23051
23052         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
23053 }
23054 run_test 273b "DoM: race writeback and object destroy"
23055
23056 test_275() {
23057         remote_ost_nodsh && skip "remote OST with nodsh"
23058         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
23059                 skip "Need OST version >= 2.10.57"
23060
23061         local file=$DIR/$tfile
23062         local oss
23063
23064         oss=$(comma_list $(osts_nodes))
23065
23066         dd if=/dev/urandom of=$file bs=1M count=2 ||
23067                 error "failed to create a file"
23068         cancel_lru_locks osc
23069
23070         #lock 1
23071         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23072                 error "failed to read a file"
23073
23074 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
23075         $LCTL set_param fail_loc=0x8000031f
23076
23077         cancel_lru_locks osc &
23078         sleep 1
23079
23080 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
23081         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
23082         #IO takes another lock, but matches the PENDING one
23083         #and places it to the IO RPC
23084         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23085                 error "failed to read a file with PENDING lock"
23086 }
23087 run_test 275 "Read on a canceled duplicate lock"
23088
23089 test_276() {
23090         remote_ost_nodsh && skip "remote OST with nodsh"
23091         local pid
23092
23093         do_facet ost1 "(while true; do \
23094                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
23095                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
23096         pid=$!
23097
23098         for LOOP in $(seq 20); do
23099                 stop ost1
23100                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
23101         done
23102         kill -9 $pid
23103         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23104                 rm $TMP/sanity_276_pid"
23105 }
23106 run_test 276 "Race between mount and obd_statfs"
23107
23108 test_277() {
23109         $LCTL set_param ldlm.namespaces.*.lru_size=0
23110         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23111         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23112                         grep ^used_mb | awk '{print $2}')
23113         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23114         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23115                 oflag=direct conv=notrunc
23116         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23117                         grep ^used_mb | awk '{print $2}')
23118         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23119 }
23120 run_test 277 "Direct IO shall drop page cache"
23121
23122 test_278() {
23123         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23124         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23125         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23126                 skip "needs the same host for mdt1 mdt2" && return
23127
23128         local pid1
23129         local pid2
23130
23131 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
23132         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
23133         stop mds2 &
23134         pid2=$!
23135
23136         stop mds1
23137
23138         echo "Starting MDTs"
23139         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23140         wait $pid2
23141 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23142 #will return NULL
23143         do_facet mds2 $LCTL set_param fail_loc=0
23144
23145         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23146         wait_recovery_complete mds2
23147 }
23148 run_test 278 "Race starting MDS between MDTs stop/start"
23149
23150 test_280() {
23151         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23152                 skip "Need MGS version at least 2.13.52"
23153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23154         combined_mgs_mds || skip "needs combined MGS/MDT"
23155
23156         umount_client $MOUNT
23157 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23158         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23159
23160         mount_client $MOUNT &
23161         sleep 1
23162         stop mgs || error "stop mgs failed"
23163         #for a race mgs would crash
23164         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23165         # make sure we unmount client before remounting
23166         wait
23167         umount_client $MOUNT
23168         mount_client $MOUNT || error "mount client failed"
23169 }
23170 run_test 280 "Race between MGS umount and client llog processing"
23171
23172 cleanup_test_300() {
23173         trap 0
23174         umask $SAVE_UMASK
23175 }
23176 test_striped_dir() {
23177         local mdt_index=$1
23178         local stripe_count
23179         local stripe_index
23180
23181         mkdir -p $DIR/$tdir
23182
23183         SAVE_UMASK=$(umask)
23184         trap cleanup_test_300 RETURN EXIT
23185
23186         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23187                                                 $DIR/$tdir/striped_dir ||
23188                 error "set striped dir error"
23189
23190         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23191         [ "$mode" = "755" ] || error "expect 755 got $mode"
23192
23193         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23194                 error "getdirstripe failed"
23195         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23196         if [ "$stripe_count" != "2" ]; then
23197                 error "1:stripe_count is $stripe_count, expect 2"
23198         fi
23199         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23200         if [ "$stripe_count" != "2" ]; then
23201                 error "2:stripe_count is $stripe_count, expect 2"
23202         fi
23203
23204         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23205         if [ "$stripe_index" != "$mdt_index" ]; then
23206                 error "stripe_index is $stripe_index, expect $mdt_index"
23207         fi
23208
23209         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23210                 error "nlink error after create striped dir"
23211
23212         mkdir $DIR/$tdir/striped_dir/a
23213         mkdir $DIR/$tdir/striped_dir/b
23214
23215         stat $DIR/$tdir/striped_dir/a ||
23216                 error "create dir under striped dir failed"
23217         stat $DIR/$tdir/striped_dir/b ||
23218                 error "create dir under striped dir failed"
23219
23220         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23221                 error "nlink error after mkdir"
23222
23223         rmdir $DIR/$tdir/striped_dir/a
23224         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23225                 error "nlink error after rmdir"
23226
23227         rmdir $DIR/$tdir/striped_dir/b
23228         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23229                 error "nlink error after rmdir"
23230
23231         chattr +i $DIR/$tdir/striped_dir
23232         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23233                 error "immutable flags not working under striped dir!"
23234         chattr -i $DIR/$tdir/striped_dir
23235
23236         rmdir $DIR/$tdir/striped_dir ||
23237                 error "rmdir striped dir error"
23238
23239         cleanup_test_300
23240
23241         true
23242 }
23243
23244 test_300a() {
23245         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23246                 skip "skipped for lustre < 2.7.0"
23247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23248         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23249
23250         test_striped_dir 0 || error "failed on striped dir on MDT0"
23251         test_striped_dir 1 || error "failed on striped dir on MDT0"
23252 }
23253 run_test 300a "basic striped dir sanity test"
23254
23255 test_300b() {
23256         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23257                 skip "skipped for lustre < 2.7.0"
23258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23259         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23260
23261         local i
23262         local mtime1
23263         local mtime2
23264         local mtime3
23265
23266         test_mkdir $DIR/$tdir || error "mkdir fail"
23267         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23268                 error "set striped dir error"
23269         for i in {0..9}; do
23270                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23271                 sleep 1
23272                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23273                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23274                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23275                 sleep 1
23276                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23277                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23278                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23279         done
23280         true
23281 }
23282 run_test 300b "check ctime/mtime for striped dir"
23283
23284 test_300c() {
23285         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23286                 skip "skipped for lustre < 2.7.0"
23287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23288         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23289
23290         local file_count
23291
23292         mkdir_on_mdt0 $DIR/$tdir
23293         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23294                 error "set striped dir error"
23295
23296         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23297                 error "chown striped dir failed"
23298
23299         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23300                 error "create 5k files failed"
23301
23302         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23303
23304         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23305
23306         rm -rf $DIR/$tdir
23307 }
23308 run_test 300c "chown && check ls under striped directory"
23309
23310 test_300d() {
23311         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23312                 skip "skipped for lustre < 2.7.0"
23313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23314         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23315
23316         local stripe_count
23317         local file
23318
23319         mkdir -p $DIR/$tdir
23320         $LFS setstripe -c 2 $DIR/$tdir
23321
23322         #local striped directory
23323         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23324                 error "set striped dir error"
23325         #look at the directories for debug purposes
23326         ls -l $DIR/$tdir
23327         $LFS getdirstripe $DIR/$tdir
23328         ls -l $DIR/$tdir/striped_dir
23329         $LFS getdirstripe $DIR/$tdir/striped_dir
23330         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23331                 error "create 10 files failed"
23332
23333         #remote striped directory
23334         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23335                 error "set striped dir error"
23336         #look at the directories for debug purposes
23337         ls -l $DIR/$tdir
23338         $LFS getdirstripe $DIR/$tdir
23339         ls -l $DIR/$tdir/remote_striped_dir
23340         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23341         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23342                 error "create 10 files failed"
23343
23344         for file in $(find $DIR/$tdir); do
23345                 stripe_count=$($LFS getstripe -c $file)
23346                 [ $stripe_count -eq 2 ] ||
23347                         error "wrong stripe $stripe_count for $file"
23348         done
23349
23350         rm -rf $DIR/$tdir
23351 }
23352 run_test 300d "check default stripe under striped directory"
23353
23354 test_300e() {
23355         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23356                 skip "Need MDS version at least 2.7.55"
23357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23358         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23359
23360         local stripe_count
23361         local file
23362
23363         mkdir -p $DIR/$tdir
23364
23365         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23366                 error "set striped dir error"
23367
23368         touch $DIR/$tdir/striped_dir/a
23369         touch $DIR/$tdir/striped_dir/b
23370         touch $DIR/$tdir/striped_dir/c
23371
23372         mkdir $DIR/$tdir/striped_dir/dir_a
23373         mkdir $DIR/$tdir/striped_dir/dir_b
23374         mkdir $DIR/$tdir/striped_dir/dir_c
23375
23376         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23377                 error "set striped adir under striped dir error"
23378
23379         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23380                 error "set striped bdir under striped dir error"
23381
23382         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23383                 error "set striped cdir under striped dir error"
23384
23385         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23386                 error "rename dir under striped dir fails"
23387
23388         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23389                 error "rename dir under different stripes fails"
23390
23391         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23392                 error "rename file under striped dir should succeed"
23393
23394         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23395                 error "rename dir under striped dir should succeed"
23396
23397         rm -rf $DIR/$tdir
23398 }
23399 run_test 300e "check rename under striped directory"
23400
23401 test_300f() {
23402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23403         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23404         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23405                 skip "Need MDS version at least 2.7.55"
23406
23407         local stripe_count
23408         local file
23409
23410         rm -rf $DIR/$tdir
23411         mkdir -p $DIR/$tdir
23412
23413         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23414                 error "set striped dir error"
23415
23416         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23417                 error "set striped dir error"
23418
23419         touch $DIR/$tdir/striped_dir/a
23420         mkdir $DIR/$tdir/striped_dir/dir_a
23421         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23422                 error "create striped dir under striped dir fails"
23423
23424         touch $DIR/$tdir/striped_dir1/b
23425         mkdir $DIR/$tdir/striped_dir1/dir_b
23426         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23427                 error "create striped dir under striped dir fails"
23428
23429         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23430                 error "rename dir under different striped dir should fail"
23431
23432         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23433                 error "rename striped dir under diff striped dir should fail"
23434
23435         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23436                 error "rename file under diff striped dirs fails"
23437
23438         rm -rf $DIR/$tdir
23439 }
23440 run_test 300f "check rename cross striped directory"
23441
23442 test_300_check_default_striped_dir()
23443 {
23444         local dirname=$1
23445         local default_count=$2
23446         local default_index=$3
23447         local stripe_count
23448         local stripe_index
23449         local dir_stripe_index
23450         local dir
23451
23452         echo "checking $dirname $default_count $default_index"
23453         $LFS setdirstripe -D -c $default_count -i $default_index \
23454                                 -H all_char $DIR/$tdir/$dirname ||
23455                 error "set default stripe on striped dir error"
23456         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23457         [ $stripe_count -eq $default_count ] ||
23458                 error "expect $default_count get $stripe_count for $dirname"
23459
23460         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23461         [ $stripe_index -eq $default_index ] ||
23462                 error "expect $default_index get $stripe_index for $dirname"
23463
23464         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23465                                                 error "create dirs failed"
23466
23467         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23468         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23469         for dir in $(find $DIR/$tdir/$dirname/*); do
23470                 stripe_count=$($LFS getdirstripe -c $dir)
23471                 (( $stripe_count == $default_count )) ||
23472                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23473                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23474                 error "stripe count $default_count != $stripe_count for $dir"
23475
23476                 stripe_index=$($LFS getdirstripe -i $dir)
23477                 [ $default_index -eq -1 ] ||
23478                         [ $stripe_index -eq $default_index ] ||
23479                         error "$stripe_index != $default_index for $dir"
23480
23481                 #check default stripe
23482                 stripe_count=$($LFS getdirstripe -D -c $dir)
23483                 [ $stripe_count -eq $default_count ] ||
23484                 error "default count $default_count != $stripe_count for $dir"
23485
23486                 stripe_index=$($LFS getdirstripe -D -i $dir)
23487                 [ $stripe_index -eq $default_index ] ||
23488                 error "default index $default_index != $stripe_index for $dir"
23489         done
23490         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23491 }
23492
23493 test_300g() {
23494         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23495         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23496                 skip "Need MDS version at least 2.7.55"
23497
23498         local dir
23499         local stripe_count
23500         local stripe_index
23501
23502         mkdir_on_mdt0 $DIR/$tdir
23503         mkdir $DIR/$tdir/normal_dir
23504
23505         #Checking when client cache stripe index
23506         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23507         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23508                 error "create striped_dir failed"
23509
23510         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23511                 error "create dir0 fails"
23512         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23513         [ $stripe_index -eq 0 ] ||
23514                 error "dir0 expect index 0 got $stripe_index"
23515
23516         mkdir $DIR/$tdir/striped_dir/dir1 ||
23517                 error "create dir1 fails"
23518         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23519         [ $stripe_index -eq 1 ] ||
23520                 error "dir1 expect index 1 got $stripe_index"
23521
23522         #check default stripe count/stripe index
23523         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23524         test_300_check_default_striped_dir normal_dir 1 0
23525         test_300_check_default_striped_dir normal_dir -1 1
23526         test_300_check_default_striped_dir normal_dir 2 -1
23527
23528         #delete default stripe information
23529         echo "delete default stripeEA"
23530         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23531                 error "set default stripe on striped dir error"
23532
23533         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23534         for dir in $(find $DIR/$tdir/normal_dir/*); do
23535                 stripe_count=$($LFS getdirstripe -c $dir)
23536                 [ $stripe_count -eq 0 ] ||
23537                         error "expect 1 get $stripe_count for $dir"
23538         done
23539 }
23540 run_test 300g "check default striped directory for normal directory"
23541
23542 test_300h() {
23543         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23544         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23545                 skip "Need MDS version at least 2.7.55"
23546
23547         local dir
23548         local stripe_count
23549
23550         mkdir $DIR/$tdir
23551         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23552                 error "set striped dir error"
23553
23554         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23555         test_300_check_default_striped_dir striped_dir 1 0
23556         test_300_check_default_striped_dir striped_dir -1 1
23557         test_300_check_default_striped_dir striped_dir 2 -1
23558
23559         #delete default stripe information
23560         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23561                 error "set default stripe on striped dir error"
23562
23563         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23564         for dir in $(find $DIR/$tdir/striped_dir/*); do
23565                 stripe_count=$($LFS getdirstripe -c $dir)
23566                 [ $stripe_count -eq 0 ] ||
23567                         error "expect 1 get $stripe_count for $dir"
23568         done
23569 }
23570 run_test 300h "check default striped directory for striped directory"
23571
23572 test_300i() {
23573         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
23574         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
23575         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
23576                 skip "Need MDS version at least 2.7.55"
23577
23578         local stripe_count
23579         local file
23580
23581         mkdir $DIR/$tdir
23582
23583         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23584                 error "set striped dir error"
23585
23586         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23587                 error "create files under striped dir failed"
23588
23589         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23590                 error "set striped hashdir error"
23591
23592         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23593                 error "create dir0 under hash dir failed"
23594         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23595                 error "create dir1 under hash dir failed"
23596         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23597                 error "create dir2 under hash dir failed"
23598
23599         # unfortunately, we need to umount to clear dir layout cache for now
23600         # once we fully implement dir layout, we can drop this
23601         umount_client $MOUNT || error "umount failed"
23602         mount_client $MOUNT || error "mount failed"
23603
23604         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23605         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23606         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
23607
23608         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
23609                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
23610                         error "create crush2 dir $tdir/hashdir/d3 failed"
23611                 $LFS find -H crush2 $DIR/$tdir/hashdir
23612                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
23613                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
23614
23615                 # mkdir with an invalid hash type (hash=fail_val) from client
23616                 # should be replaced on MDS with a valid (default) hash type
23617                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
23618                 $LCTL set_param fail_loc=0x1901 fail_val=99
23619                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
23620
23621                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
23622                 local expect=$(do_facet mds1 \
23623                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
23624                 [[ $hash == $expect ]] ||
23625                         error "d99 hash '$hash' != expected hash '$expect'"
23626         fi
23627
23628         #set the stripe to be unknown hash type on read
23629         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
23630         $LCTL set_param fail_loc=0x1901 fail_val=99
23631         for ((i = 0; i < 10; i++)); do
23632                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23633                         error "stat f-$i failed"
23634                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23635         done
23636
23637         touch $DIR/$tdir/striped_dir/f0 &&
23638                 error "create under striped dir with unknown hash should fail"
23639
23640         $LCTL set_param fail_loc=0
23641
23642         umount_client $MOUNT || error "umount failed"
23643         mount_client $MOUNT || error "mount failed"
23644
23645         return 0
23646 }
23647 run_test 300i "client handle unknown hash type striped directory"
23648
23649 test_300j() {
23650         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23652         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23653                 skip "Need MDS version at least 2.7.55"
23654
23655         local stripe_count
23656         local file
23657
23658         mkdir $DIR/$tdir
23659
23660         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23661         $LCTL set_param fail_loc=0x1702
23662         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23663                 error "set striped dir error"
23664
23665         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23666                 error "create files under striped dir failed"
23667
23668         $LCTL set_param fail_loc=0
23669
23670         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23671
23672         return 0
23673 }
23674 run_test 300j "test large update record"
23675
23676 test_300k() {
23677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23678         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23679         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23680                 skip "Need MDS version at least 2.7.55"
23681
23682         # this test needs a huge transaction
23683         local kb
23684         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23685              osd*.$FSNAME-MDT0000.kbytestotal")
23686         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23687
23688         local stripe_count
23689         local file
23690
23691         mkdir $DIR/$tdir
23692
23693         #define OBD_FAIL_LARGE_STRIPE   0x1703
23694         $LCTL set_param fail_loc=0x1703
23695         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23696                 error "set striped dir error"
23697         $LCTL set_param fail_loc=0
23698
23699         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23700                 error "getstripeddir fails"
23701         rm -rf $DIR/$tdir/striped_dir ||
23702                 error "unlink striped dir fails"
23703
23704         return 0
23705 }
23706 run_test 300k "test large striped directory"
23707
23708 test_300l() {
23709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23710         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23711         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23712                 skip "Need MDS version at least 2.7.55"
23713
23714         local stripe_index
23715
23716         test_mkdir -p $DIR/$tdir/striped_dir
23717         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23718                         error "chown $RUNAS_ID failed"
23719         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23720                 error "set default striped dir failed"
23721
23722         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23723         $LCTL set_param fail_loc=0x80000158
23724         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23725
23726         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23727         [ $stripe_index -eq 1 ] ||
23728                 error "expect 1 get $stripe_index for $dir"
23729 }
23730 run_test 300l "non-root user to create dir under striped dir with stale layout"
23731
23732 test_300m() {
23733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23734         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23735         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23736                 skip "Need MDS version at least 2.7.55"
23737
23738         mkdir -p $DIR/$tdir/striped_dir
23739         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23740                 error "set default stripes dir error"
23741
23742         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23743
23744         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23745         [ $stripe_count -eq 0 ] ||
23746                         error "expect 0 get $stripe_count for a"
23747
23748         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23749                 error "set default stripes dir error"
23750
23751         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23752
23753         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23754         [ $stripe_count -eq 0 ] ||
23755                         error "expect 0 get $stripe_count for b"
23756
23757         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23758                 error "set default stripes dir error"
23759
23760         mkdir $DIR/$tdir/striped_dir/c &&
23761                 error "default stripe_index is invalid, mkdir c should fails"
23762
23763         rm -rf $DIR/$tdir || error "rmdir fails"
23764 }
23765 run_test 300m "setstriped directory on single MDT FS"
23766
23767 cleanup_300n() {
23768         local list=$(comma_list $(mdts_nodes))
23769
23770         trap 0
23771         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23772 }
23773
23774 test_300n() {
23775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23776         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23777         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23778                 skip "Need MDS version at least 2.7.55"
23779         remote_mds_nodsh && skip "remote MDS with nodsh"
23780
23781         local stripe_index
23782         local list=$(comma_list $(mdts_nodes))
23783
23784         trap cleanup_300n RETURN EXIT
23785         mkdir -p $DIR/$tdir
23786         chmod 777 $DIR/$tdir
23787         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23788                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23789                 error "create striped dir succeeds with gid=0"
23790
23791         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23792         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23793                 error "create striped dir fails with gid=-1"
23794
23795         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23796         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23797                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23798                 error "set default striped dir succeeds with gid=0"
23799
23800
23801         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23802         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23803                 error "set default striped dir fails with gid=-1"
23804
23805
23806         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23807         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23808                                         error "create test_dir fails"
23809         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23810                                         error "create test_dir1 fails"
23811         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23812                                         error "create test_dir2 fails"
23813         cleanup_300n
23814 }
23815 run_test 300n "non-root user to create dir under striped dir with default EA"
23816
23817 test_300o() {
23818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23819         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23820         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23821                 skip "Need MDS version at least 2.7.55"
23822
23823         local numfree1
23824         local numfree2
23825
23826         mkdir -p $DIR/$tdir
23827
23828         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23829         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23830         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23831                 skip "not enough free inodes $numfree1 $numfree2"
23832         fi
23833
23834         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23835         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23836         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23837                 skip "not enough free space $numfree1 $numfree2"
23838         fi
23839
23840         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23841                 error "setdirstripe fails"
23842
23843         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23844                 error "create dirs fails"
23845
23846         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23847         ls $DIR/$tdir/striped_dir > /dev/null ||
23848                 error "ls striped dir fails"
23849         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23850                 error "unlink big striped dir fails"
23851 }
23852 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23853
23854 test_300p() {
23855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23856         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23857         remote_mds_nodsh && skip "remote MDS with nodsh"
23858
23859         mkdir_on_mdt0 $DIR/$tdir
23860
23861         #define OBD_FAIL_OUT_ENOSPC     0x1704
23862         do_facet mds2 lctl set_param fail_loc=0x80001704
23863         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23864                  && error "create striped directory should fail"
23865
23866         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23867
23868         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23869         true
23870 }
23871 run_test 300p "create striped directory without space"
23872
23873 test_300q() {
23874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23875         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23876
23877         local fd=$(free_fd)
23878         local cmd="exec $fd<$tdir"
23879         cd $DIR
23880         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23881         eval $cmd
23882         cmd="exec $fd<&-"
23883         trap "eval $cmd" EXIT
23884         cd $tdir || error "cd $tdir fails"
23885         rmdir  ../$tdir || error "rmdir $tdir fails"
23886         mkdir local_dir && error "create dir succeeds"
23887         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23888         eval $cmd
23889         return 0
23890 }
23891 run_test 300q "create remote directory under orphan directory"
23892
23893 test_300r() {
23894         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23895                 skip "Need MDS version at least 2.7.55" && return
23896         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23897
23898         mkdir $DIR/$tdir
23899
23900         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23901                 error "set striped dir error"
23902
23903         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23904                 error "getstripeddir fails"
23905
23906         local stripe_count
23907         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23908                       awk '/lmv_stripe_count:/ { print $2 }')
23909
23910         [ $MDSCOUNT -ne $stripe_count ] &&
23911                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23912
23913         rm -rf $DIR/$tdir/striped_dir ||
23914                 error "unlink striped dir fails"
23915 }
23916 run_test 300r "test -1 striped directory"
23917
23918 test_300s_helper() {
23919         local count=$1
23920
23921         local stripe_dir=$DIR/$tdir/striped_dir.$count
23922
23923         $LFS mkdir -c $count $stripe_dir ||
23924                 error "lfs mkdir -c error"
23925
23926         $LFS getdirstripe $stripe_dir ||
23927                 error "lfs getdirstripe fails"
23928
23929         local stripe_count
23930         stripe_count=$($LFS getdirstripe $stripe_dir |
23931                       awk '/lmv_stripe_count:/ { print $2 }')
23932
23933         [ $count -ne $stripe_count ] &&
23934                 error_noexit "bad stripe count $stripe_count expected $count"
23935
23936         local dupe_stripes
23937         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23938                 awk '/0x/ {count[$1] += 1}; END {
23939                         for (idx in count) {
23940                                 if (count[idx]>1) {
23941                                         print "index " idx " count " count[idx]
23942                                 }
23943                         }
23944                 }')
23945
23946         if [[ -n "$dupe_stripes" ]] ; then
23947                 lfs getdirstripe $stripe_dir
23948                 error_noexit "Dupe MDT above: $dupe_stripes "
23949         fi
23950
23951         rm -rf $stripe_dir ||
23952                 error_noexit "unlink $stripe_dir fails"
23953 }
23954
23955 test_300s() {
23956         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23957                 skip "Need MDS version at least 2.7.55" && return
23958         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23959
23960         mkdir $DIR/$tdir
23961         for count in $(seq 2 $MDSCOUNT); do
23962                 test_300s_helper $count
23963         done
23964 }
23965 run_test 300s "test lfs mkdir -c without -i"
23966
23967 test_300t() {
23968         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
23969                 skip "need MDS 2.14.55 or later"
23970         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
23971
23972         local testdir="$DIR/$tdir/striped_dir"
23973         local dir1=$testdir/dir1
23974         local dir2=$testdir/dir2
23975
23976         mkdir -p $testdir
23977
23978         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
23979                 error "failed to set default stripe count for $testdir"
23980
23981         mkdir $dir1
23982         local stripe_count=$($LFS getdirstripe -c $dir1)
23983
23984         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
23985
23986         local max_count=$((MDSCOUNT - 1))
23987         local mdts=$(comma_list $(mdts_nodes))
23988
23989         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
23990         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
23991
23992         mkdir $dir2
23993         stripe_count=$($LFS getdirstripe -c $dir2)
23994
23995         (( $stripe_count == $max_count )) || error "wrong stripe count"
23996 }
23997 run_test 300t "test max_mdt_stripecount"
23998
23999 prepare_remote_file() {
24000         mkdir $DIR/$tdir/src_dir ||
24001                 error "create remote source failed"
24002
24003         cp /etc/hosts $DIR/$tdir/src_dir/a ||
24004                  error "cp to remote source failed"
24005         touch $DIR/$tdir/src_dir/a
24006
24007         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
24008                 error "create remote target dir failed"
24009
24010         touch $DIR/$tdir/tgt_dir/b
24011
24012         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
24013                 error "rename dir cross MDT failed!"
24014
24015         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
24016                 error "src_child still exists after rename"
24017
24018         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
24019                 error "missing file(a) after rename"
24020
24021         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
24022                 error "diff after rename"
24023 }
24024
24025 test_310a() {
24026         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24028
24029         local remote_file=$DIR/$tdir/tgt_dir/b
24030
24031         mkdir -p $DIR/$tdir
24032
24033         prepare_remote_file || error "prepare remote file failed"
24034
24035         #open-unlink file
24036         $OPENUNLINK $remote_file $remote_file ||
24037                 error "openunlink $remote_file failed"
24038         $CHECKSTAT -a $remote_file || error "$remote_file exists"
24039 }
24040 run_test 310a "open unlink remote file"
24041
24042 test_310b() {
24043         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24045
24046         local remote_file=$DIR/$tdir/tgt_dir/b
24047
24048         mkdir -p $DIR/$tdir
24049
24050         prepare_remote_file || error "prepare remote file failed"
24051
24052         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24053         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
24054         $CHECKSTAT -t file $remote_file || error "check file failed"
24055 }
24056 run_test 310b "unlink remote file with multiple links while open"
24057
24058 test_310c() {
24059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24060         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
24061
24062         local remote_file=$DIR/$tdir/tgt_dir/b
24063
24064         mkdir -p $DIR/$tdir
24065
24066         prepare_remote_file || error "prepare remote file failed"
24067
24068         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24069         multiop_bg_pause $remote_file O_uc ||
24070                         error "mulitop failed for remote file"
24071         MULTIPID=$!
24072         $MULTIOP $DIR/$tfile Ouc
24073         kill -USR1 $MULTIPID
24074         wait $MULTIPID
24075 }
24076 run_test 310c "open-unlink remote file with multiple links"
24077
24078 #LU-4825
24079 test_311() {
24080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24081         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24082         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
24083                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
24084         remote_mds_nodsh && skip "remote MDS with nodsh"
24085
24086         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24087         local mdts=$(comma_list $(mdts_nodes))
24088
24089         mkdir -p $DIR/$tdir
24090         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24091         createmany -o $DIR/$tdir/$tfile. 1000
24092
24093         # statfs data is not real time, let's just calculate it
24094         old_iused=$((old_iused + 1000))
24095
24096         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24097                         osp.*OST0000*MDT0000.create_count")
24098         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24099                                 osp.*OST0000*MDT0000.max_create_count")
24100         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
24101
24102         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
24103         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
24104         [ $index -ne 0 ] || error "$tfile stripe index is 0"
24105
24106         unlinkmany $DIR/$tdir/$tfile. 1000
24107
24108         do_nodes $mdts "$LCTL set_param -n \
24109                         osp.*OST0000*.max_create_count=$max_count"
24110         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
24111                 do_nodes $mdts "$LCTL set_param -n \
24112                                 osp.*OST0000*.create_count=$count"
24113         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
24114                         grep "=0" && error "create_count is zero"
24115
24116         local new_iused
24117         for i in $(seq 120); do
24118                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24119                 # system may be too busy to destroy all objs in time, use
24120                 # a somewhat small value to not fail autotest
24121                 [ $((old_iused - new_iused)) -gt 400 ] && break
24122                 sleep 1
24123         done
24124
24125         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24126         [ $((old_iused - new_iused)) -gt 400 ] ||
24127                 error "objs not destroyed after unlink"
24128 }
24129 run_test 311 "disable OSP precreate, and unlink should destroy objs"
24130
24131 zfs_oid_to_objid()
24132 {
24133         local ost=$1
24134         local objid=$2
24135
24136         local vdevdir=$(dirname $(facet_vdevice $ost))
24137         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
24138         local zfs_zapid=$(do_facet $ost $cmd |
24139                           grep -w "/O/0/d$((objid%32))" -C 5 |
24140                           awk '/Object/{getline; print $1}')
24141         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
24142                           awk "/$objid = /"'{printf $3}')
24143
24144         echo $zfs_objid
24145 }
24146
24147 zfs_object_blksz() {
24148         local ost=$1
24149         local objid=$2
24150
24151         local vdevdir=$(dirname $(facet_vdevice $ost))
24152         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
24153         local blksz=$(do_facet $ost $cmd $objid |
24154                       awk '/dblk/{getline; printf $4}')
24155
24156         case "${blksz: -1}" in
24157                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24158                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24159                 *) ;;
24160         esac
24161
24162         echo $blksz
24163 }
24164
24165 test_312() { # LU-4856
24166         remote_ost_nodsh && skip "remote OST with nodsh"
24167         [ "$ost1_FSTYPE" = "zfs" ] ||
24168                 skip_env "the test only applies to zfs"
24169
24170         local max_blksz=$(do_facet ost1 \
24171                           $ZFS get -p recordsize $(facet_device ost1) |
24172                           awk '!/VALUE/{print $3}')
24173
24174         # to make life a little bit easier
24175         $LFS mkdir -c 1 -i 0 $DIR/$tdir
24176         $LFS setstripe -c 1 -i 0 $DIR/$tdir
24177
24178         local tf=$DIR/$tdir/$tfile
24179         touch $tf
24180         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24181
24182         # Get ZFS object id
24183         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24184         # block size change by sequential overwrite
24185         local bs
24186
24187         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24188                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24189
24190                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
24191                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
24192         done
24193         rm -f $tf
24194
24195         # block size change by sequential append write
24196         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24197         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24198         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24199         local count
24200
24201         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24202                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24203                         oflag=sync conv=notrunc
24204
24205                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
24206                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
24207                         error "blksz error, actual $blksz, " \
24208                                 "expected: 2 * $count * $PAGE_SIZE"
24209         done
24210         rm -f $tf
24211
24212         # random write
24213         touch $tf
24214         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24215         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24216
24217         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24218         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24219         [ $blksz -eq $PAGE_SIZE ] ||
24220                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24221
24222         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24223         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24224         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
24225
24226         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24227         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24228         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
24229 }
24230 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24231
24232 test_313() {
24233         remote_ost_nodsh && skip "remote OST with nodsh"
24234
24235         local file=$DIR/$tfile
24236
24237         rm -f $file
24238         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24239
24240         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24241         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24242         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24243                 error "write should failed"
24244         do_facet ost1 "$LCTL set_param fail_loc=0"
24245         rm -f $file
24246 }
24247 run_test 313 "io should fail after last_rcvd update fail"
24248
24249 test_314() {
24250         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24251
24252         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24253         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24254         rm -f $DIR/$tfile
24255         wait_delete_completed
24256         do_facet ost1 "$LCTL set_param fail_loc=0"
24257 }
24258 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24259
24260 test_315() { # LU-618
24261         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24262
24263         local file=$DIR/$tfile
24264         rm -f $file
24265
24266         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24267                 error "multiop file write failed"
24268         $MULTIOP $file oO_RDONLY:r4063232_c &
24269         PID=$!
24270
24271         sleep 2
24272
24273         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24274         kill -USR1 $PID
24275
24276         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24277         rm -f $file
24278 }
24279 run_test 315 "read should be accounted"
24280
24281 test_316() {
24282         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24283         large_xattr_enabled || skip "ea_inode feature disabled"
24284
24285         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
24286         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
24287         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
24288         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
24289
24290         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
24291 }
24292 run_test 316 "lfs migrate of file with large_xattr enabled"
24293
24294 test_317() {
24295         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24296                 skip "Need MDS version at least 2.11.53"
24297         if [ "$ost1_FSTYPE" == "zfs" ]; then
24298                 skip "LU-10370: no implementation for ZFS"
24299         fi
24300
24301         local trunc_sz
24302         local grant_blk_size
24303
24304         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24305                         awk '/grant_block_size:/ { print $2; exit; }')
24306         #
24307         # Create File of size 5M. Truncate it to below size's and verify
24308         # blocks count.
24309         #
24310         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24311                 error "Create file $DIR/$tfile failed"
24312         stack_trap "rm -f $DIR/$tfile" EXIT
24313
24314         for trunc_sz in 2097152 4097 4000 509 0; do
24315                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24316                         error "truncate $tfile to $trunc_sz failed"
24317                 local sz=$(stat --format=%s $DIR/$tfile)
24318                 local blk=$(stat --format=%b $DIR/$tfile)
24319                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24320                                      grant_blk_size) * 8))
24321
24322                 if [[ $blk -ne $trunc_blk ]]; then
24323                         $(which stat) $DIR/$tfile
24324                         error "Expected Block $trunc_blk got $blk for $tfile"
24325                 fi
24326
24327                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24328                         error "Expected Size $trunc_sz got $sz for $tfile"
24329         done
24330
24331         #
24332         # sparse file test
24333         # Create file with a hole and write actual 65536 bytes which aligned
24334         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24335         #
24336         local bs=65536
24337         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24338                 error "Create file : $DIR/$tfile"
24339
24340         #
24341         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24342         # blocks. The block count must drop to 8.
24343         #
24344         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
24345                 ((bs - grant_blk_size) + 1)))
24346         $TRUNCATE $DIR/$tfile $trunc_sz ||
24347                 error "truncate $tfile to $trunc_sz failed"
24348
24349         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24350         sz=$(stat --format=%s $DIR/$tfile)
24351         blk=$(stat --format=%b $DIR/$tfile)
24352
24353         if [[ $blk -ne $trunc_bsz ]]; then
24354                 $(which stat) $DIR/$tfile
24355                 error "Expected Block $trunc_bsz got $blk for $tfile"
24356         fi
24357
24358         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24359                 error "Expected Size $trunc_sz got $sz for $tfile"
24360 }
24361 run_test 317 "Verify blocks get correctly update after truncate"
24362
24363 test_318() {
24364         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24365         local old_max_active=$($LCTL get_param -n \
24366                             ${llite_name}.max_read_ahead_async_active \
24367                             2>/dev/null)
24368
24369         $LCTL set_param llite.*.max_read_ahead_async_active=256
24370         local max_active=$($LCTL get_param -n \
24371                            ${llite_name}.max_read_ahead_async_active \
24372                            2>/dev/null)
24373         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24374
24375         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24376                 error "set max_read_ahead_async_active should succeed"
24377
24378         $LCTL set_param llite.*.max_read_ahead_async_active=512
24379         max_active=$($LCTL get_param -n \
24380                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24381         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24382
24383         # restore @max_active
24384         [ $old_max_active -ne 0 ] && $LCTL set_param \
24385                 llite.*.max_read_ahead_async_active=$old_max_active
24386
24387         local old_threshold=$($LCTL get_param -n \
24388                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24389         local max_per_file_mb=$($LCTL get_param -n \
24390                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24391
24392         local invalid=$(($max_per_file_mb + 1))
24393         $LCTL set_param \
24394                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24395                         && error "set $invalid should fail"
24396
24397         local valid=$(($invalid - 1))
24398         $LCTL set_param \
24399                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24400                         error "set $valid should succeed"
24401         local threshold=$($LCTL get_param -n \
24402                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24403         [ $threshold -eq $valid ] || error \
24404                 "expect threshold $valid got $threshold"
24405         $LCTL set_param \
24406                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24407 }
24408 run_test 318 "Verify async readahead tunables"
24409
24410 test_319() {
24411         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24412
24413         local before=$(date +%s)
24414         local evict
24415         local mdir=$DIR/$tdir
24416         local file=$mdir/xxx
24417
24418         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24419         touch $file
24420
24421 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24422         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24423         $LFS migrate -m1 $mdir &
24424
24425         sleep 1
24426         dd if=$file of=/dev/null
24427         wait
24428         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24429           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24430
24431         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24432 }
24433 run_test 319 "lost lease lock on migrate error"
24434
24435 test_398a() { # LU-4198
24436         local ost1_imp=$(get_osc_import_name client ost1)
24437         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24438                          cut -d'.' -f2)
24439
24440         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24441         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24442
24443         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
24444         # request a new lock on client
24445         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24446
24447         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24448         #local lock_count=$($LCTL get_param -n \
24449         #                  ldlm.namespaces.$imp_name.lru_size)
24450         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24451
24452         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24453
24454         # no lock cached, should use lockless DIO and not enqueue new lock
24455         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
24456                 conv=notrunc ||
24457                 error "dio write failed"
24458         lock_count=$($LCTL get_param -n \
24459                      ldlm.namespaces.$imp_name.lru_size)
24460         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24461
24462         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24463
24464         # no lock cached, should use locked DIO append
24465         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
24466                 conv=notrunc || error "DIO append failed"
24467         lock_count=$($LCTL get_param -n \
24468                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
24469         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
24470 }
24471 run_test 398a "direct IO should cancel lock otherwise lockless"
24472
24473 test_398b() { # LU-4198
24474         which fio || skip_env "no fio installed"
24475         $LFS setstripe -c -1 -S 1M $DIR/$tfile
24476
24477         local size=48
24478         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24479
24480         local njobs=4
24481         # Single page, multiple pages, stripe size, 4*stripe size
24482         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
24483                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
24484                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
24485                         --numjobs=$njobs --fallocate=none \
24486                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24487                         --filename=$DIR/$tfile &
24488                 bg_pid=$!
24489
24490                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
24491                 fio --name=rand-rw --rw=randrw --bs=$bsize \
24492                         --numjobs=$njobs --fallocate=none \
24493                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24494                         --filename=$DIR/$tfile || true
24495                 wait $bg_pid
24496         done
24497
24498         evict=$(do_facet client $LCTL get_param \
24499                 osc.$FSNAME-OST*-osc-*/state |
24500             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
24501
24502         [ -z "$evict" ] || [[ $evict -le $before ]] ||
24503                 (do_facet client $LCTL get_param \
24504                         osc.$FSNAME-OST*-osc-*/state;
24505                     error "eviction happened: $evict before:$before")
24506
24507         rm -f $DIR/$tfile
24508 }
24509 run_test 398b "DIO and buffer IO race"
24510
24511 test_398c() { # LU-4198
24512         local ost1_imp=$(get_osc_import_name client ost1)
24513         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24514                          cut -d'.' -f2)
24515
24516         which fio || skip_env "no fio installed"
24517
24518         saved_debug=$($LCTL get_param -n debug)
24519         $LCTL set_param debug=0
24520
24521         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24522         ((size /= 1024)) # by megabytes
24523         ((size /= 2)) # write half of the OST at most
24524         [ $size -gt 40 ] && size=40 #reduce test time anyway
24525
24526         $LFS setstripe -c 1 $DIR/$tfile
24527
24528         # it seems like ldiskfs reserves more space than necessary if the
24529         # writing blocks are not mapped, so it extends the file firstly
24530         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24531         cancel_lru_locks osc
24532
24533         # clear and verify rpc_stats later
24534         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24535
24536         local njobs=4
24537         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24538         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24539                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24540                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24541                 --filename=$DIR/$tfile
24542         [ $? -eq 0 ] || error "fio write error"
24543
24544         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24545                 error "Locks were requested while doing AIO"
24546
24547         # get the percentage of 1-page I/O
24548         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24549                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24550                 awk '{print $7}')
24551         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24552
24553         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24554         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24555                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24556                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24557                 --filename=$DIR/$tfile
24558         [ $? -eq 0 ] || error "fio mixed read write error"
24559
24560         echo "AIO with large block size ${size}M"
24561         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24562                 --numjobs=1 --fallocate=none --ioengine=libaio \
24563                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24564                 --filename=$DIR/$tfile
24565         [ $? -eq 0 ] || error "fio large block size failed"
24566
24567         rm -f $DIR/$tfile
24568         $LCTL set_param debug="$saved_debug"
24569 }
24570 run_test 398c "run fio to test AIO"
24571
24572 test_398d() { #  LU-13846
24573         which aiocp || skip_env "no aiocp installed"
24574         local aio_file=$DIR/$tfile.aio
24575
24576         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24577
24578         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24579         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24580         stack_trap "rm -f $DIR/$tfile $aio_file"
24581
24582         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24583
24584         # make sure we don't crash and fail properly
24585         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24586                 error "aio not aligned with PAGE SIZE should fail"
24587
24588         rm -f $DIR/$tfile $aio_file
24589 }
24590 run_test 398d "run aiocp to verify block size > stripe size"
24591
24592 test_398e() {
24593         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24594         touch $DIR/$tfile.new
24595         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24596 }
24597 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24598
24599 test_398f() { #  LU-14687
24600         which aiocp || skip_env "no aiocp installed"
24601         local aio_file=$DIR/$tfile.aio
24602
24603         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24604
24605         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24606         stack_trap "rm -f $DIR/$tfile $aio_file"
24607
24608         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24609         $LCTL set_param fail_loc=0x1418
24610         # make sure we don't crash and fail properly
24611         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24612                 error "aio with page allocation failure succeeded"
24613         $LCTL set_param fail_loc=0
24614         diff $DIR/$tfile $aio_file
24615         [[ $? != 0 ]] || error "no diff after failed aiocp"
24616 }
24617 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24618
24619 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24620 # stripe and i/o size must be > stripe size
24621 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24622 # single RPC in flight.  This test shows async DIO submission is working by
24623 # showing multiple RPCs in flight.
24624 test_398g() { #  LU-13798
24625         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24626
24627         # We need to do some i/o first to acquire enough grant to put our RPCs
24628         # in flight; otherwise a new connection may not have enough grant
24629         # available
24630         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24631                 error "parallel dio failed"
24632         stack_trap "rm -f $DIR/$tfile"
24633
24634         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24635         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24636         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24637         stack_trap "$LCTL set_param -n $pages_per_rpc"
24638
24639         # Recreate file so it's empty
24640         rm -f $DIR/$tfile
24641         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24642         #Pause rpc completion to guarantee we see multiple rpcs in flight
24643         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24644         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24645         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24646
24647         # Clear rpc stats
24648         $LCTL set_param osc.*.rpc_stats=c
24649
24650         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24651                 error "parallel dio failed"
24652         stack_trap "rm -f $DIR/$tfile"
24653
24654         $LCTL get_param osc.*-OST0000-*.rpc_stats
24655         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24656                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24657                 grep "8:" | awk '{print $8}')
24658         # We look at the "8 rpcs in flight" field, and verify A) it is present
24659         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24660         # as expected for an 8M DIO to a file with 1M stripes.
24661         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24662
24663         # Verify turning off parallel dio works as expected
24664         # Clear rpc stats
24665         $LCTL set_param osc.*.rpc_stats=c
24666         $LCTL set_param llite.*.parallel_dio=0
24667         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24668
24669         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24670                 error "dio with parallel dio disabled failed"
24671
24672         # Ideally, we would see only one RPC in flight here, but there is an
24673         # unavoidable race between i/o completion and RPC in flight counting,
24674         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24675         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24676         # So instead we just verify it's always < 8.
24677         $LCTL get_param osc.*-OST0000-*.rpc_stats
24678         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24679                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24680                 grep '^$' -B1 | grep . | awk '{print $1}')
24681         [ $ret != "8:" ] ||
24682                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24683 }
24684 run_test 398g "verify parallel dio async RPC submission"
24685
24686 test_398h() { #  LU-13798
24687         local dio_file=$DIR/$tfile.dio
24688
24689         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24690
24691         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24692         stack_trap "rm -f $DIR/$tfile $dio_file"
24693
24694         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24695                 error "parallel dio failed"
24696         diff $DIR/$tfile $dio_file
24697         [[ $? == 0 ]] || error "file diff after aiocp"
24698 }
24699 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24700
24701 test_398i() { #  LU-13798
24702         local dio_file=$DIR/$tfile.dio
24703
24704         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24705
24706         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24707         stack_trap "rm -f $DIR/$tfile $dio_file"
24708
24709         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24710         $LCTL set_param fail_loc=0x1418
24711         # make sure we don't crash and fail properly
24712         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24713                 error "parallel dio page allocation failure succeeded"
24714         diff $DIR/$tfile $dio_file
24715         [[ $? != 0 ]] || error "no diff after failed aiocp"
24716 }
24717 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24718
24719 test_398j() { #  LU-13798
24720         # Stripe size > RPC size but less than i/o size tests split across
24721         # stripes and RPCs for individual i/o op
24722         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24723
24724         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24725         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24726         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24727         stack_trap "$LCTL set_param -n $pages_per_rpc"
24728
24729         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24730                 error "parallel dio write failed"
24731         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24732
24733         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24734                 error "parallel dio read failed"
24735         diff $DIR/$tfile $DIR/$tfile.2
24736         [[ $? == 0 ]] || error "file diff after parallel dio read"
24737 }
24738 run_test 398j "test parallel dio where stripe size > rpc_size"
24739
24740 test_398k() { #  LU-13798
24741         wait_delete_completed
24742         wait_mds_ost_sync
24743
24744         # 4 stripe file; we will cause out of space on OST0
24745         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24746
24747         # Fill OST0 (if it's not too large)
24748         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24749                    head -n1)
24750         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24751                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24752         fi
24753         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24754         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24755                 error "dd should fill OST0"
24756         stack_trap "rm -f $DIR/$tfile.1"
24757
24758         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24759         err=$?
24760
24761         ls -la $DIR/$tfile
24762         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24763                 error "file is not 0 bytes in size"
24764
24765         # dd above should not succeed, but don't error until here so we can
24766         # get debug info above
24767         [[ $err != 0 ]] ||
24768                 error "parallel dio write with enospc succeeded"
24769         stack_trap "rm -f $DIR/$tfile"
24770 }
24771 run_test 398k "test enospc on first stripe"
24772
24773 test_398l() { #  LU-13798
24774         wait_delete_completed
24775         wait_mds_ost_sync
24776
24777         # 4 stripe file; we will cause out of space on OST0
24778         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24779         # happens on the second i/o chunk we issue
24780         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24781
24782         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24783         stack_trap "rm -f $DIR/$tfile"
24784
24785         # Fill OST0 (if it's not too large)
24786         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24787                    head -n1)
24788         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24789                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24790         fi
24791         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24792         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24793                 error "dd should fill OST0"
24794         stack_trap "rm -f $DIR/$tfile.1"
24795
24796         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24797         err=$?
24798         stack_trap "rm -f $DIR/$tfile.2"
24799
24800         # Check that short write completed as expected
24801         ls -la $DIR/$tfile.2
24802         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24803                 error "file is not 1M in size"
24804
24805         # dd above should not succeed, but don't error until here so we can
24806         # get debug info above
24807         [[ $err != 0 ]] ||
24808                 error "parallel dio write with enospc succeeded"
24809
24810         # Truncate source file to same length as output file and diff them
24811         $TRUNCATE $DIR/$tfile 1048576
24812         diff $DIR/$tfile $DIR/$tfile.2
24813         [[ $? == 0 ]] || error "data incorrect after short write"
24814 }
24815 run_test 398l "test enospc on intermediate stripe/RPC"
24816
24817 test_398m() { #  LU-13798
24818         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24819
24820         # Set up failure on OST0, the first stripe:
24821         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24822         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24823         # So this fail_val specifies OST0
24824         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24825         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24826
24827         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24828                 error "parallel dio write with failure on first stripe succeeded"
24829         stack_trap "rm -f $DIR/$tfile"
24830         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24831
24832         # Place data in file for read
24833         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24834                 error "parallel dio write failed"
24835
24836         # Fail read on OST0, first stripe
24837         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24838         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24839         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24840                 error "parallel dio read with error on first stripe succeeded"
24841         rm -f $DIR/$tfile.2
24842         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24843
24844         # Switch to testing on OST1, second stripe
24845         # Clear file contents, maintain striping
24846         echo > $DIR/$tfile
24847         # Set up failure on OST1, second stripe:
24848         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24849         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24850
24851         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24852                 error "parallel dio write with failure on first stripe succeeded"
24853         stack_trap "rm -f $DIR/$tfile"
24854         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24855
24856         # Place data in file for read
24857         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24858                 error "parallel dio write failed"
24859
24860         # Fail read on OST1, second stripe
24861         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24862         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24863         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24864                 error "parallel dio read with error on first stripe succeeded"
24865         rm -f $DIR/$tfile.2
24866         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24867 }
24868 run_test 398m "test RPC failures with parallel dio"
24869
24870 # Parallel submission of DIO should not cause problems for append, but it's
24871 # important to verify.
24872 test_398n() { #  LU-13798
24873         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24874
24875         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24876                 error "dd to create source file failed"
24877         stack_trap "rm -f $DIR/$tfile"
24878
24879         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24880                 error "parallel dio write with failure on second stripe succeeded"
24881         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24882         diff $DIR/$tfile $DIR/$tfile.1
24883         [[ $? == 0 ]] || error "data incorrect after append"
24884
24885 }
24886 run_test 398n "test append with parallel DIO"
24887
24888 test_fake_rw() {
24889         local read_write=$1
24890         if [ "$read_write" = "write" ]; then
24891                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24892         elif [ "$read_write" = "read" ]; then
24893                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24894         else
24895                 error "argument error"
24896         fi
24897
24898         # turn off debug for performance testing
24899         local saved_debug=$($LCTL get_param -n debug)
24900         $LCTL set_param debug=0
24901
24902         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24903
24904         # get ost1 size - $FSNAME-OST0000
24905         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24906         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
24907         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
24908
24909         if [ "$read_write" = "read" ]; then
24910                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
24911         fi
24912
24913         local start_time=$(date +%s.%N)
24914         $dd_cmd bs=1M count=$blocks oflag=sync ||
24915                 error "real dd $read_write error"
24916         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
24917
24918         if [ "$read_write" = "write" ]; then
24919                 rm -f $DIR/$tfile
24920         fi
24921
24922         # define OBD_FAIL_OST_FAKE_RW           0x238
24923         do_facet ost1 $LCTL set_param fail_loc=0x238
24924
24925         local start_time=$(date +%s.%N)
24926         $dd_cmd bs=1M count=$blocks oflag=sync ||
24927                 error "fake dd $read_write error"
24928         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
24929
24930         if [ "$read_write" = "write" ]; then
24931                 # verify file size
24932                 cancel_lru_locks osc
24933                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
24934                         error "$tfile size not $blocks MB"
24935         fi
24936         do_facet ost1 $LCTL set_param fail_loc=0
24937
24938         echo "fake $read_write $duration_fake vs. normal $read_write" \
24939                 "$duration in seconds"
24940         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
24941                 error_not_in_vm "fake write is slower"
24942
24943         $LCTL set_param -n debug="$saved_debug"
24944         rm -f $DIR/$tfile
24945 }
24946 test_399a() { # LU-7655 for OST fake write
24947         remote_ost_nodsh && skip "remote OST with nodsh"
24948
24949         test_fake_rw write
24950 }
24951 run_test 399a "fake write should not be slower than normal write"
24952
24953 test_399b() { # LU-8726 for OST fake read
24954         remote_ost_nodsh && skip "remote OST with nodsh"
24955         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
24956                 skip_env "ldiskfs only test"
24957         fi
24958
24959         test_fake_rw read
24960 }
24961 run_test 399b "fake read should not be slower than normal read"
24962
24963 test_400a() { # LU-1606, was conf-sanity test_74
24964         if ! which $CC > /dev/null 2>&1; then
24965                 skip_env "$CC is not installed"
24966         fi
24967
24968         local extra_flags=''
24969         local out=$TMP/$tfile
24970         local prefix=/usr/include/lustre
24971         local prog
24972
24973         # Oleg removes c files in his test rig so test if any c files exist
24974         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24975                 skip_env "Needed c test files are missing"
24976
24977         if ! [[ -d $prefix ]]; then
24978                 # Assume we're running in tree and fixup the include path.
24979                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24980                 extra_flags+=" -L$LUSTRE/utils/.lib"
24981         fi
24982
24983         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24984                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24985                         error "client api broken"
24986         done
24987         rm -f $out
24988 }
24989 run_test 400a "Lustre client api program can compile and link"
24990
24991 test_400b() { # LU-1606, LU-5011
24992         local header
24993         local out=$TMP/$tfile
24994         local prefix=/usr/include/linux/lustre
24995
24996         # We use a hard coded prefix so that this test will not fail
24997         # when run in tree. There are headers in lustre/include/lustre/
24998         # that are not packaged (like lustre_idl.h) and have more
24999         # complicated include dependencies (like config.h and lnet/types.h).
25000         # Since this test about correct packaging we just skip them when
25001         # they don't exist (see below) rather than try to fixup cppflags.
25002
25003         if ! which $CC > /dev/null 2>&1; then
25004                 skip_env "$CC is not installed"
25005         fi
25006
25007         for header in $prefix/*.h; do
25008                 if ! [[ -f "$header" ]]; then
25009                         continue
25010                 fi
25011
25012                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
25013                         continue # lustre_ioctl.h is internal header
25014                 fi
25015
25016                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
25017                         error "cannot compile '$header'"
25018         done
25019         rm -f $out
25020 }
25021 run_test 400b "packaged headers can be compiled"
25022
25023 test_401a() { #LU-7437
25024         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
25025         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
25026
25027         #count the number of parameters by "list_param -R"
25028         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
25029         #count the number of parameters by listing proc files
25030         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
25031         echo "proc_dirs='$proc_dirs'"
25032         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
25033         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
25034                       sort -u | wc -l)
25035
25036         [ $params -eq $procs ] ||
25037                 error "found $params parameters vs. $procs proc files"
25038
25039         # test the list_param -D option only returns directories
25040         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
25041         #count the number of parameters by listing proc directories
25042         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
25043                 sort -u | wc -l)
25044
25045         [ $params -eq $procs ] ||
25046                 error "found $params parameters vs. $procs proc files"
25047 }
25048 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
25049
25050 test_401b() {
25051         # jobid_var may not allow arbitrary values, so use jobid_name
25052         # if available
25053         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25054                 local testname=jobid_name tmp='testing%p'
25055         else
25056                 local testname=jobid_var tmp=testing
25057         fi
25058
25059         local save=$($LCTL get_param -n $testname)
25060
25061         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
25062                 error "no error returned when setting bad parameters"
25063
25064         local jobid_new=$($LCTL get_param -n foe $testname baz)
25065         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
25066
25067         $LCTL set_param -n fog=bam $testname=$save bat=fog
25068         local jobid_old=$($LCTL get_param -n foe $testname bag)
25069         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
25070 }
25071 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
25072
25073 test_401c() {
25074         # jobid_var may not allow arbitrary values, so use jobid_name
25075         # if available
25076         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25077                 local testname=jobid_name
25078         else
25079                 local testname=jobid_var
25080         fi
25081
25082         local jobid_var_old=$($LCTL get_param -n $testname)
25083         local jobid_var_new
25084
25085         $LCTL set_param $testname= &&
25086                 error "no error returned for 'set_param a='"
25087
25088         jobid_var_new=$($LCTL get_param -n $testname)
25089         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25090                 error "$testname was changed by setting without value"
25091
25092         $LCTL set_param $testname &&
25093                 error "no error returned for 'set_param a'"
25094
25095         jobid_var_new=$($LCTL get_param -n $testname)
25096         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25097                 error "$testname was changed by setting without value"
25098 }
25099 run_test 401c "Verify 'lctl set_param' without value fails in either format."
25100
25101 test_401d() {
25102         # jobid_var may not allow arbitrary values, so use jobid_name
25103         # if available
25104         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25105                 local testname=jobid_name new_value='foo=bar%p'
25106         else
25107                 local testname=jobid_var new_valuie=foo=bar
25108         fi
25109
25110         local jobid_var_old=$($LCTL get_param -n $testname)
25111         local jobid_var_new
25112
25113         $LCTL set_param $testname=$new_value ||
25114                 error "'set_param a=b' did not accept a value containing '='"
25115
25116         jobid_var_new=$($LCTL get_param -n $testname)
25117         [[ "$jobid_var_new" == "$new_value" ]] ||
25118                 error "'set_param a=b' failed on a value containing '='"
25119
25120         # Reset the $testname to test the other format
25121         $LCTL set_param $testname=$jobid_var_old
25122         jobid_var_new=$($LCTL get_param -n $testname)
25123         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25124                 error "failed to reset $testname"
25125
25126         $LCTL set_param $testname $new_value ||
25127                 error "'set_param a b' did not accept a value containing '='"
25128
25129         jobid_var_new=$($LCTL get_param -n $testname)
25130         [[ "$jobid_var_new" == "$new_value" ]] ||
25131                 error "'set_param a b' failed on a value containing '='"
25132
25133         $LCTL set_param $testname $jobid_var_old
25134         jobid_var_new=$($LCTL get_param -n $testname)
25135         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25136                 error "failed to reset $testname"
25137 }
25138 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
25139
25140 test_401e() { # LU-14779
25141         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
25142                 error "lctl list_param MGC* failed"
25143         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
25144         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
25145                 error "lctl get_param lru_size failed"
25146 }
25147 run_test 401e "verify 'lctl get_param' works with NID in parameter"
25148
25149 test_402() {
25150         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
25151         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
25152                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
25153         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
25154                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
25155                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
25156         remote_mds_nodsh && skip "remote MDS with nodsh"
25157
25158         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
25159 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
25160         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
25161         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
25162                 echo "Touch failed - OK"
25163 }
25164 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
25165
25166 test_403() {
25167         local file1=$DIR/$tfile.1
25168         local file2=$DIR/$tfile.2
25169         local tfile=$TMP/$tfile
25170
25171         rm -f $file1 $file2 $tfile
25172
25173         touch $file1
25174         ln $file1 $file2
25175
25176         # 30 sec OBD_TIMEOUT in ll_getattr()
25177         # right before populating st_nlink
25178         $LCTL set_param fail_loc=0x80001409
25179         stat -c %h $file1 > $tfile &
25180
25181         # create an alias, drop all locks and reclaim the dentry
25182         < $file2
25183         cancel_lru_locks mdc
25184         cancel_lru_locks osc
25185         sysctl -w vm.drop_caches=2
25186
25187         wait
25188
25189         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25190
25191         rm -f $tfile $file1 $file2
25192 }
25193 run_test 403 "i_nlink should not drop to zero due to aliasing"
25194
25195 test_404() { # LU-6601
25196         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25197                 skip "Need server version newer than 2.8.52"
25198         remote_mds_nodsh && skip "remote MDS with nodsh"
25199
25200         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25201                 awk '/osp .*-osc-MDT/ { print $4}')
25202
25203         local osp
25204         for osp in $mosps; do
25205                 echo "Deactivate: " $osp
25206                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25207                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25208                         awk -vp=$osp '$4 == p { print $2 }')
25209                 [ $stat = IN ] || {
25210                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25211                         error "deactivate error"
25212                 }
25213                 echo "Activate: " $osp
25214                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25215                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25216                         awk -vp=$osp '$4 == p { print $2 }')
25217                 [ $stat = UP ] || {
25218                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25219                         error "activate error"
25220                 }
25221         done
25222 }
25223 run_test 404 "validate manual {de}activated works properly for OSPs"
25224
25225 test_405() {
25226         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25227         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25228                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25229                         skip "Layout swap lock is not supported"
25230
25231         check_swap_layouts_support
25232         check_swap_layout_no_dom $DIR
25233
25234         test_mkdir $DIR/$tdir
25235         swap_lock_test -d $DIR/$tdir ||
25236                 error "One layout swap locked test failed"
25237 }
25238 run_test 405 "Various layout swap lock tests"
25239
25240 test_406() {
25241         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25242         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25243         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25245         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25246                 skip "Need MDS version at least 2.8.50"
25247
25248         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25249         local test_pool=$TESTNAME
25250
25251         pool_add $test_pool || error "pool_add failed"
25252         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25253                 error "pool_add_targets failed"
25254
25255         save_layout_restore_at_exit $MOUNT
25256
25257         # parent set default stripe count only, child will stripe from both
25258         # parent and fs default
25259         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25260                 error "setstripe $MOUNT failed"
25261         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25262         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25263         for i in $(seq 10); do
25264                 local f=$DIR/$tdir/$tfile.$i
25265                 touch $f || error "touch failed"
25266                 local count=$($LFS getstripe -c $f)
25267                 [ $count -eq $OSTCOUNT ] ||
25268                         error "$f stripe count $count != $OSTCOUNT"
25269                 local offset=$($LFS getstripe -i $f)
25270                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25271                 local size=$($LFS getstripe -S $f)
25272                 [ $size -eq $((def_stripe_size * 2)) ] ||
25273                         error "$f stripe size $size != $((def_stripe_size * 2))"
25274                 local pool=$($LFS getstripe -p $f)
25275                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25276         done
25277
25278         # change fs default striping, delete parent default striping, now child
25279         # will stripe from new fs default striping only
25280         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25281                 error "change $MOUNT default stripe failed"
25282         $LFS setstripe -c 0 $DIR/$tdir ||
25283                 error "delete $tdir default stripe failed"
25284         for i in $(seq 11 20); do
25285                 local f=$DIR/$tdir/$tfile.$i
25286                 touch $f || error "touch $f failed"
25287                 local count=$($LFS getstripe -c $f)
25288                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25289                 local offset=$($LFS getstripe -i $f)
25290                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25291                 local size=$($LFS getstripe -S $f)
25292                 [ $size -eq $def_stripe_size ] ||
25293                         error "$f stripe size $size != $def_stripe_size"
25294                 local pool=$($LFS getstripe -p $f)
25295                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25296         done
25297
25298         unlinkmany $DIR/$tdir/$tfile. 1 20
25299
25300         local f=$DIR/$tdir/$tfile
25301         pool_remove_all_targets $test_pool $f
25302         pool_remove $test_pool $f
25303 }
25304 run_test 406 "DNE support fs default striping"
25305
25306 test_407() {
25307         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25308         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25309                 skip "Need MDS version at least 2.8.55"
25310         remote_mds_nodsh && skip "remote MDS with nodsh"
25311
25312         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25313                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25314         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25315                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25316         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25317
25318         #define OBD_FAIL_DT_TXN_STOP    0x2019
25319         for idx in $(seq $MDSCOUNT); do
25320                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25321         done
25322         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25323         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25324                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25325         true
25326 }
25327 run_test 407 "transaction fail should cause operation fail"
25328
25329 test_408() {
25330         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25331
25332         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25333         lctl set_param fail_loc=0x8000040a
25334         # let ll_prepare_partial_page() fail
25335         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25336
25337         rm -f $DIR/$tfile
25338
25339         # create at least 100 unused inodes so that
25340         # shrink_icache_memory(0) should not return 0
25341         touch $DIR/$tfile-{0..100}
25342         rm -f $DIR/$tfile-{0..100}
25343         sync
25344
25345         echo 2 > /proc/sys/vm/drop_caches
25346 }
25347 run_test 408 "drop_caches should not hang due to page leaks"
25348
25349 test_409()
25350 {
25351         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25352
25353         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25354         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25355         touch $DIR/$tdir/guard || error "(2) Fail to create"
25356
25357         local PREFIX=$(str_repeat 'A' 128)
25358         echo "Create 1K hard links start at $(date)"
25359         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25360                 error "(3) Fail to hard link"
25361
25362         echo "Links count should be right although linkEA overflow"
25363         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25364         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25365         [ $linkcount -eq 1001 ] ||
25366                 error "(5) Unexpected hard links count: $linkcount"
25367
25368         echo "List all links start at $(date)"
25369         ls -l $DIR/$tdir/foo > /dev/null ||
25370                 error "(6) Fail to list $DIR/$tdir/foo"
25371
25372         echo "Unlink hard links start at $(date)"
25373         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25374                 error "(7) Fail to unlink"
25375         echo "Unlink hard links finished at $(date)"
25376 }
25377 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25378
25379 test_410()
25380 {
25381         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25382                 skip "Need client version at least 2.9.59"
25383         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25384                 skip "Need MODULES build"
25385
25386         # Create a file, and stat it from the kernel
25387         local testfile=$DIR/$tfile
25388         touch $testfile
25389
25390         local run_id=$RANDOM
25391         local my_ino=$(stat --format "%i" $testfile)
25392
25393         # Try to insert the module. This will always fail as the
25394         # module is designed to not be inserted.
25395         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25396             &> /dev/null
25397
25398         # Anything but success is a test failure
25399         dmesg | grep -q \
25400             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25401             error "no inode match"
25402 }
25403 run_test 410 "Test inode number returned from kernel thread"
25404
25405 cleanup_test411_cgroup() {
25406         trap 0
25407         rmdir "$1"
25408 }
25409
25410 test_411() {
25411         local cg_basedir=/sys/fs/cgroup/memory
25412         # LU-9966
25413         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25414                 skip "no setup for cgroup"
25415
25416         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25417                 error "test file creation failed"
25418         cancel_lru_locks osc
25419
25420         # Create a very small memory cgroup to force a slab allocation error
25421         local cgdir=$cg_basedir/osc_slab_alloc
25422         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25423         trap "cleanup_test411_cgroup $cgdir" EXIT
25424         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25425         echo 1M > $cgdir/memory.limit_in_bytes
25426
25427         # Should not LBUG, just be killed by oom-killer
25428         # dd will return 0 even allocation failure in some environment.
25429         # So don't check return value
25430         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25431         cleanup_test411_cgroup $cgdir
25432
25433         return 0
25434 }
25435 run_test 411 "Slab allocation error with cgroup does not LBUG"
25436
25437 test_412() {
25438         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25439         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25440                 skip "Need server version at least 2.10.55"
25441
25442         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25443                 error "mkdir failed"
25444         $LFS getdirstripe $DIR/$tdir
25445         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25446         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25447                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25448         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25449         [ $stripe_count -eq 2 ] ||
25450                 error "expect 2 get $stripe_count"
25451
25452         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25453
25454         local index
25455         local index2
25456
25457         # subdirs should be on the same MDT as parent
25458         for i in $(seq 0 $((MDSCOUNT - 1))); do
25459                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25460                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25461                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25462                 (( index == i )) || error "mdt$i/sub on MDT$index"
25463         done
25464
25465         # stripe offset -1, ditto
25466         for i in {1..10}; do
25467                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25468                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25469                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25470                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25471                 (( index == index2 )) ||
25472                         error "qos$i on MDT$index, sub on MDT$index2"
25473         done
25474
25475         local testdir=$DIR/$tdir/inherit
25476
25477         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25478         # inherit 2 levels
25479         for i in 1 2; do
25480                 testdir=$testdir/s$i
25481                 mkdir $testdir || error "mkdir $testdir failed"
25482                 index=$($LFS getstripe -m $testdir)
25483                 (( index == 1 )) ||
25484                         error "$testdir on MDT$index"
25485         done
25486
25487         # not inherit any more
25488         testdir=$testdir/s3
25489         mkdir $testdir || error "mkdir $testdir failed"
25490         getfattr -d -m dmv $testdir | grep dmv &&
25491                 error "default LMV set on $testdir" || true
25492 }
25493 run_test 412 "mkdir on specific MDTs"
25494
25495 generate_uneven_mdts() {
25496         local threshold=$1
25497         local lmv_qos_maxage
25498         local lod_qos_maxage
25499         local ffree
25500         local bavail
25501         local max
25502         local min
25503         local max_index
25504         local min_index
25505         local tmp
25506         local i
25507
25508         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25509         $LCTL set_param lmv.*.qos_maxage=1
25510         stack_trap "$LCTL set_param \
25511                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25512         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25513                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25514         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25515                 lod.*.mdt_qos_maxage=1
25516         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25517                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25518
25519         echo
25520         echo "Check for uneven MDTs: "
25521
25522         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25523         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25524         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25525
25526         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25527         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25528         max_index=0
25529         min_index=0
25530         for ((i = 1; i < ${#ffree[@]}; i++)); do
25531                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25532                 if [ $tmp -gt $max ]; then
25533                         max=$tmp
25534                         max_index=$i
25535                 fi
25536                 if [ $tmp -lt $min ]; then
25537                         min=$tmp
25538                         min_index=$i
25539                 fi
25540         done
25541
25542         (( ${ffree[min_index]} > 0 )) ||
25543                 skip "no free files in MDT$min_index"
25544         (( ${ffree[min_index]} < 10000000 )) ||
25545                 skip "too many free files in MDT$min_index"
25546
25547         # Check if we need to generate uneven MDTs
25548         local diff=$(((max - min) * 100 / min))
25549         local testdir=$DIR/$tdir-fillmdt
25550         local start
25551
25552         mkdir -p $testdir
25553
25554         i=0
25555         while (( diff < threshold )); do
25556                 # generate uneven MDTs, create till $threshold% diff
25557                 echo -n "weight diff=$diff% must be > $threshold% ..."
25558                 echo "Fill MDT$min_index with 1000 files: loop $i"
25559                 testdir=$DIR/$tdir-fillmdt/$i
25560                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
25561                         error "mkdir $testdir failed"
25562                 $LFS setstripe -E 1M -L mdt $testdir ||
25563                         error "setstripe $testdir failed"
25564                 start=$SECONDS
25565                 for F in f.{0..999}; do
25566                         dd if=/dev/zero of=$testdir/$F bs=64K count=1 > \
25567                                 /dev/null 2>&1 || error "dd $F failed"
25568                 done
25569
25570                 # wait for QOS to update
25571                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25572
25573                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25574                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25575                 max=$(((${ffree[max_index]} >> 8) *
25576                         (${bavail[max_index]} * bsize >> 16)))
25577                 min=$(((${ffree[min_index]} >> 8) *
25578                         (${bavail[min_index]} * bsize >> 16)))
25579                 diff=$(((max - min) * 100 / min))
25580                 i=$((i + 1))
25581         done
25582
25583         echo "MDT filesfree available: ${ffree[*]}"
25584         echo "MDT blocks available: ${bavail[*]}"
25585         echo "weight diff=$diff%"
25586 }
25587
25588 test_qos_mkdir() {
25589         local mkdir_cmd=$1
25590         local stripe_count=$2
25591         local mdts=$(comma_list $(mdts_nodes))
25592
25593         local testdir
25594         local lmv_qos_prio_free
25595         local lmv_qos_threshold_rr
25596         local lmv_qos_maxage
25597         local lod_qos_prio_free
25598         local lod_qos_threshold_rr
25599         local lod_qos_maxage
25600         local count
25601         local i
25602
25603         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25604         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25605         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25606                 head -n1)
25607         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25608         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25609         stack_trap "$LCTL set_param \
25610                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25611         stack_trap "$LCTL set_param \
25612                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25613         stack_trap "$LCTL set_param \
25614                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25615
25616         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25617                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25618         lod_qos_prio_free=${lod_qos_prio_free%%%}
25619         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25620                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25621         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25622         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25623                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25624         stack_trap "do_nodes $mdts $LCTL set_param \
25625                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25626         stack_trap "do_nodes $mdts $LCTL set_param \
25627                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25628         stack_trap "do_nodes $mdts $LCTL set_param \
25629                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25630
25631         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25632         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25633
25634         testdir=$DIR/$tdir-s$stripe_count/rr
25635
25636         local stripe_index=$($LFS getstripe -m $testdir)
25637         local test_mkdir_rr=true
25638
25639         getfattr -d -m dmv -e hex $testdir | grep dmv
25640         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25641                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25642                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25643                         test_mkdir_rr=false
25644         fi
25645
25646         echo
25647         $test_mkdir_rr &&
25648                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25649                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25650
25651         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25652         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25653                 eval $mkdir_cmd $testdir/subdir$i ||
25654                         error "$mkdir_cmd subdir$i failed"
25655         done
25656
25657         for (( i = 0; i < $MDSCOUNT; i++ )); do
25658                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25659                 echo "$count directories created on MDT$i"
25660                 if $test_mkdir_rr; then
25661                         (( $count == 100 )) ||
25662                                 error "subdirs are not evenly distributed"
25663                 elif (( $i == $stripe_index )); then
25664                         (( $count == 100 * MDSCOUNT )) ||
25665                                 error "$count subdirs created on MDT$i"
25666                 else
25667                         (( $count == 0 )) ||
25668                                 error "$count subdirs created on MDT$i"
25669                 fi
25670
25671                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25672                         count=$($LFS getdirstripe $testdir/* |
25673                                 grep -c -P "^\s+$i\t")
25674                         echo "$count stripes created on MDT$i"
25675                         # deviation should < 5% of average
25676                         (( $count >= 95 * stripe_count &&
25677                            $count <= 105 * stripe_count)) ||
25678                                 error "stripes are not evenly distributed"
25679                 fi
25680         done
25681
25682         echo
25683         echo "Check for uneven MDTs: "
25684
25685         local ffree
25686         local bavail
25687         local max
25688         local min
25689         local max_index
25690         local min_index
25691         local tmp
25692
25693         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25694         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25695         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25696
25697         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25698         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25699         max_index=0
25700         min_index=0
25701         for ((i = 1; i < ${#ffree[@]}; i++)); do
25702                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25703                 if [ $tmp -gt $max ]; then
25704                         max=$tmp
25705                         max_index=$i
25706                 fi
25707                 if [ $tmp -lt $min ]; then
25708                         min=$tmp
25709                         min_index=$i
25710                 fi
25711         done
25712
25713         (( ${ffree[min_index]} > 0 )) ||
25714                 skip "no free files in MDT$min_index"
25715         (( ${ffree[min_index]} < 10000000 )) ||
25716                 skip "too many free files in MDT$min_index"
25717
25718         echo "MDT filesfree available: ${ffree[*]}"
25719         echo "MDT blocks available: ${bavail[*]}"
25720         echo "weight diff=$(((max - min) * 100 / min))%"
25721         echo
25722         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25723
25724         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25725         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25726         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25727         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25728         # decrease statfs age, so that it can be updated in time
25729         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25730         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25731
25732         sleep 1
25733
25734         testdir=$DIR/$tdir-s$stripe_count/qos
25735         local num=200
25736
25737         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25738         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25739                 eval $mkdir_cmd $testdir/subdir$i ||
25740                         error "$mkdir_cmd subdir$i failed"
25741         done
25742
25743         max=0
25744         for (( i = 0; i < $MDSCOUNT; i++ )); do
25745                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25746                 (( count > max )) && max=$count
25747                 echo "$count directories created on MDT$i"
25748         done
25749
25750         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25751
25752         # D-value should > 10% of averge
25753         (( max - min > num / 10 )) ||
25754                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25755
25756         # ditto for stripes
25757         if (( stripe_count > 1 )); then
25758                 max=0
25759                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25760                         count=$($LFS getdirstripe $testdir/* |
25761                                 grep -c -P "^\s+$i\t")
25762                         (( count > max )) && max=$count
25763                         echo "$count stripes created on MDT$i"
25764                 done
25765
25766                 min=$($LFS getdirstripe $testdir/* |
25767                         grep -c -P "^\s+$min_index\t")
25768                 (( max - min > num * stripe_count / 10 )) ||
25769                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25770         fi
25771 }
25772
25773 most_full_mdt() {
25774         local ffree
25775         local bavail
25776         local bsize
25777         local min
25778         local min_index
25779         local tmp
25780
25781         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25782         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25783         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25784
25785         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25786         min_index=0
25787         for ((i = 1; i < ${#ffree[@]}; i++)); do
25788                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25789                 (( tmp < min )) && min=$tmp && min_index=$i
25790         done
25791
25792         echo -n $min_index
25793 }
25794
25795 test_413a() {
25796         [ $MDSCOUNT -lt 2 ] &&
25797                 skip "We need at least 2 MDTs for this test"
25798
25799         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25800                 skip "Need server version at least 2.12.52"
25801
25802         local stripe_count
25803
25804         generate_uneven_mdts 100
25805         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25806                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25807                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25808                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25809                         error "mkdir failed"
25810                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25811         done
25812 }
25813 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25814
25815 test_413b() {
25816         [ $MDSCOUNT -lt 2 ] &&
25817                 skip "We need at least 2 MDTs for this test"
25818
25819         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25820                 skip "Need server version at least 2.12.52"
25821
25822         local testdir
25823         local stripe_count
25824
25825         generate_uneven_mdts 100
25826         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25827                 testdir=$DIR/$tdir-s$stripe_count
25828                 mkdir $testdir || error "mkdir $testdir failed"
25829                 mkdir $testdir/rr || error "mkdir rr failed"
25830                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25831                         error "mkdir qos failed"
25832                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25833                         $testdir/rr || error "setdirstripe rr failed"
25834                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25835                         error "setdirstripe failed"
25836                 test_qos_mkdir "mkdir" $stripe_count
25837         done
25838 }
25839 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25840
25841 test_413c() {
25842         (( $MDSCOUNT >= 2 )) ||
25843                 skip "We need at least 2 MDTs for this test"
25844
25845         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25846                 skip "Need server version at least 2.14.51"
25847
25848         local testdir
25849         local inherit
25850         local inherit_rr
25851
25852         testdir=$DIR/${tdir}-s1
25853         mkdir $testdir || error "mkdir $testdir failed"
25854         mkdir $testdir/rr || error "mkdir rr failed"
25855         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25856         # default max_inherit is -1, default max_inherit_rr is 0
25857         $LFS setdirstripe -D -c 1 $testdir/rr ||
25858                 error "setdirstripe rr failed"
25859         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25860                 error "setdirstripe qos failed"
25861         test_qos_mkdir "mkdir" 1
25862
25863         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25864         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25865         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25866         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25867         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25868
25869         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25870         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25871         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25872         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25873         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25874         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25875         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25876                 error "level2 shouldn't have default LMV" || true
25877 }
25878 run_test 413c "mkdir with default LMV max inherit rr"
25879
25880 test_413d() {
25881         (( MDSCOUNT >= 2 )) ||
25882                 skip "We need at least 2 MDTs for this test"
25883
25884         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25885                 skip "Need server version at least 2.14.51"
25886
25887         local lmv_qos_threshold_rr
25888
25889         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25890                 head -n1)
25891         stack_trap "$LCTL set_param \
25892                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
25893
25894         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25895         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25896         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
25897                 error "$tdir shouldn't have default LMV"
25898         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
25899                 error "mkdir sub failed"
25900
25901         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
25902
25903         (( count == 100 )) || error "$count subdirs on MDT0"
25904 }
25905 run_test 413d "inherit ROOT default LMV"
25906
25907 test_413e() {
25908         (( MDSCOUNT >= 2 )) ||
25909                 skip "We need at least 2 MDTs for this test"
25910         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25911                 skip "Need server version at least 2.14.55"
25912
25913         local testdir=$DIR/$tdir
25914         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
25915         local max_inherit
25916         local sub_max_inherit
25917
25918         mkdir -p $testdir || error "failed to create $testdir"
25919
25920         # set default max-inherit to -1 if stripe count is 0 or 1
25921         $LFS setdirstripe -D -c 1 $testdir ||
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         # set default max_inherit to a fixed value if stripe count is not 0 or 1
25928         $LFS setdirstripe -D -c -1 $testdir ||
25929                 error "failed to set default LMV"
25930         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25931         (( max_inherit > 0 )) ||
25932                 error "wrong max_inherit value $max_inherit"
25933
25934         # and the subdir will decrease the max_inherit by 1
25935         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
25936         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
25937         (( sub_max_inherit == max_inherit - 1)) ||
25938                 error "wrong max-inherit of subdir $sub_max_inherit"
25939
25940         # check specified --max-inherit and warning message
25941         stack_trap "rm -f $tmpfile"
25942         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
25943                 error "failed to set default LMV"
25944         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25945         (( max_inherit == -1 )) ||
25946                 error "wrong max_inherit value $max_inherit"
25947
25948         # check the warning messages
25949         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
25950                 error "failed to detect warning string"
25951         fi
25952 }
25953 run_test 413e "check default max-inherit value"
25954
25955 test_fs_dmv_inherit()
25956 {
25957         local testdir=$DIR/$tdir
25958
25959         local count
25960         local inherit
25961         local inherit_rr
25962
25963         for i in 1 2 3; do
25964                 mkdir $testdir || error "mkdir $testdir failed"
25965                 count=$($LFS getdirstripe -D -c $testdir)
25966                 (( count == 1 )) ||
25967                         error "$testdir default LMV count mismatch $count != 1"
25968                 inherit=$($LFS getdirstripe -D -X $testdir)
25969                 (( inherit == 3 - i )) ||
25970                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
25971                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
25972                 (( inherit_rr == 3 - i )) ||
25973                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
25974                 testdir=$testdir/sub
25975         done
25976
25977         mkdir $testdir || error "mkdir $testdir failed"
25978         count=$($LFS getdirstripe -D -c $testdir)
25979         (( count == 0 )) ||
25980                 error "$testdir default LMV count not zero: $count"
25981 }
25982
25983 test_413f() {
25984         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
25985
25986         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25987                 skip "Need server version at least 2.14.55"
25988
25989         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
25990                 error "dump $DIR default LMV failed"
25991         stack_trap "setfattr --restore=$TMP/dmv.ea"
25992
25993         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
25994                 error "set $DIR default LMV failed"
25995
25996         test_fs_dmv_inherit
25997 }
25998 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
25999
26000 test_413g() {
26001         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26002
26003         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
26004         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26005                 error "dump $DIR default LMV failed"
26006         stack_trap "setfattr --restore=$TMP/dmv.ea"
26007
26008         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26009                 error "set $DIR default LMV failed"
26010
26011         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
26012                 error "mount $MOUNT2 failed"
26013         stack_trap "umount_client $MOUNT2"
26014
26015         local saved_DIR=$DIR
26016
26017         export DIR=$MOUNT2
26018
26019         stack_trap "export DIR=$saved_DIR"
26020
26021         # first check filesystem-wide default LMV inheritance
26022         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
26023
26024         # then check subdirs are spread to all MDTs
26025         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
26026
26027         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
26028
26029         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
26030 }
26031 run_test 413g "enforce ROOT default LMV on subdir mount"
26032
26033 test_413z() {
26034         local pids=""
26035         local subdir
26036         local pid
26037
26038         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
26039                 unlinkmany $subdir/f. 1000 &
26040                 pids="$pids $!"
26041         done
26042
26043         for pid in $pids; do
26044                 wait $pid
26045         done
26046 }
26047 run_test 413z "413 test cleanup"
26048
26049 test_414() {
26050 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
26051         $LCTL set_param fail_loc=0x80000521
26052         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26053         rm -f $DIR/$tfile
26054 }
26055 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
26056
26057 test_415() {
26058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26059         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26060                 skip "Need server version at least 2.11.52"
26061
26062         # LU-11102
26063         local total
26064         local setattr_pid
26065         local start_time
26066         local end_time
26067         local duration
26068
26069         total=500
26070         # this test may be slow on ZFS
26071         [ "$mds1_FSTYPE" == "zfs" ] && total=50
26072
26073         # though this test is designed for striped directory, let's test normal
26074         # directory too since lock is always saved as CoS lock.
26075         test_mkdir $DIR/$tdir || error "mkdir $tdir"
26076         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
26077
26078         (
26079                 while true; do
26080                         touch $DIR/$tdir
26081                 done
26082         ) &
26083         setattr_pid=$!
26084
26085         start_time=$(date +%s)
26086         for i in $(seq $total); do
26087                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
26088                         > /dev/null
26089         done
26090         end_time=$(date +%s)
26091         duration=$((end_time - start_time))
26092
26093         kill -9 $setattr_pid
26094
26095         echo "rename $total files took $duration sec"
26096         [ $duration -lt 100 ] || error "rename took $duration sec"
26097 }
26098 run_test 415 "lock revoke is not missing"
26099
26100 test_416() {
26101         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26102                 skip "Need server version at least 2.11.55"
26103
26104         # define OBD_FAIL_OSD_TXN_START    0x19a
26105         do_facet mds1 lctl set_param fail_loc=0x19a
26106
26107         lfs mkdir -c $MDSCOUNT $DIR/$tdir
26108
26109         true
26110 }
26111 run_test 416 "transaction start failure won't cause system hung"
26112
26113 cleanup_417() {
26114         trap 0
26115         do_nodes $(comma_list $(mdts_nodes)) \
26116                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
26117         do_nodes $(comma_list $(mdts_nodes)) \
26118                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
26119         do_nodes $(comma_list $(mdts_nodes)) \
26120                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
26121 }
26122
26123 test_417() {
26124         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26125         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
26126                 skip "Need MDS version at least 2.11.56"
26127
26128         trap cleanup_417 RETURN EXIT
26129
26130         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
26131         do_nodes $(comma_list $(mdts_nodes)) \
26132                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
26133         $LFS migrate -m 0 $DIR/$tdir.1 &&
26134                 error "migrate dir $tdir.1 should fail"
26135
26136         do_nodes $(comma_list $(mdts_nodes)) \
26137                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
26138         $LFS mkdir -i 1 $DIR/$tdir.2 &&
26139                 error "create remote dir $tdir.2 should fail"
26140
26141         do_nodes $(comma_list $(mdts_nodes)) \
26142                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
26143         $LFS mkdir -c 2 $DIR/$tdir.3 &&
26144                 error "create striped dir $tdir.3 should fail"
26145         true
26146 }
26147 run_test 417 "disable remote dir, striped dir and dir migration"
26148
26149 # Checks that the outputs of df [-i] and lfs df [-i] match
26150 #
26151 # usage: check_lfs_df <blocks | inodes> <mountpoint>
26152 check_lfs_df() {
26153         local dir=$2
26154         local inodes
26155         local df_out
26156         local lfs_df_out
26157         local count
26158         local passed=false
26159
26160         # blocks or inodes
26161         [ "$1" == "blocks" ] && inodes= || inodes="-i"
26162
26163         for count in {1..100}; do
26164                 do_nodes "$CLIENTS" \
26165                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26166                 sync; sleep 0.2
26167
26168                 # read the lines of interest
26169                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
26170                         error "df $inodes $dir | tail -n +2 failed"
26171                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
26172                         error "lfs df $inodes $dir | grep summary: failed"
26173
26174                 # skip first substrings of each output as they are different
26175                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
26176                 # compare the two outputs
26177                 passed=true
26178                 #  skip "available" on MDT until LU-13997 is fixed.
26179                 #for i in {1..5}; do
26180                 for i in 1 2 4 5; do
26181                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
26182                 done
26183                 $passed && break
26184         done
26185
26186         if ! $passed; then
26187                 df -P $inodes $dir
26188                 echo
26189                 lfs df $inodes $dir
26190                 error "df and lfs df $1 output mismatch: "      \
26191                       "df ${inodes}: ${df_out[*]}, "            \
26192                       "lfs df ${inodes}: ${lfs_df_out[*]}"
26193         fi
26194 }
26195
26196 test_418() {
26197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26198
26199         local dir=$DIR/$tdir
26200         local numfiles=$((RANDOM % 4096 + 2))
26201         local numblocks=$((RANDOM % 256 + 1))
26202
26203         wait_delete_completed
26204         test_mkdir $dir
26205
26206         # check block output
26207         check_lfs_df blocks $dir
26208         # check inode output
26209         check_lfs_df inodes $dir
26210
26211         # create a single file and retest
26212         echo "Creating a single file and testing"
26213         createmany -o $dir/$tfile- 1 &>/dev/null ||
26214                 error "creating 1 file in $dir failed"
26215         check_lfs_df blocks $dir
26216         check_lfs_df inodes $dir
26217
26218         # create a random number of files
26219         echo "Creating $((numfiles - 1)) files and testing"
26220         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
26221                 error "creating $((numfiles - 1)) files in $dir failed"
26222
26223         # write a random number of blocks to the first test file
26224         echo "Writing $numblocks 4K blocks and testing"
26225         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26226                 count=$numblocks &>/dev/null ||
26227                 error "dd to $dir/${tfile}-0 failed"
26228
26229         # retest
26230         check_lfs_df blocks $dir
26231         check_lfs_df inodes $dir
26232
26233         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
26234                 error "unlinking $numfiles files in $dir failed"
26235 }
26236 run_test 418 "df and lfs df outputs match"
26237
26238 test_419()
26239 {
26240         local dir=$DIR/$tdir
26241
26242         mkdir -p $dir
26243         touch $dir/file
26244
26245         cancel_lru_locks mdc
26246
26247         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26248         $LCTL set_param fail_loc=0x1410
26249         cat $dir/file
26250         $LCTL set_param fail_loc=0
26251         rm -rf $dir
26252 }
26253 run_test 419 "Verify open file by name doesn't crash kernel"
26254
26255 test_420()
26256 {
26257         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26258                 skip "Need MDS version at least 2.12.53"
26259
26260         local SAVE_UMASK=$(umask)
26261         local dir=$DIR/$tdir
26262         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26263
26264         mkdir -p $dir
26265         umask 0000
26266         mkdir -m03777 $dir/testdir
26267         ls -dn $dir/testdir
26268         # Need to remove trailing '.' when SELinux is enabled
26269         local dirperms=$(ls -dn $dir/testdir |
26270                          awk '{ sub(/\.$/, "", $1); print $1}')
26271         [ $dirperms == "drwxrwsrwt" ] ||
26272                 error "incorrect perms on $dir/testdir"
26273
26274         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26275                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26276         ls -n $dir/testdir/testfile
26277         local fileperms=$(ls -n $dir/testdir/testfile |
26278                           awk '{ sub(/\.$/, "", $1); print $1}')
26279         [ $fileperms == "-rwxr-xr-x" ] ||
26280                 error "incorrect perms on $dir/testdir/testfile"
26281
26282         umask $SAVE_UMASK
26283 }
26284 run_test 420 "clear SGID bit on non-directories for non-members"
26285
26286 test_421a() {
26287         local cnt
26288         local fid1
26289         local fid2
26290
26291         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26292                 skip "Need MDS version at least 2.12.54"
26293
26294         test_mkdir $DIR/$tdir
26295         createmany -o $DIR/$tdir/f 3
26296         cnt=$(ls -1 $DIR/$tdir | wc -l)
26297         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26298
26299         fid1=$(lfs path2fid $DIR/$tdir/f1)
26300         fid2=$(lfs path2fid $DIR/$tdir/f2)
26301         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26302
26303         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26304         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26305
26306         cnt=$(ls -1 $DIR/$tdir | wc -l)
26307         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26308
26309         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26310         createmany -o $DIR/$tdir/f 3
26311         cnt=$(ls -1 $DIR/$tdir | wc -l)
26312         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26313
26314         fid1=$(lfs path2fid $DIR/$tdir/f1)
26315         fid2=$(lfs path2fid $DIR/$tdir/f2)
26316         echo "remove using fsname $FSNAME"
26317         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26318
26319         cnt=$(ls -1 $DIR/$tdir | wc -l)
26320         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26321 }
26322 run_test 421a "simple rm by fid"
26323
26324 test_421b() {
26325         local cnt
26326         local FID1
26327         local FID2
26328
26329         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26330                 skip "Need MDS version at least 2.12.54"
26331
26332         test_mkdir $DIR/$tdir
26333         createmany -o $DIR/$tdir/f 3
26334         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26335         MULTIPID=$!
26336
26337         FID1=$(lfs path2fid $DIR/$tdir/f1)
26338         FID2=$(lfs path2fid $DIR/$tdir/f2)
26339         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26340
26341         kill -USR1 $MULTIPID
26342         wait
26343
26344         cnt=$(ls $DIR/$tdir | wc -l)
26345         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26346 }
26347 run_test 421b "rm by fid on open file"
26348
26349 test_421c() {
26350         local cnt
26351         local FIDS
26352
26353         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26354                 skip "Need MDS version at least 2.12.54"
26355
26356         test_mkdir $DIR/$tdir
26357         createmany -o $DIR/$tdir/f 3
26358         touch $DIR/$tdir/$tfile
26359         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26360         cnt=$(ls -1 $DIR/$tdir | wc -l)
26361         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26362
26363         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26364         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26365
26366         cnt=$(ls $DIR/$tdir | wc -l)
26367         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26368 }
26369 run_test 421c "rm by fid against hardlinked files"
26370
26371 test_421d() {
26372         local cnt
26373         local FIDS
26374
26375         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26376                 skip "Need MDS version at least 2.12.54"
26377
26378         test_mkdir $DIR/$tdir
26379         createmany -o $DIR/$tdir/f 4097
26380         cnt=$(ls -1 $DIR/$tdir | wc -l)
26381         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26382
26383         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26384         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26385
26386         cnt=$(ls $DIR/$tdir | wc -l)
26387         rm -rf $DIR/$tdir
26388         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26389 }
26390 run_test 421d "rmfid en masse"
26391
26392 test_421e() {
26393         local cnt
26394         local FID
26395
26396         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26397         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26398                 skip "Need MDS version at least 2.12.54"
26399
26400         mkdir -p $DIR/$tdir
26401         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26402         createmany -o $DIR/$tdir/striped_dir/f 512
26403         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26404         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26405
26406         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26407                 sed "s/[/][^:]*://g")
26408         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26409
26410         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26411         rm -rf $DIR/$tdir
26412         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26413 }
26414 run_test 421e "rmfid in DNE"
26415
26416 test_421f() {
26417         local cnt
26418         local FID
26419
26420         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26421                 skip "Need MDS version at least 2.12.54"
26422
26423         test_mkdir $DIR/$tdir
26424         touch $DIR/$tdir/f
26425         cnt=$(ls -1 $DIR/$tdir | wc -l)
26426         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26427
26428         FID=$(lfs path2fid $DIR/$tdir/f)
26429         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26430         # rmfid should fail
26431         cnt=$(ls -1 $DIR/$tdir | wc -l)
26432         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26433
26434         chmod a+rw $DIR/$tdir
26435         ls -la $DIR/$tdir
26436         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26437         # rmfid should fail
26438         cnt=$(ls -1 $DIR/$tdir | wc -l)
26439         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26440
26441         rm -f $DIR/$tdir/f
26442         $RUNAS touch $DIR/$tdir/f
26443         FID=$(lfs path2fid $DIR/$tdir/f)
26444         echo "rmfid as root"
26445         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26446         cnt=$(ls -1 $DIR/$tdir | wc -l)
26447         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26448
26449         rm -f $DIR/$tdir/f
26450         $RUNAS touch $DIR/$tdir/f
26451         cnt=$(ls -1 $DIR/$tdir | wc -l)
26452         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26453         FID=$(lfs path2fid $DIR/$tdir/f)
26454         # rmfid w/o user_fid2path mount option should fail
26455         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26456         cnt=$(ls -1 $DIR/$tdir | wc -l)
26457         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26458
26459         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26460         stack_trap "rmdir $tmpdir"
26461         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26462                 error "failed to mount client'"
26463         stack_trap "umount_client $tmpdir"
26464
26465         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26466         # rmfid should succeed
26467         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26468         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26469
26470         # rmfid shouldn't allow to remove files due to dir's permission
26471         chmod a+rwx $tmpdir/$tdir
26472         touch $tmpdir/$tdir/f
26473         ls -la $tmpdir/$tdir
26474         FID=$(lfs path2fid $tmpdir/$tdir/f)
26475         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26476         return 0
26477 }
26478 run_test 421f "rmfid checks permissions"
26479
26480 test_421g() {
26481         local cnt
26482         local FIDS
26483
26484         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26485         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26486                 skip "Need MDS version at least 2.12.54"
26487
26488         mkdir -p $DIR/$tdir
26489         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26490         createmany -o $DIR/$tdir/striped_dir/f 512
26491         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26492         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26493
26494         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26495                 sed "s/[/][^:]*://g")
26496
26497         rm -f $DIR/$tdir/striped_dir/f1*
26498         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26499         removed=$((512 - cnt))
26500
26501         # few files have been just removed, so we expect
26502         # rmfid to fail on their fids
26503         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26504         [ $removed != $errors ] && error "$errors != $removed"
26505
26506         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26507         rm -rf $DIR/$tdir
26508         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26509 }
26510 run_test 421g "rmfid to return errors properly"
26511
26512 test_422() {
26513         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26514         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26515         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26516         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26517         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26518
26519         local amc=$(at_max_get client)
26520         local amo=$(at_max_get mds1)
26521         local timeout=`lctl get_param -n timeout`
26522
26523         at_max_set 0 client
26524         at_max_set 0 mds1
26525
26526 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26527         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26528                         fail_val=$(((2*timeout + 10)*1000))
26529         touch $DIR/$tdir/d3/file &
26530         sleep 2
26531 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26532         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26533                         fail_val=$((2*timeout + 5))
26534         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26535         local pid=$!
26536         sleep 1
26537         kill -9 $pid
26538         sleep $((2 * timeout))
26539         echo kill $pid
26540         kill -9 $pid
26541         lctl mark touch
26542         touch $DIR/$tdir/d2/file3
26543         touch $DIR/$tdir/d2/file4
26544         touch $DIR/$tdir/d2/file5
26545
26546         wait
26547         at_max_set $amc client
26548         at_max_set $amo mds1
26549
26550         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26551         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26552                 error "Watchdog is always throttled"
26553 }
26554 run_test 422 "kill a process with RPC in progress"
26555
26556 stat_test() {
26557     df -h $MOUNT &
26558     df -h $MOUNT &
26559     df -h $MOUNT &
26560     df -h $MOUNT &
26561     df -h $MOUNT &
26562     df -h $MOUNT &
26563 }
26564
26565 test_423() {
26566     local _stats
26567     # ensure statfs cache is expired
26568     sleep 2;
26569
26570     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26571     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26572
26573     return 0
26574 }
26575 run_test 423 "statfs should return a right data"
26576
26577 test_424() {
26578 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26579         $LCTL set_param fail_loc=0x80000522
26580         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26581         rm -f $DIR/$tfile
26582 }
26583 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26584
26585 test_425() {
26586         test_mkdir -c -1 $DIR/$tdir
26587         $LFS setstripe -c -1 $DIR/$tdir
26588
26589         lru_resize_disable "" 100
26590         stack_trap "lru_resize_enable" EXIT
26591
26592         sleep 5
26593
26594         for i in $(seq $((MDSCOUNT * 125))); do
26595                 local t=$DIR/$tdir/$tfile_$i
26596
26597                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26598                         error_noexit "Create file $t"
26599         done
26600         stack_trap "rm -rf $DIR/$tdir" EXIT
26601
26602         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26603                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26604                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26605
26606                 [ $lock_count -le $lru_size ] ||
26607                         error "osc lock count $lock_count > lru size $lru_size"
26608         done
26609
26610         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26611                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26612                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26613
26614                 [ $lock_count -le $lru_size ] ||
26615                         error "mdc lock count $lock_count > lru size $lru_size"
26616         done
26617 }
26618 run_test 425 "lock count should not exceed lru size"
26619
26620 test_426() {
26621         splice-test -r $DIR/$tfile
26622         splice-test -rd $DIR/$tfile
26623         splice-test $DIR/$tfile
26624         splice-test -d $DIR/$tfile
26625 }
26626 run_test 426 "splice test on Lustre"
26627
26628 test_427() {
26629         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26630         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26631                 skip "Need MDS version at least 2.12.4"
26632         local log
26633
26634         mkdir $DIR/$tdir
26635         mkdir $DIR/$tdir/1
26636         mkdir $DIR/$tdir/2
26637         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26638         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26639
26640         $LFS getdirstripe $DIR/$tdir/1/dir
26641
26642         #first setfattr for creating updatelog
26643         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26644
26645 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26646         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26647         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26648         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26649
26650         sleep 2
26651         fail mds2
26652         wait_recovery_complete mds2 $((2*TIMEOUT))
26653
26654         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26655         echo $log | grep "get update log failed" &&
26656                 error "update log corruption is detected" || true
26657 }
26658 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26659
26660 test_428() {
26661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26662         local cache_limit=$CACHE_MAX
26663
26664         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26665         $LCTL set_param -n llite.*.max_cached_mb=64
26666
26667         mkdir $DIR/$tdir
26668         $LFS setstripe -c 1 $DIR/$tdir
26669         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26670         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26671         #test write
26672         for f in $(seq 4); do
26673                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26674         done
26675         wait
26676
26677         cancel_lru_locks osc
26678         # Test read
26679         for f in $(seq 4); do
26680                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26681         done
26682         wait
26683 }
26684 run_test 428 "large block size IO should not hang"
26685
26686 test_429() { # LU-7915 / LU-10948
26687         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26688         local testfile=$DIR/$tfile
26689         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26690         local new_flag=1
26691         local first_rpc
26692         local second_rpc
26693         local third_rpc
26694
26695         $LCTL get_param $ll_opencache_threshold_count ||
26696                 skip "client does not have opencache parameter"
26697
26698         set_opencache $new_flag
26699         stack_trap "restore_opencache"
26700         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26701                 error "enable opencache failed"
26702         touch $testfile
26703         # drop MDC DLM locks
26704         cancel_lru_locks mdc
26705         # clear MDC RPC stats counters
26706         $LCTL set_param $mdc_rpcstats=clear
26707
26708         # According to the current implementation, we need to run 3 times
26709         # open & close file to verify if opencache is enabled correctly.
26710         # 1st, RPCs are sent for lookup/open and open handle is released on
26711         #      close finally.
26712         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26713         #      so open handle won't be released thereafter.
26714         # 3rd, No RPC is sent out.
26715         $MULTIOP $testfile oc || error "multiop failed"
26716         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26717         echo "1st: $first_rpc RPCs in flight"
26718
26719         $MULTIOP $testfile oc || error "multiop failed"
26720         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26721         echo "2nd: $second_rpc RPCs in flight"
26722
26723         $MULTIOP $testfile oc || error "multiop failed"
26724         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26725         echo "3rd: $third_rpc RPCs in flight"
26726
26727         #verify no MDC RPC is sent
26728         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26729 }
26730 run_test 429 "verify if opencache flag on client side does work"
26731
26732 lseek_test_430() {
26733         local offset
26734         local file=$1
26735
26736         # data at [200K, 400K)
26737         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26738                 error "256K->512K dd fails"
26739         # data at [2M, 3M)
26740         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26741                 error "2M->3M dd fails"
26742         # data at [4M, 5M)
26743         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26744                 error "4M->5M dd fails"
26745         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26746         # start at first component hole #1
26747         printf "Seeking hole from 1000 ... "
26748         offset=$(lseek_test -l 1000 $file)
26749         echo $offset
26750         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26751         printf "Seeking data from 1000 ... "
26752         offset=$(lseek_test -d 1000 $file)
26753         echo $offset
26754         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26755
26756         # start at first component data block
26757         printf "Seeking hole from 300000 ... "
26758         offset=$(lseek_test -l 300000 $file)
26759         echo $offset
26760         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26761         printf "Seeking data from 300000 ... "
26762         offset=$(lseek_test -d 300000 $file)
26763         echo $offset
26764         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26765
26766         # start at the first component but beyond end of object size
26767         printf "Seeking hole from 1000000 ... "
26768         offset=$(lseek_test -l 1000000 $file)
26769         echo $offset
26770         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26771         printf "Seeking data from 1000000 ... "
26772         offset=$(lseek_test -d 1000000 $file)
26773         echo $offset
26774         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26775
26776         # start at second component stripe 2 (empty file)
26777         printf "Seeking hole from 1500000 ... "
26778         offset=$(lseek_test -l 1500000 $file)
26779         echo $offset
26780         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26781         printf "Seeking data from 1500000 ... "
26782         offset=$(lseek_test -d 1500000 $file)
26783         echo $offset
26784         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26785
26786         # start at second component stripe 1 (all data)
26787         printf "Seeking hole from 3000000 ... "
26788         offset=$(lseek_test -l 3000000 $file)
26789         echo $offset
26790         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26791         printf "Seeking data from 3000000 ... "
26792         offset=$(lseek_test -d 3000000 $file)
26793         echo $offset
26794         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26795
26796         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26797                 error "2nd dd fails"
26798         echo "Add data block at 640K...1280K"
26799
26800         # start at before new data block, in hole
26801         printf "Seeking hole from 600000 ... "
26802         offset=$(lseek_test -l 600000 $file)
26803         echo $offset
26804         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26805         printf "Seeking data from 600000 ... "
26806         offset=$(lseek_test -d 600000 $file)
26807         echo $offset
26808         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26809
26810         # start at the first component new data block
26811         printf "Seeking hole from 1000000 ... "
26812         offset=$(lseek_test -l 1000000 $file)
26813         echo $offset
26814         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26815         printf "Seeking data from 1000000 ... "
26816         offset=$(lseek_test -d 1000000 $file)
26817         echo $offset
26818         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26819
26820         # start at second component stripe 2, new data
26821         printf "Seeking hole from 1200000 ... "
26822         offset=$(lseek_test -l 1200000 $file)
26823         echo $offset
26824         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26825         printf "Seeking data from 1200000 ... "
26826         offset=$(lseek_test -d 1200000 $file)
26827         echo $offset
26828         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
26829
26830         # start beyond file end
26831         printf "Using offset > filesize ... "
26832         lseek_test -l 4000000 $file && error "lseek should fail"
26833         printf "Using offset > filesize ... "
26834         lseek_test -d 4000000 $file && error "lseek should fail"
26835
26836         printf "Done\n\n"
26837 }
26838
26839 test_430a() {
26840         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
26841                 skip "MDT does not support SEEK_HOLE"
26842
26843         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26844                 skip "OST does not support SEEK_HOLE"
26845
26846         local file=$DIR/$tdir/$tfile
26847
26848         mkdir -p $DIR/$tdir
26849
26850         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
26851         # OST stripe #1 will have continuous data at [1M, 3M)
26852         # OST stripe #2 is empty
26853         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
26854         lseek_test_430 $file
26855         rm $file
26856         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
26857         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
26858         lseek_test_430 $file
26859         rm $file
26860         $LFS setstripe -c2 -S 512K $file
26861         echo "Two stripes, stripe size 512K"
26862         lseek_test_430 $file
26863         rm $file
26864         # FLR with stale mirror
26865         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
26866                        -N -c2 -S 1M $file
26867         echo "Mirrored file:"
26868         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
26869         echo "Plain 2 stripes 1M"
26870         lseek_test_430 $file
26871         rm $file
26872 }
26873 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
26874
26875 test_430b() {
26876         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26877                 skip "OST does not support SEEK_HOLE"
26878
26879         local offset
26880         local file=$DIR/$tdir/$tfile
26881
26882         mkdir -p $DIR/$tdir
26883         # Empty layout lseek should fail
26884         $MCREATE $file
26885         # seek from 0
26886         printf "Seeking hole from 0 ... "
26887         lseek_test -l 0 $file && error "lseek should fail"
26888         printf "Seeking data from 0 ... "
26889         lseek_test -d 0 $file && error "lseek should fail"
26890         rm $file
26891
26892         # 1M-hole file
26893         $LFS setstripe -E 1M -c2 -E eof $file
26894         $TRUNCATE $file 1048576
26895         printf "Seeking hole from 1000000 ... "
26896         offset=$(lseek_test -l 1000000 $file)
26897         echo $offset
26898         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26899         printf "Seeking data from 1000000 ... "
26900         lseek_test -d 1000000 $file && error "lseek should fail"
26901         rm $file
26902
26903         # full component followed by non-inited one
26904         $LFS setstripe -E 1M -c2 -E eof $file
26905         dd if=/dev/urandom of=$file bs=1M count=1
26906         printf "Seeking hole from 1000000 ... "
26907         offset=$(lseek_test -l 1000000 $file)
26908         echo $offset
26909         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26910         printf "Seeking hole from 1048576 ... "
26911         lseek_test -l 1048576 $file && error "lseek should fail"
26912         # init second component and truncate back
26913         echo "123" >> $file
26914         $TRUNCATE $file 1048576
26915         printf "Seeking hole from 1000000 ... "
26916         offset=$(lseek_test -l 1000000 $file)
26917         echo $offset
26918         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26919         printf "Seeking hole from 1048576 ... "
26920         lseek_test -l 1048576 $file && error "lseek should fail"
26921         # boundary checks for big values
26922         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
26923         offset=$(lseek_test -d 0 $file.10g)
26924         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
26925         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
26926         offset=$(lseek_test -d 0 $file.100g)
26927         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
26928         return 0
26929 }
26930 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
26931
26932 test_430c() {
26933         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26934                 skip "OST does not support SEEK_HOLE"
26935
26936         local file=$DIR/$tdir/$tfile
26937         local start
26938
26939         mkdir -p $DIR/$tdir
26940         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
26941
26942         # cp version 8.33+ prefers lseek over fiemap
26943         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
26944                 start=$SECONDS
26945                 time cp $file /dev/null
26946                 (( SECONDS - start < 5 )) ||
26947                         error "cp: too long runtime $((SECONDS - start))"
26948
26949         fi
26950         # tar version 1.29+ supports SEEK_HOLE/DATA
26951         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
26952                 start=$SECONDS
26953                 time tar cS $file - | cat > /dev/null
26954                 (( SECONDS - start < 5 )) ||
26955                         error "tar: too long runtime $((SECONDS - start))"
26956         fi
26957 }
26958 run_test 430c "lseek: external tools check"
26959
26960 test_431() { # LU-14187
26961         local file=$DIR/$tdir/$tfile
26962
26963         mkdir -p $DIR/$tdir
26964         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
26965         dd if=/dev/urandom of=$file bs=4k count=1
26966         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
26967         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
26968         #define OBD_FAIL_OST_RESTART_IO 0x251
26969         do_facet ost1 "$LCTL set_param fail_loc=0x251"
26970         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
26971         cp $file $file.0
26972         cancel_lru_locks
26973         sync_all_data
26974         echo 3 > /proc/sys/vm/drop_caches
26975         diff  $file $file.0 || error "data diff"
26976 }
26977 run_test 431 "Restart transaction for IO"
26978
26979 cleanup_test_432() {
26980         do_facet mgs $LCTL nodemap_activate 0
26981         wait_nm_sync active
26982 }
26983
26984 test_432() {
26985         local tmpdir=$TMP/dir432
26986
26987         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
26988                 skip "Need MDS version at least 2.14.52"
26989
26990         stack_trap cleanup_test_432 EXIT
26991         mkdir $DIR/$tdir
26992         mkdir $tmpdir
26993
26994         do_facet mgs $LCTL nodemap_activate 1
26995         wait_nm_sync active
26996         do_facet mgs $LCTL nodemap_modify --name default \
26997                 --property admin --value 1
26998         do_facet mgs $LCTL nodemap_modify --name default \
26999                 --property trusted --value 1
27000         cancel_lru_locks mdc
27001         wait_nm_sync default admin_nodemap
27002         wait_nm_sync default trusted_nodemap
27003
27004         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
27005                grep -ci "Operation not permitted") -ne 0 ]; then
27006                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
27007         fi
27008 }
27009 run_test 432 "mv dir from outside Lustre"
27010
27011 test_433() {
27012         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27013
27014         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
27015                 skip "inode cache not supported"
27016
27017         $LCTL set_param llite.*.inode_cache=0
27018         stack_trap "$LCTL set_param llite.*.inode_cache=1"
27019
27020         local count=256
27021         local before
27022         local after
27023
27024         cancel_lru_locks mdc
27025         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27026         createmany -m $DIR/$tdir/f $count
27027         createmany -d $DIR/$tdir/d $count
27028         ls -l $DIR/$tdir > /dev/null
27029         stack_trap "rm -rf $DIR/$tdir"
27030
27031         before=$(num_objects)
27032         cancel_lru_locks mdc
27033         after=$(num_objects)
27034
27035         # sometimes even @before is less than 2 * count
27036         while (( before - after < count )); do
27037                 sleep 1
27038                 after=$(num_objects)
27039                 wait=$((wait + 1))
27040                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
27041                 if (( wait > 60 )); then
27042                         error "inode slab grew from $before to $after"
27043                 fi
27044         done
27045
27046         echo "lustre_inode_cache $before objs before lock cancel, $after after"
27047 }
27048 run_test 433 "ldlm lock cancel releases dentries and inodes"
27049
27050 prep_801() {
27051         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27052         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27053                 skip "Need server version at least 2.9.55"
27054
27055         start_full_debug_logging
27056 }
27057
27058 post_801() {
27059         stop_full_debug_logging
27060 }
27061
27062 barrier_stat() {
27063         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27064                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27065                            awk '/The barrier for/ { print $7 }')
27066                 echo $st
27067         else
27068                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
27069                 echo \'$st\'
27070         fi
27071 }
27072
27073 barrier_expired() {
27074         local expired
27075
27076         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27077                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27078                           awk '/will be expired/ { print $7 }')
27079         else
27080                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
27081         fi
27082
27083         echo $expired
27084 }
27085
27086 test_801a() {
27087         prep_801
27088
27089         echo "Start barrier_freeze at: $(date)"
27090         #define OBD_FAIL_BARRIER_DELAY          0x2202
27091         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27092         # Do not reduce barrier time - See LU-11873
27093         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
27094
27095         sleep 2
27096         local b_status=$(barrier_stat)
27097         echo "Got barrier status at: $(date)"
27098         [ "$b_status" = "'freezing_p1'" ] ||
27099                 error "(1) unexpected barrier status $b_status"
27100
27101         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27102         wait
27103         b_status=$(barrier_stat)
27104         [ "$b_status" = "'frozen'" ] ||
27105                 error "(2) unexpected barrier status $b_status"
27106
27107         local expired=$(barrier_expired)
27108         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
27109         sleep $((expired + 3))
27110
27111         b_status=$(barrier_stat)
27112         [ "$b_status" = "'expired'" ] ||
27113                 error "(3) unexpected barrier status $b_status"
27114
27115         # Do not reduce barrier time - See LU-11873
27116         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
27117                 error "(4) fail to freeze barrier"
27118
27119         b_status=$(barrier_stat)
27120         [ "$b_status" = "'frozen'" ] ||
27121                 error "(5) unexpected barrier status $b_status"
27122
27123         echo "Start barrier_thaw at: $(date)"
27124         #define OBD_FAIL_BARRIER_DELAY          0x2202
27125         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27126         do_facet mgs $LCTL barrier_thaw $FSNAME &
27127
27128         sleep 2
27129         b_status=$(barrier_stat)
27130         echo "Got barrier status at: $(date)"
27131         [ "$b_status" = "'thawing'" ] ||
27132                 error "(6) unexpected barrier status $b_status"
27133
27134         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27135         wait
27136         b_status=$(barrier_stat)
27137         [ "$b_status" = "'thawed'" ] ||
27138                 error "(7) unexpected barrier status $b_status"
27139
27140         #define OBD_FAIL_BARRIER_FAILURE        0x2203
27141         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
27142         do_facet mgs $LCTL barrier_freeze $FSNAME
27143
27144         b_status=$(barrier_stat)
27145         [ "$b_status" = "'failed'" ] ||
27146                 error "(8) unexpected barrier status $b_status"
27147
27148         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
27149         do_facet mgs $LCTL barrier_thaw $FSNAME
27150
27151         post_801
27152 }
27153 run_test 801a "write barrier user interfaces and stat machine"
27154
27155 test_801b() {
27156         prep_801
27157
27158         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27159         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
27160         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
27161         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
27162         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
27163
27164         cancel_lru_locks mdc
27165
27166         # 180 seconds should be long enough
27167         do_facet mgs $LCTL barrier_freeze $FSNAME 180
27168
27169         local b_status=$(barrier_stat)
27170         [ "$b_status" = "'frozen'" ] ||
27171                 error "(6) unexpected barrier status $b_status"
27172
27173         mkdir $DIR/$tdir/d0/d10 &
27174         mkdir_pid=$!
27175
27176         touch $DIR/$tdir/d1/f13 &
27177         touch_pid=$!
27178
27179         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
27180         ln_pid=$!
27181
27182         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
27183         mv_pid=$!
27184
27185         rm -f $DIR/$tdir/d4/f12 &
27186         rm_pid=$!
27187
27188         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
27189
27190         # To guarantee taht the 'stat' is not blocked
27191         b_status=$(barrier_stat)
27192         [ "$b_status" = "'frozen'" ] ||
27193                 error "(8) unexpected barrier status $b_status"
27194
27195         # let above commands to run at background
27196         sleep 5
27197
27198         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
27199         ps -p $touch_pid || error "(10) touch should be blocked"
27200         ps -p $ln_pid || error "(11) link should be blocked"
27201         ps -p $mv_pid || error "(12) rename should be blocked"
27202         ps -p $rm_pid || error "(13) unlink should be blocked"
27203
27204         b_status=$(barrier_stat)
27205         [ "$b_status" = "'frozen'" ] ||
27206                 error "(14) unexpected barrier status $b_status"
27207
27208         do_facet mgs $LCTL barrier_thaw $FSNAME
27209         b_status=$(barrier_stat)
27210         [ "$b_status" = "'thawed'" ] ||
27211                 error "(15) unexpected barrier status $b_status"
27212
27213         wait $mkdir_pid || error "(16) mkdir should succeed"
27214         wait $touch_pid || error "(17) touch should succeed"
27215         wait $ln_pid || error "(18) link should succeed"
27216         wait $mv_pid || error "(19) rename should succeed"
27217         wait $rm_pid || error "(20) unlink should succeed"
27218
27219         post_801
27220 }
27221 run_test 801b "modification will be blocked by write barrier"
27222
27223 test_801c() {
27224         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27225
27226         prep_801
27227
27228         stop mds2 || error "(1) Fail to stop mds2"
27229
27230         do_facet mgs $LCTL barrier_freeze $FSNAME 30
27231
27232         local b_status=$(barrier_stat)
27233         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
27234                 do_facet mgs $LCTL barrier_thaw $FSNAME
27235                 error "(2) unexpected barrier status $b_status"
27236         }
27237
27238         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27239                 error "(3) Fail to rescan barrier bitmap"
27240
27241         # Do not reduce barrier time - See LU-11873
27242         do_facet mgs $LCTL barrier_freeze $FSNAME 20
27243
27244         b_status=$(barrier_stat)
27245         [ "$b_status" = "'frozen'" ] ||
27246                 error "(4) unexpected barrier status $b_status"
27247
27248         do_facet mgs $LCTL barrier_thaw $FSNAME
27249         b_status=$(barrier_stat)
27250         [ "$b_status" = "'thawed'" ] ||
27251                 error "(5) unexpected barrier status $b_status"
27252
27253         local devname=$(mdsdevname 2)
27254
27255         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
27256
27257         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27258                 error "(7) Fail to rescan barrier bitmap"
27259
27260         post_801
27261 }
27262 run_test 801c "rescan barrier bitmap"
27263
27264 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
27265 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
27266 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
27267 saved_MOUNT_OPTS=$MOUNT_OPTS
27268
27269 cleanup_802a() {
27270         trap 0
27271
27272         stopall
27273         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
27274         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
27275         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
27276         MOUNT_OPTS=$saved_MOUNT_OPTS
27277         setupall
27278 }
27279
27280 test_802a() {
27281         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
27282         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27283         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27284                 skip "Need server version at least 2.9.55"
27285
27286         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
27287
27288         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27289
27290         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27291                 error "(2) Fail to copy"
27292
27293         trap cleanup_802a EXIT
27294
27295         # sync by force before remount as readonly
27296         sync; sync_all_data; sleep 3; sync_all_data
27297
27298         stopall
27299
27300         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
27301         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
27302         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
27303
27304         echo "Mount the server as read only"
27305         setupall server_only || error "(3) Fail to start servers"
27306
27307         echo "Mount client without ro should fail"
27308         mount_client $MOUNT &&
27309                 error "(4) Mount client without 'ro' should fail"
27310
27311         echo "Mount client with ro should succeed"
27312         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
27313         mount_client $MOUNT ||
27314                 error "(5) Mount client with 'ro' should succeed"
27315
27316         echo "Modify should be refused"
27317         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27318
27319         echo "Read should be allowed"
27320         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27321                 error "(7) Read should succeed under ro mode"
27322
27323         cleanup_802a
27324 }
27325 run_test 802a "simulate readonly device"
27326
27327 test_802b() {
27328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27329         remote_mds_nodsh && skip "remote MDS with nodsh"
27330
27331         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27332                 skip "readonly option not available"
27333
27334         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27335
27336         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27337                 error "(2) Fail to copy"
27338
27339         # write back all cached data before setting MDT to readonly
27340         cancel_lru_locks
27341         sync_all_data
27342
27343         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27344         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27345
27346         echo "Modify should be refused"
27347         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27348
27349         echo "Read should be allowed"
27350         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27351                 error "(7) Read should succeed under ro mode"
27352
27353         # disable readonly
27354         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27355 }
27356 run_test 802b "be able to set MDTs to readonly"
27357
27358 test_803a() {
27359         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27360         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27361                 skip "MDS needs to be newer than 2.10.54"
27362
27363         mkdir_on_mdt0 $DIR/$tdir
27364         # Create some objects on all MDTs to trigger related logs objects
27365         for idx in $(seq $MDSCOUNT); do
27366                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27367                         $DIR/$tdir/dir${idx} ||
27368                         error "Fail to create $DIR/$tdir/dir${idx}"
27369         done
27370
27371         sync; sleep 3
27372         wait_delete_completed # ensure old test cleanups are finished
27373         echo "before create:"
27374         $LFS df -i $MOUNT
27375         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27376
27377         for i in {1..10}; do
27378                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27379                         error "Fail to create $DIR/$tdir/foo$i"
27380         done
27381
27382         sync; sleep 3
27383         echo "after create:"
27384         $LFS df -i $MOUNT
27385         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27386
27387         # allow for an llog to be cleaned up during the test
27388         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27389                 error "before ($before_used) + 10 > after ($after_used)"
27390
27391         for i in {1..10}; do
27392                 rm -rf $DIR/$tdir/foo$i ||
27393                         error "Fail to remove $DIR/$tdir/foo$i"
27394         done
27395
27396         sleep 3 # avoid MDT return cached statfs
27397         wait_delete_completed
27398         echo "after unlink:"
27399         $LFS df -i $MOUNT
27400         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27401
27402         # allow for an llog to be created during the test
27403         [ $after_used -le $((before_used + 1)) ] ||
27404                 error "after ($after_used) > before ($before_used) + 1"
27405 }
27406 run_test 803a "verify agent object for remote object"
27407
27408 test_803b() {
27409         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27410         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27411                 skip "MDS needs to be newer than 2.13.56"
27412         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27413
27414         for i in $(seq 0 $((MDSCOUNT - 1))); do
27415                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27416         done
27417
27418         local before=0
27419         local after=0
27420
27421         local tmp
27422
27423         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27424         for i in $(seq 0 $((MDSCOUNT - 1))); do
27425                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27426                         awk '/getattr/ { print $2 }')
27427                 before=$((before + tmp))
27428         done
27429         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27430         for i in $(seq 0 $((MDSCOUNT - 1))); do
27431                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27432                         awk '/getattr/ { print $2 }')
27433                 after=$((after + tmp))
27434         done
27435
27436         [ $before -eq $after ] || error "getattr count $before != $after"
27437 }
27438 run_test 803b "remote object can getattr from cache"
27439
27440 test_804() {
27441         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27442         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27443                 skip "MDS needs to be newer than 2.10.54"
27444         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27445
27446         mkdir -p $DIR/$tdir
27447         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27448                 error "Fail to create $DIR/$tdir/dir0"
27449
27450         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27451         local dev=$(mdsdevname 2)
27452
27453         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27454                 grep ${fid} || error "NOT found agent entry for dir0"
27455
27456         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27457                 error "Fail to create $DIR/$tdir/dir1"
27458
27459         touch $DIR/$tdir/dir1/foo0 ||
27460                 error "Fail to create $DIR/$tdir/dir1/foo0"
27461         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27462         local rc=0
27463
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
27471         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27472                 error "Fail to rename foo0 to foo1"
27473         if [ $rc -eq 0 ]; then
27474                 for idx in $(seq $MDSCOUNT); do
27475                         dev=$(mdsdevname $idx)
27476                         do_facet mds${idx} \
27477                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27478                         grep ${fid} && rc=$idx
27479                 done
27480         fi
27481
27482         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27483                 error "Fail to rename foo1 to foo2"
27484         if [ $rc -eq 0 ]; then
27485                 for idx in $(seq $MDSCOUNT); do
27486                         dev=$(mdsdevname $idx)
27487                         do_facet mds${idx} \
27488                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27489                         grep ${fid} && rc=$idx
27490                 done
27491         fi
27492
27493         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27494
27495         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27496                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27497         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27498                 error "Fail to rename foo2 to foo0"
27499         unlink $DIR/$tdir/dir1/foo0 ||
27500                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27501         rm -rf $DIR/$tdir/dir0 ||
27502                 error "Fail to rm $DIR/$tdir/dir0"
27503
27504         for idx in $(seq $MDSCOUNT); do
27505                 rc=0
27506
27507                 stop mds${idx}
27508                 dev=$(mdsdevname $idx)
27509                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27510                         rc=$?
27511                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27512                         error "mount mds$idx failed"
27513                 df $MOUNT > /dev/null 2>&1
27514
27515                 # e2fsck should not return error
27516                 [ $rc -eq 0 ] ||
27517                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27518         done
27519 }
27520 run_test 804 "verify agent entry for remote entry"
27521
27522 cleanup_805() {
27523         do_facet $SINGLEMDS zfs set quota=$old $fsset
27524         unlinkmany $DIR/$tdir/f- 1000000
27525         trap 0
27526 }
27527
27528 test_805() {
27529         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
27530         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
27531         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
27532                 skip "netfree not implemented before 0.7"
27533         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
27534                 skip "Need MDS version at least 2.10.57"
27535
27536         local fsset
27537         local freekb
27538         local usedkb
27539         local old
27540         local quota
27541         local pref="osd-zfs.$FSNAME-MDT0000."
27542
27543         # limit available space on MDS dataset to meet nospace issue
27544         # quickly. then ZFS 0.7.2 can use reserved space if asked
27545         # properly (using netfree flag in osd_declare_destroy()
27546         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
27547         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
27548                 gawk '{print $3}')
27549         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
27550         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
27551         let "usedkb=usedkb-freekb"
27552         let "freekb=freekb/2"
27553         if let "freekb > 5000"; then
27554                 let "freekb=5000"
27555         fi
27556         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
27557         trap cleanup_805 EXIT
27558         mkdir_on_mdt0 $DIR/$tdir
27559         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
27560                 error "Can't set PFL layout"
27561         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27562         rm -rf $DIR/$tdir || error "not able to remove"
27563         do_facet $SINGLEMDS zfs set quota=$old $fsset
27564         trap 0
27565 }
27566 run_test 805 "ZFS can remove from full fs"
27567
27568 # Size-on-MDS test
27569 check_lsom_data()
27570 {
27571         local file=$1
27572         local expect=$(stat -c %s $file)
27573
27574         check_lsom_size $1 $expect
27575
27576         local blocks=$($LFS getsom -b $file)
27577         expect=$(stat -c %b $file)
27578         [[ $blocks == $expect ]] ||
27579                 error "$file expected blocks: $expect, got: $blocks"
27580 }
27581
27582 check_lsom_size()
27583 {
27584         local size
27585         local expect=$2
27586
27587         cancel_lru_locks mdc
27588
27589         size=$($LFS getsom -s $1)
27590         [[ $size == $expect ]] ||
27591                 error "$file expected size: $expect, got: $size"
27592 }
27593
27594 test_806() {
27595         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27596                 skip "Need MDS version at least 2.11.52"
27597
27598         local bs=1048576
27599
27600         touch $DIR/$tfile || error "touch $tfile failed"
27601
27602         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27603         save_lustre_params client "llite.*.xattr_cache" > $save
27604         lctl set_param llite.*.xattr_cache=0
27605         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27606
27607         # single-threaded write
27608         echo "Test SOM for single-threaded write"
27609         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27610                 error "write $tfile failed"
27611         check_lsom_size $DIR/$tfile $bs
27612
27613         local num=32
27614         local size=$(($num * $bs))
27615         local offset=0
27616         local i
27617
27618         echo "Test SOM for single client multi-threaded($num) write"
27619         $TRUNCATE $DIR/$tfile 0
27620         for ((i = 0; i < $num; i++)); do
27621                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27622                 local pids[$i]=$!
27623                 offset=$((offset + $bs))
27624         done
27625         for (( i=0; i < $num; i++ )); do
27626                 wait ${pids[$i]}
27627         done
27628         check_lsom_size $DIR/$tfile $size
27629
27630         $TRUNCATE $DIR/$tfile 0
27631         for ((i = 0; i < $num; i++)); do
27632                 offset=$((offset - $bs))
27633                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27634                 local pids[$i]=$!
27635         done
27636         for (( i=0; i < $num; i++ )); do
27637                 wait ${pids[$i]}
27638         done
27639         check_lsom_size $DIR/$tfile $size
27640
27641         # multi-client writes
27642         num=$(get_node_count ${CLIENTS//,/ })
27643         size=$(($num * $bs))
27644         offset=0
27645         i=0
27646
27647         echo "Test SOM for multi-client ($num) writes"
27648         $TRUNCATE $DIR/$tfile 0
27649         for client in ${CLIENTS//,/ }; do
27650                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27651                 local pids[$i]=$!
27652                 i=$((i + 1))
27653                 offset=$((offset + $bs))
27654         done
27655         for (( i=0; i < $num; i++ )); do
27656                 wait ${pids[$i]}
27657         done
27658         check_lsom_size $DIR/$tfile $offset
27659
27660         i=0
27661         $TRUNCATE $DIR/$tfile 0
27662         for client in ${CLIENTS//,/ }; do
27663                 offset=$((offset - $bs))
27664                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27665                 local pids[$i]=$!
27666                 i=$((i + 1))
27667         done
27668         for (( i=0; i < $num; i++ )); do
27669                 wait ${pids[$i]}
27670         done
27671         check_lsom_size $DIR/$tfile $size
27672
27673         # verify truncate
27674         echo "Test SOM for truncate"
27675         $TRUNCATE $DIR/$tfile 1048576
27676         check_lsom_size $DIR/$tfile 1048576
27677         $TRUNCATE $DIR/$tfile 1234
27678         check_lsom_size $DIR/$tfile 1234
27679
27680         # verify SOM blocks count
27681         echo "Verify SOM block count"
27682         $TRUNCATE $DIR/$tfile 0
27683         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27684                 error "failed to write file $tfile"
27685         check_lsom_data $DIR/$tfile
27686 }
27687 run_test 806 "Verify Lazy Size on MDS"
27688
27689 test_807() {
27690         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27691         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27692                 skip "Need MDS version at least 2.11.52"
27693
27694         # Registration step
27695         changelog_register || error "changelog_register failed"
27696         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27697         changelog_users $SINGLEMDS | grep -q $cl_user ||
27698                 error "User $cl_user not found in changelog_users"
27699
27700         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27701         save_lustre_params client "llite.*.xattr_cache" > $save
27702         lctl set_param llite.*.xattr_cache=0
27703         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27704
27705         rm -rf $DIR/$tdir || error "rm $tdir failed"
27706         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27707         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27708         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27709         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27710                 error "truncate $tdir/trunc failed"
27711
27712         local bs=1048576
27713         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27714                 error "write $tfile failed"
27715
27716         # multi-client wirtes
27717         local num=$(get_node_count ${CLIENTS//,/ })
27718         local offset=0
27719         local i=0
27720
27721         echo "Test SOM for multi-client ($num) writes"
27722         touch $DIR/$tfile || error "touch $tfile failed"
27723         $TRUNCATE $DIR/$tfile 0
27724         for client in ${CLIENTS//,/ }; do
27725                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27726                 local pids[$i]=$!
27727                 i=$((i + 1))
27728                 offset=$((offset + $bs))
27729         done
27730         for (( i=0; i < $num; i++ )); do
27731                 wait ${pids[$i]}
27732         done
27733
27734         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27735         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27736         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27737         check_lsom_data $DIR/$tdir/trunc
27738         check_lsom_data $DIR/$tdir/single_dd
27739         check_lsom_data $DIR/$tfile
27740
27741         rm -rf $DIR/$tdir
27742         # Deregistration step
27743         changelog_deregister || error "changelog_deregister failed"
27744 }
27745 run_test 807 "verify LSOM syncing tool"
27746
27747 check_som_nologged()
27748 {
27749         local lines=$($LFS changelog $FSNAME-MDT0000 |
27750                 grep 'x=trusted.som' | wc -l)
27751         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27752 }
27753
27754 test_808() {
27755         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27756                 skip "Need MDS version at least 2.11.55"
27757
27758         # Registration step
27759         changelog_register || error "changelog_register failed"
27760
27761         touch $DIR/$tfile || error "touch $tfile failed"
27762         check_som_nologged
27763
27764         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27765                 error "write $tfile failed"
27766         check_som_nologged
27767
27768         $TRUNCATE $DIR/$tfile 1234
27769         check_som_nologged
27770
27771         $TRUNCATE $DIR/$tfile 1048576
27772         check_som_nologged
27773
27774         # Deregistration step
27775         changelog_deregister || error "changelog_deregister failed"
27776 }
27777 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27778
27779 check_som_nodata()
27780 {
27781         $LFS getsom $1
27782         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27783 }
27784
27785 test_809() {
27786         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27787                 skip "Need MDS version at least 2.11.56"
27788
27789         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27790                 error "failed to create DoM-only file $DIR/$tfile"
27791         touch $DIR/$tfile || error "touch $tfile failed"
27792         check_som_nodata $DIR/$tfile
27793
27794         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27795                 error "write $tfile failed"
27796         check_som_nodata $DIR/$tfile
27797
27798         $TRUNCATE $DIR/$tfile 1234
27799         check_som_nodata $DIR/$tfile
27800
27801         $TRUNCATE $DIR/$tfile 4097
27802         check_som_nodata $DIR/$file
27803 }
27804 run_test 809 "Verify no SOM xattr store for DoM-only files"
27805
27806 test_810() {
27807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27808         $GSS && skip_env "could not run with gss"
27809         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27810                 skip "OST < 2.12.58 doesn't align checksum"
27811
27812         set_checksums 1
27813         stack_trap "set_checksums $ORIG_CSUM" EXIT
27814         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27815
27816         local csum
27817         local before
27818         local after
27819         for csum in $CKSUM_TYPES; do
27820                 #define OBD_FAIL_OSC_NO_GRANT   0x411
27821                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
27822                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
27823                         eval set -- $i
27824                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
27825                         before=$(md5sum $DIR/$tfile)
27826                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
27827                         after=$(md5sum $DIR/$tfile)
27828                         [ "$before" == "$after" ] ||
27829                                 error "$csum: $before != $after bs=$1 seek=$2"
27830                 done
27831         done
27832 }
27833 run_test 810 "partial page writes on ZFS (LU-11663)"
27834
27835 test_812a() {
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
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         stat $DIR/$tfile >/dev/null || error "can't stat file"
27853 }
27854 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
27855
27856 test_812b() { # LU-12378
27857         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27858                 skip "OST < 2.12.51 doesn't support this fail_loc"
27859
27860         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
27861         # ensure ost1 is connected
27862         stat $DIR/$tfile >/dev/null || error "can't stat"
27863         wait_osc_import_state client ost1 FULL
27864         # no locks, no reqs to let the connection idle
27865         cancel_lru_locks osc
27866
27867         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27868 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27869         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27870         wait_osc_import_state client ost1 CONNECTING
27871         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27872
27873         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
27874         wait_osc_import_state client ost1 IDLE
27875 }
27876 run_test 812b "do not drop no resend request for idle connect"
27877
27878 test_812c() {
27879         local old
27880
27881         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
27882
27883         $LFS setstripe -c 1 -o 0 $DIR/$tfile
27884         $LFS getstripe $DIR/$tfile
27885         $LCTL set_param osc.*.idle_timeout=10
27886         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
27887         # ensure ost1 is connected
27888         stat $DIR/$tfile >/dev/null || error "can't stat"
27889         wait_osc_import_state client ost1 FULL
27890         # no locks, no reqs to let the connection idle
27891         cancel_lru_locks osc
27892
27893 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
27894         $LCTL set_param fail_loc=0x80000533
27895         sleep 15
27896         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
27897 }
27898 run_test 812c "idle import vs lock enqueue race"
27899
27900 test_813() {
27901         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
27902         [ -z "$file_heat_sav" ] && skip "no file heat support"
27903
27904         local readsample
27905         local writesample
27906         local readbyte
27907         local writebyte
27908         local readsample1
27909         local writesample1
27910         local readbyte1
27911         local writebyte1
27912
27913         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
27914         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
27915
27916         $LCTL set_param -n llite.*.file_heat=1
27917         echo "Turn on file heat"
27918         echo "Period second: $period_second, Decay percentage: $decay_pct"
27919
27920         echo "QQQQ" > $DIR/$tfile
27921         echo "QQQQ" > $DIR/$tfile
27922         echo "QQQQ" > $DIR/$tfile
27923         cat $DIR/$tfile > /dev/null
27924         cat $DIR/$tfile > /dev/null
27925         cat $DIR/$tfile > /dev/null
27926         cat $DIR/$tfile > /dev/null
27927
27928         local out=$($LFS heat_get $DIR/$tfile)
27929
27930         $LFS heat_get $DIR/$tfile
27931         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27932         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27933         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27934         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27935
27936         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
27937         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
27938         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
27939         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
27940
27941         sleep $((period_second + 3))
27942         echo "Sleep $((period_second + 3)) seconds..."
27943         # The recursion formula to calculate the heat of the file f is as
27944         # follow:
27945         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
27946         # Where Hi is the heat value in the period between time points i*I and
27947         # (i+1)*I; Ci is the access count in the period; the symbol P refers
27948         # to the weight of Ci.
27949         out=$($LFS heat_get $DIR/$tfile)
27950         $LFS heat_get $DIR/$tfile
27951         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27952         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27953         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27954         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27955
27956         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
27957                 error "read sample ($readsample) is wrong"
27958         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
27959                 error "write sample ($writesample) is wrong"
27960         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
27961                 error "read bytes ($readbyte) is wrong"
27962         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
27963                 error "write bytes ($writebyte) is wrong"
27964
27965         echo "QQQQ" > $DIR/$tfile
27966         echo "QQQQ" > $DIR/$tfile
27967         echo "QQQQ" > $DIR/$tfile
27968         cat $DIR/$tfile > /dev/null
27969         cat $DIR/$tfile > /dev/null
27970         cat $DIR/$tfile > /dev/null
27971         cat $DIR/$tfile > /dev/null
27972
27973         sleep $((period_second + 3))
27974         echo "Sleep $((period_second + 3)) seconds..."
27975
27976         out=$($LFS heat_get $DIR/$tfile)
27977         $LFS heat_get $DIR/$tfile
27978         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27979         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27980         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27981         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27982
27983         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
27984                 4 * $decay_pct) / 100") -eq 1 ] ||
27985                 error "read sample ($readsample1) is wrong"
27986         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
27987                 3 * $decay_pct) / 100") -eq 1 ] ||
27988                 error "write sample ($writesample1) is wrong"
27989         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
27990                 20 * $decay_pct) / 100") -eq 1 ] ||
27991                 error "read bytes ($readbyte1) is wrong"
27992         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
27993                 15 * $decay_pct) / 100") -eq 1 ] ||
27994                 error "write bytes ($writebyte1) is wrong"
27995
27996         echo "Turn off file heat for the file $DIR/$tfile"
27997         $LFS heat_set -o $DIR/$tfile
27998
27999         echo "QQQQ" > $DIR/$tfile
28000         echo "QQQQ" > $DIR/$tfile
28001         echo "QQQQ" > $DIR/$tfile
28002         cat $DIR/$tfile > /dev/null
28003         cat $DIR/$tfile > /dev/null
28004         cat $DIR/$tfile > /dev/null
28005         cat $DIR/$tfile > /dev/null
28006
28007         out=$($LFS heat_get $DIR/$tfile)
28008         $LFS heat_get $DIR/$tfile
28009         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28010         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28011         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28012         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28013
28014         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28015         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28016         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28017         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28018
28019         echo "Trun on file heat for the file $DIR/$tfile"
28020         $LFS heat_set -O $DIR/$tfile
28021
28022         echo "QQQQ" > $DIR/$tfile
28023         echo "QQQQ" > $DIR/$tfile
28024         echo "QQQQ" > $DIR/$tfile
28025         cat $DIR/$tfile > /dev/null
28026         cat $DIR/$tfile > /dev/null
28027         cat $DIR/$tfile > /dev/null
28028         cat $DIR/$tfile > /dev/null
28029
28030         out=$($LFS heat_get $DIR/$tfile)
28031         $LFS heat_get $DIR/$tfile
28032         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28033         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28034         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28035         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28036
28037         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
28038         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
28039         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
28040         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
28041
28042         $LFS heat_set -c $DIR/$tfile
28043         $LCTL set_param -n llite.*.file_heat=0
28044         echo "Turn off file heat support for the Lustre filesystem"
28045
28046         echo "QQQQ" > $DIR/$tfile
28047         echo "QQQQ" > $DIR/$tfile
28048         echo "QQQQ" > $DIR/$tfile
28049         cat $DIR/$tfile > /dev/null
28050         cat $DIR/$tfile > /dev/null
28051         cat $DIR/$tfile > /dev/null
28052         cat $DIR/$tfile > /dev/null
28053
28054         out=$($LFS heat_get $DIR/$tfile)
28055         $LFS heat_get $DIR/$tfile
28056         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28057         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28058         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28059         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28060
28061         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28062         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28063         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28064         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28065
28066         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
28067         rm -f $DIR/$tfile
28068 }
28069 run_test 813 "File heat verfication"
28070
28071 test_814()
28072 {
28073         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
28074         echo -n y >> $DIR/$tfile
28075         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
28076         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
28077 }
28078 run_test 814 "sparse cp works as expected (LU-12361)"
28079
28080 test_815()
28081 {
28082         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
28083         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
28084 }
28085 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
28086
28087 test_816() {
28088         local ost1_imp=$(get_osc_import_name client ost1)
28089         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
28090                          cut -d'.' -f2)
28091
28092         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28093         # ensure ost1 is connected
28094
28095         stat $DIR/$tfile >/dev/null || error "can't stat"
28096         wait_osc_import_state client ost1 FULL
28097         # no locks, no reqs to let the connection idle
28098         cancel_lru_locks osc
28099         lru_resize_disable osc
28100         local before
28101         local now
28102         before=$($LCTL get_param -n \
28103                  ldlm.namespaces.$imp_name.lru_size)
28104
28105         wait_osc_import_state client ost1 IDLE
28106         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
28107         now=$($LCTL get_param -n \
28108               ldlm.namespaces.$imp_name.lru_size)
28109         [ $before == $now ] || error "lru_size changed $before != $now"
28110 }
28111 run_test 816 "do not reset lru_resize on idle reconnect"
28112
28113 cleanup_817() {
28114         umount $tmpdir
28115         exportfs -u localhost:$DIR/nfsexp
28116         rm -rf $DIR/nfsexp
28117 }
28118
28119 test_817() {
28120         systemctl restart nfs-server.service || skip "failed to restart nfsd"
28121
28122         mkdir -p $DIR/nfsexp
28123         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
28124                 error "failed to export nfs"
28125
28126         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
28127         stack_trap cleanup_817 EXIT
28128
28129         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
28130                 error "failed to mount nfs to $tmpdir"
28131
28132         cp /bin/true $tmpdir
28133         $DIR/nfsexp/true || error "failed to execute 'true' command"
28134 }
28135 run_test 817 "nfsd won't cache write lock for exec file"
28136
28137 test_818() {
28138         test_mkdir -i0 -c1 $DIR/$tdir
28139         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
28140         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
28141         stop $SINGLEMDS
28142
28143         # restore osp-syn threads
28144         stack_trap "fail $SINGLEMDS"
28145
28146         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
28147         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
28148         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
28149                 error "start $SINGLEMDS failed"
28150         rm -rf $DIR/$tdir
28151
28152         local testid=$(echo $TESTNAME | tr '_' ' ')
28153
28154         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
28155                 grep "run LFSCK" || error "run LFSCK is not suggested"
28156 }
28157 run_test 818 "unlink with failed llog"
28158
28159 test_819a() {
28160         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28161         cancel_lru_locks osc
28162         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28163         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28164         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
28165         rm -f $TDIR/$tfile
28166 }
28167 run_test 819a "too big niobuf in read"
28168
28169 test_819b() {
28170         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28171         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28172         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28173         cancel_lru_locks osc
28174         sleep 1
28175         rm -f $TDIR/$tfile
28176 }
28177 run_test 819b "too big niobuf in write"
28178
28179
28180 function test_820_start_ost() {
28181         sleep 5
28182
28183         for num in $(seq $OSTCOUNT); do
28184                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
28185         done
28186 }
28187
28188 test_820() {
28189         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28190
28191         mkdir $DIR/$tdir
28192         umount_client $MOUNT || error "umount failed"
28193         for num in $(seq $OSTCOUNT); do
28194                 stop ost$num
28195         done
28196
28197         # mount client with no active OSTs
28198         # so that the client can't initialize max LOV EA size
28199         # from OSC notifications
28200         mount_client $MOUNT || error "mount failed"
28201         # delay OST starting to keep this 0 max EA size for a while
28202         test_820_start_ost &
28203
28204         # create a directory on MDS2
28205         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
28206                 error "Failed to create directory"
28207         # open intent should update default EA size
28208         # see mdc_update_max_ea_from_body()
28209         # notice this is the very first RPC to MDS2
28210         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
28211         ret=$?
28212         echo $out
28213         # With SSK, this situation can lead to -EPERM being returned.
28214         # In that case, simply retry.
28215         if [ $ret -ne 0 ] && $SHARED_KEY; then
28216                 if echo "$out" | grep -q "not permitted"; then
28217                         cp /etc/services $DIR/$tdir/mds2
28218                         ret=$?
28219                 fi
28220         fi
28221         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
28222 }
28223 run_test 820 "update max EA from open intent"
28224
28225 test_822() {
28226         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28227
28228         save_lustre_params mds1 \
28229                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28230         do_facet $SINGLEMDS "$LCTL set_param -n \
28231                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
28232         do_facet $SINGLEMDS "$LCTL set_param -n \
28233                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
28234
28235         # wait for statfs update to clear OS_STATFS_NOPRECREATE
28236         local maxage=$(do_facet mds1 $LCTL get_param -n \
28237                        osp.$FSNAME-OST0000*MDT0000.maxage)
28238         sleep $((maxage + 1))
28239
28240         #define OBD_FAIL_NET_ERROR_RPC          0x532
28241         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
28242
28243         stack_trap "restore_lustre_params < $p; rm $p"
28244
28245         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
28246                       osp.$FSNAME-OST0000*MDT0000.create_count")
28247         for i in $(seq 1 $count); do
28248                 touch $DIR/$tfile.${i} || error "touch failed"
28249         done
28250 }
28251 run_test 822 "test precreate failure"
28252
28253 test_823() {
28254         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28255         local OST_MAX_PRECREATE=20000
28256
28257         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
28258                 skip "Need MDS version at least 2.14.56"
28259
28260         save_lustre_params mds1 \
28261                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28262         do_facet $SINGLEMDS "$LCTL set_param -n \
28263                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
28264         do_facet $SINGLEMDS "$LCTL set_param -n \
28265                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
28266
28267         stack_trap "restore_lustre_params < $p; rm $p"
28268
28269         do_facet $SINGLEMDS "$LCTL set_param -n \
28270                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
28271
28272         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28273                       osp.$FSNAME-OST0000*MDT0000.create_count")
28274         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28275                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
28276         local expect_count=$(((($max/2)/256) * 256))
28277
28278         log "setting create_count to 100200:"
28279         log " -result- count: $count with max: $max, expecting: $expect_count"
28280
28281         [[ $count -eq expect_count ]] ||
28282                 error "Create count not set to max precreate."
28283 }
28284 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28285
28286 test_831() {
28287         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
28288                 skip "Need MDS version 2.14.56"
28289
28290         local sync_changes=$(do_facet $SINGLEMDS \
28291                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28292
28293         [ "$sync_changes" -gt 100 ] &&
28294                 skip "Sync changes $sync_changes > 100 already"
28295
28296         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28297
28298         $LFS mkdir -i 0 $DIR/$tdir
28299         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28300
28301         save_lustre_params mds1 \
28302                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28303         save_lustre_params mds1 \
28304                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28305
28306         do_facet mds1 "$LCTL set_param -n \
28307                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28308                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28309         stack_trap "restore_lustre_params < $p" EXIT
28310
28311         createmany -o $DIR/$tdir/f- 1000
28312         unlinkmany $DIR/$tdir/f- 1000 &
28313         local UNLINK_PID=$!
28314
28315         while sleep 1; do
28316                 sync_changes=$(do_facet mds1 \
28317                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28318                 # the check in the code is racy, fail the test
28319                 # if the value above the limit by 10.
28320                 [ $sync_changes -gt 110 ] && {
28321                         kill -2 $UNLINK_PID
28322                         wait
28323                         error "osp changes throttling failed, $sync_changes>110"
28324                 }
28325                 kill -0 $UNLINK_PID 2> /dev/null || break
28326         done
28327         wait
28328 }
28329 run_test 831 "throttling unlink/setattr queuing on OSP"
28330
28331 #
28332 # tests that do cleanup/setup should be run at the end
28333 #
28334
28335 test_900() {
28336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28337         local ls
28338
28339         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28340         $LCTL set_param fail_loc=0x903
28341
28342         cancel_lru_locks MGC
28343
28344         FAIL_ON_ERROR=true cleanup
28345         FAIL_ON_ERROR=true setup
28346 }
28347 run_test 900 "umount should not race with any mgc requeue thread"
28348
28349 # LUS-6253/LU-11185
28350 test_901() {
28351         local old
28352         local count
28353         local oldc
28354         local newc
28355         local olds
28356         local news
28357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28358
28359         # some get_param have a bug to handle dot in param name
28360         cancel_lru_locks MGC
28361         old=$(mount -t lustre | wc -l)
28362         # 1 config+sptlrpc
28363         # 2 params
28364         # 3 nodemap
28365         # 4 IR
28366         old=$((old * 4))
28367         oldc=0
28368         count=0
28369         while [ $old -ne $oldc ]; do
28370                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28371                 sleep 1
28372                 ((count++))
28373                 if [ $count -ge $TIMEOUT ]; then
28374                         error "too large timeout"
28375                 fi
28376         done
28377         umount_client $MOUNT || error "umount failed"
28378         mount_client $MOUNT || error "mount failed"
28379         cancel_lru_locks MGC
28380         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28381
28382         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28383
28384         return 0
28385 }
28386 run_test 901 "don't leak a mgc lock on client umount"
28387
28388 # LU-13377
28389 test_902() {
28390         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28391                 skip "client does not have LU-13377 fix"
28392         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28393         $LCTL set_param fail_loc=0x1415
28394         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28395         cancel_lru_locks osc
28396         rm -f $DIR/$tfile
28397 }
28398 run_test 902 "test short write doesn't hang lustre"
28399
28400 # LU-14711
28401 test_903() {
28402         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28403         echo "blah" > $DIR/${tfile}-2
28404         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28405         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28406         $LCTL set_param fail_loc=0x417 fail_val=20
28407
28408         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28409         sleep 1 # To start the destroy
28410         wait_destroy_complete 150 || error "Destroy taking too long"
28411         cat $DIR/$tfile > /dev/null || error "Evicted"
28412 }
28413 run_test 903 "Test long page discard does not cause evictions"
28414
28415 test_904() {
28416         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28417         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28418                 grep -q project || skip "skip project quota not supported"
28419
28420         local testfile="$DIR/$tdir/$tfile"
28421         local xattr="trusted.projid"
28422         local projid
28423         local mdts=$(comma_list $(mdts_nodes))
28424         local saved=$(do_facet mds1 $LCTL get_param -n \
28425                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
28426
28427         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
28428         stack_trap "do_nodes $mdts $LCTL set_param \
28429                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
28430
28431         mkdir -p $DIR/$tdir
28432         touch $testfile
28433         #hide projid xattr on server
28434         $LFS project -p 1 $testfile ||
28435                 error "set $testfile project id failed"
28436         getfattr -m - $testfile | grep $xattr &&
28437                 error "do not show trusted.projid when disabled on server"
28438         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
28439         #should be hidden when projid is 0
28440         $LFS project -p 0 $testfile ||
28441                 error "set $testfile project id failed"
28442         getfattr -m - $testfile | grep $xattr &&
28443                 error "do not show trusted.projid with project ID 0"
28444
28445         #still can getxattr explicitly
28446         projid=$(getfattr -n $xattr $testfile |
28447                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28448         [ $projid == "0" ] ||
28449                 error "projid expected 0 not $projid"
28450
28451         #set the projid via setxattr
28452         setfattr -n $xattr -v "1000" $testfile ||
28453                 error "setattr failed with $?"
28454         projid=($($LFS project $testfile))
28455         [ ${projid[0]} == "1000" ] ||
28456                 error "projid expected 1000 not $projid"
28457
28458         #check the new projid via getxattr
28459         $LFS project -p 1001 $testfile ||
28460                 error "set $testfile project id failed"
28461         getfattr -m - $testfile | grep $xattr ||
28462                 error "should show trusted.projid when project ID != 0"
28463         projid=$(getfattr -n $xattr $testfile |
28464                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28465         [ $projid == "1001" ] ||
28466                 error "projid expected 1001 not $projid"
28467
28468         #try to set invalid projid
28469         setfattr -n $xattr -v "4294967295" $testfile &&
28470                 error "set invalid projid should fail"
28471
28472         #remove the xattr means setting projid to 0
28473         setfattr -x $xattr $testfile ||
28474                 error "setfattr failed with $?"
28475         projid=($($LFS project $testfile))
28476         [ ${projid[0]} == "0" ] ||
28477                 error "projid expected 0 not $projid"
28478
28479         #should be hidden when parent has inherit flag and same projid
28480         $LFS project -srp 1002 $DIR/$tdir ||
28481                 error "set $tdir project id failed"
28482         getfattr -m - $testfile | grep $xattr &&
28483                 error "do not show trusted.projid with inherit flag"
28484
28485         #still can getxattr explicitly
28486         projid=$(getfattr -n $xattr $testfile |
28487                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28488         [ $projid == "1002" ] ||
28489                 error "projid expected 1002 not $projid"
28490 }
28491 run_test 904 "virtual project ID xattr"
28492
28493 complete $SECONDS
28494 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28495 check_and_cleanup_lustre
28496 if [ "$I_MOUNTED" != "yes" ]; then
28497         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28498 fi
28499 exit_status