Whamcloud - gitweb
LU-15910 tests: skip sanity/413g for SSK
[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                 grep "lfm_magic:.*0x0CD50CD0" ||
2899                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2900         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2901         # - sizeof(lfm_type) - sizeof(lfm_flags)
2902         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2903                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2904         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2905                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2906         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2907                 grep "lfm_flags:.*0x0000DA05" ||
2908                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2909         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2910                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2911                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2912
2913         # file create in dir should fail
2914         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2915         touch $DIR/$tdir/${tdir}2/$tfile &&
2916                 error "$DIR/${tdir}2: file create should fail"
2917
2918         # chmod should work
2919         chmod 777 $DIR/$tdir/$tdir ||
2920                 error "$DIR/$tdir: chmod failed"
2921         chmod 777 $DIR/$tdir/${tdir}2 ||
2922                 error "$DIR/${tdir}2: chmod failed"
2923
2924         # chown should work
2925         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2926                 error "$DIR/$tdir: chown failed"
2927         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2928                 error "$DIR/${tdir}2: chown failed"
2929
2930         # rename should work
2931         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2932                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2933         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2934                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2935
2936         #remove foreign dir
2937         rmdir $DIR/$tdir/${tdir}.new ||
2938                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2939         rmdir $DIR/$tdir/${tdir}2.new ||
2940                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2941 }
2942 run_test 27K "basic ops on dir with foreign LMV"
2943
2944 test_27L() {
2945         remote_mds_nodsh && skip "remote MDS with nodsh"
2946
2947         local POOL=${POOL:-$TESTNAME}
2948
2949         pool_add $POOL || error "pool_add failed"
2950
2951         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2952                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2953                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2954 }
2955 run_test 27L "lfs pool_list gives correct pool name"
2956
2957 test_27M() {
2958         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2959                 skip "Need MDS version >= than 2.12.57"
2960         remote_mds_nodsh && skip "remote MDS with nodsh"
2961         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2962
2963         test_mkdir $DIR/$tdir
2964
2965         # Set default striping on directory
2966         local setcount=4
2967         local stripe_opt
2968
2969         # if we run against a 2.12 server which lacks overstring support
2970         # then the connect_flag will not report overstriping, even if client
2971         # is 2.14+
2972         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
2973                 stripe_opt="-C $setcount"
2974         elif (( $OSTCOUNT >= $setcount )); then
2975                 stripe_opt="-c $setcount"
2976         else
2977                 skip "server does not support overstriping"
2978         fi
2979         $LFS setstripe $stripe_opt $DIR/$tdir
2980
2981         echo 1 > $DIR/$tdir/${tfile}.1
2982         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2983         [ $count -eq $setcount ] ||
2984                 error "(1) stripe count $count, should be $setcount"
2985
2986         # Capture existing append_stripe_count setting for restore
2987         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2988         local mdts=$(comma_list $(mdts_nodes))
2989         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2990
2991         local appendcount=$orig_count
2992         echo 1 >> $DIR/$tdir/${tfile}.2_append
2993         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2994         [ $count -eq $appendcount ] ||
2995                 error "(2)stripe count $count, should be $appendcount for append"
2996
2997         # Disable O_APPEND striping, verify it works
2998         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2999
3000         # Should now get the default striping, which is 4
3001         setcount=4
3002         echo 1 >> $DIR/$tdir/${tfile}.3_append
3003         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3004         [ $count -eq $setcount ] ||
3005                 error "(3) stripe count $count, should be $setcount"
3006
3007         # Try changing the stripe count for append files
3008         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3009
3010         # Append striping is now 2 (directory default is still 4)
3011         appendcount=2
3012         echo 1 >> $DIR/$tdir/${tfile}.4_append
3013         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3014         [ $count -eq $appendcount ] ||
3015                 error "(4) stripe count $count, should be $appendcount for append"
3016
3017         # Test append stripe count of -1
3018         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3019         appendcount=$OSTCOUNT
3020         echo 1 >> $DIR/$tdir/${tfile}.5
3021         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3022         [ $count -eq $appendcount ] ||
3023                 error "(5) stripe count $count, should be $appendcount for append"
3024
3025         # Set append striping back to default of 1
3026         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3027
3028         # Try a new default striping, PFL + DOM
3029         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3030
3031         # Create normal DOM file, DOM returns stripe count == 0
3032         setcount=0
3033         touch $DIR/$tdir/${tfile}.6
3034         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3035         [ $count -eq $setcount ] ||
3036                 error "(6) stripe count $count, should be $setcount"
3037
3038         # Show
3039         appendcount=1
3040         echo 1 >> $DIR/$tdir/${tfile}.7_append
3041         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3042         [ $count -eq $appendcount ] ||
3043                 error "(7) stripe count $count, should be $appendcount for append"
3044
3045         # Clean up DOM layout
3046         $LFS setstripe -d $DIR/$tdir
3047
3048         save_layout_restore_at_exit $MOUNT
3049         # Now test that append striping works when layout is from root
3050         $LFS setstripe -c 2 $MOUNT
3051         # Make a special directory for this
3052         mkdir $DIR/${tdir}/${tdir}.2
3053
3054         # Verify for normal file
3055         setcount=2
3056         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3057         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3058         [ $count -eq $setcount ] ||
3059                 error "(8) stripe count $count, should be $setcount"
3060
3061         appendcount=1
3062         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3063         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3064         [ $count -eq $appendcount ] ||
3065                 error "(9) stripe count $count, should be $appendcount for append"
3066
3067         # Now test O_APPEND striping with pools
3068         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3069         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3070
3071         # Create the pool
3072         pool_add $TESTNAME || error "pool creation failed"
3073         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3074
3075         echo 1 >> $DIR/$tdir/${tfile}.10_append
3076
3077         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3078         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3079
3080         # Check that count is still correct
3081         appendcount=1
3082         echo 1 >> $DIR/$tdir/${tfile}.11_append
3083         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3084         [ $count -eq $appendcount ] ||
3085                 error "(11) stripe count $count, should be $appendcount for append"
3086
3087         # Disable O_APPEND stripe count, verify pool works separately
3088         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3089
3090         echo 1 >> $DIR/$tdir/${tfile}.12_append
3091
3092         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3093         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3094
3095         # Remove pool setting, verify it's not applied
3096         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3097
3098         echo 1 >> $DIR/$tdir/${tfile}.13_append
3099
3100         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3101         [ "$pool" = "" ] || error "(13) pool found: $pool"
3102 }
3103 run_test 27M "test O_APPEND striping"
3104
3105 test_27N() {
3106         combined_mgs_mds && skip "needs separate MGS/MDT"
3107
3108         pool_add $TESTNAME || error "pool_add failed"
3109         do_facet mgs "$LCTL pool_list $FSNAME" |
3110                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3111                 error "lctl pool_list on MGS failed"
3112 }
3113 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3114
3115 clean_foreign_symlink() {
3116         trap 0
3117         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3118         for i in $DIR/$tdir/* ; do
3119                 $LFS unlink_foreign $i || true
3120         done
3121 }
3122
3123 test_27O() {
3124         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3125                 skip "Need MDS version newer than 2.12.51"
3126
3127         test_mkdir $DIR/$tdir
3128         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3129         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3130
3131         trap clean_foreign_symlink EXIT
3132
3133         # enable foreign_symlink behaviour
3134         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3135
3136         # foreign symlink LOV format is a partial path by default
3137
3138         # create foreign file (lfs + API)
3139         $LFS setstripe --foreign=symlink --flags 0xda05 \
3140                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3141                 error "$DIR/$tdir/${tfile}: create failed"
3142
3143         $LFS getstripe -v $DIR/$tdir/${tfile} |
3144                 grep "lfm_magic:.*0x0BD70BD0" ||
3145                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3146         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3147                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3148         $LFS getstripe -v $DIR/$tdir/${tfile} |
3149                 grep "lfm_flags:.*0x0000DA05" ||
3150                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3151         $LFS getstripe $DIR/$tdir/${tfile} |
3152                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3153                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3154
3155         # modify striping should fail
3156         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3157                 error "$DIR/$tdir/$tfile: setstripe should fail"
3158
3159         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3160         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3161         cat /etc/passwd > $DIR/$tdir/$tfile &&
3162                 error "$DIR/$tdir/$tfile: write should fail"
3163
3164         # rename should succeed
3165         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3166                 error "$DIR/$tdir/$tfile: rename has failed"
3167
3168         #remove foreign_symlink file should fail
3169         rm $DIR/$tdir/${tfile}.new &&
3170                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3171
3172         #test fake symlink
3173         mkdir /tmp/${uuid1} ||
3174                 error "/tmp/${uuid1}: mkdir has failed"
3175         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3176                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3177         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3178         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3179                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3180         #read should succeed now
3181         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3182                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3183         #write should succeed now
3184         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3185                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3186         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3187                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3188         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3189                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3190
3191         #check that getstripe still works
3192         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3193                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3194
3195         # chmod should still succeed
3196         chmod 644 $DIR/$tdir/${tfile}.new ||
3197                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3198
3199         # chown should still succeed
3200         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3201                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3202
3203         # rename should still succeed
3204         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3205                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3206
3207         #remove foreign_symlink file should still fail
3208         rm $DIR/$tdir/${tfile} &&
3209                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3210
3211         #use special ioctl() to unlink foreign_symlink file
3212         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3213                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3214
3215 }
3216 run_test 27O "basic ops on foreign file of symlink type"
3217
3218 test_27P() {
3219         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3220                 skip "Need MDS version newer than 2.12.49"
3221
3222         test_mkdir $DIR/$tdir
3223         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3224         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3225
3226         trap clean_foreign_symlink EXIT
3227
3228         # enable foreign_symlink behaviour
3229         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3230
3231         # foreign symlink LMV format is a partial path by default
3232
3233         # create foreign dir (lfs + API)
3234         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3235                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3236                 error "$DIR/$tdir/${tdir}: create failed"
3237
3238         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3239                 grep "lfm_magic:.*0x0CD50CD0" ||
3240                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3241         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3242                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3243         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3244                 grep "lfm_flags:.*0x0000DA05" ||
3245                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3246         $LFS getdirstripe $DIR/$tdir/${tdir} |
3247                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3248                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3249
3250         # file create in dir should fail
3251         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3252         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3253
3254         # rename should succeed
3255         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3256                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3257
3258         #remove foreign_symlink dir should fail
3259         rmdir $DIR/$tdir/${tdir}.new &&
3260                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3261
3262         #test fake symlink
3263         mkdir -p /tmp/${uuid1}/${uuid2} ||
3264                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3265         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3266                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3267         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3268         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3269                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3270         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3271                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3272
3273         #check that getstripe fails now that foreign_symlink enabled
3274         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3275                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3276
3277         # file create in dir should work now
3278         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3279                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3280         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3281                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3282         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3283                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3284
3285         # chmod should still succeed
3286         chmod 755 $DIR/$tdir/${tdir}.new ||
3287                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3288
3289         # chown should still succeed
3290         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3291                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3292
3293         # rename should still succeed
3294         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3295                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3296
3297         #remove foreign_symlink dir should still fail
3298         rmdir $DIR/$tdir/${tdir} &&
3299                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3300
3301         #use special ioctl() to unlink foreign_symlink file
3302         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3303                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3304
3305         #created file should still exist
3306         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3307                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3308         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3309                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3310 }
3311 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3312
3313 test_27Q() {
3314         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3315         stack_trap "rm -f $TMP/$tfile*"
3316
3317         test_mkdir $DIR/$tdir-1
3318         test_mkdir $DIR/$tdir-2
3319
3320         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3321         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3322
3323         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3324         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3325
3326         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3327         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3328
3329         # Create some bad symlinks and ensure that we don't loop
3330         # forever or something. These should return ELOOP (40) and
3331         # ENOENT (2) but I don't want to test for that because there's
3332         # always some weirdo architecture that needs to ruin
3333         # everything by defining these error numbers differently.
3334
3335         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3336         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3337
3338         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3339         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3340
3341         return 0
3342 }
3343 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3344
3345 test_27R() {
3346         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3347                 skip "need MDS 2.14.55 or later"
3348         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3349
3350         local testdir="$DIR/$tdir"
3351         test_mkdir -p $testdir
3352         stack_trap "rm -rf $testdir"
3353         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3354
3355         local f1="$testdir/f1"
3356         touch $f1 || error "failed to touch $f1"
3357         local count=$($LFS getstripe -c $f1)
3358         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3359
3360         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3361         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3362
3363         local maxcount=$(($OSTCOUNT - 1))
3364         local mdts=$(comma_list $(mdts_nodes))
3365         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3366         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3367
3368         local f2="$testdir/f2"
3369         touch $f2 || error "failed to touch $f2"
3370         local count=$($LFS getstripe -c $f2)
3371         (( $count == $maxcount )) || error "wrong stripe count"
3372 }
3373 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3374
3375 test_27S() {
3376         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
3377                 skip "Need MDS version at least 2.14.54"
3378         [[ "$(facet_host mds1)" != "$(facet_host ost1)" ]] ||
3379                 skip "needs different host for mdt1 ost1"
3380
3381         local count=$(precreated_ost_obj_count 0 0)
3382
3383         echo "precreate count $count"
3384         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
3385         $LFS setstripe -i 0 -c 1 $DIR/$tdir || error "setstripe $tdir failed"
3386         #define OBD_FAIL_OSP_GET_LAST_FID       0x2109
3387         do_facet mds1 $LCTL set_param fail_loc=0x2109
3388         #define OBD_FAIL_OST_GET_LAST_FID       0x252
3389         do_facet ost1 $LCTL set_param fail_loc=0x252
3390         createmany -o $DIR/$tdir/f $count &
3391         pid=$!
3392         echo "precreate count $(precreated_ost_obj_count 0 0)"
3393         do_facet mds1 $LCTL set_param fail_loc=0
3394         do_facet ost1 $LCTL set_param fail_loc=0
3395         wait $pid || error "createmany failed"
3396         echo "precreate count $(precreated_ost_obj_count 0 0)"
3397 }
3398 run_test 27S "don't deactivate OSP on network issue"
3399
3400 test_27T() {
3401         [ $(facet_host client) == $(facet_host ost1) ] &&
3402                 skip "need ost1 and client on different nodes"
3403
3404 #define OBD_FAIL_OSC_NO_GRANT            0x411
3405         $LCTL set_param fail_loc=0x20000411 fail_val=1
3406 #define OBD_FAIL_OST_ENOSPC              0x215
3407         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3408         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3409         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3410                 error "multiop failed"
3411 }
3412 run_test 27T "no eio on close on partial write due to enosp"
3413
3414 # createtest also checks that device nodes are created and
3415 # then visible correctly (#2091)
3416 test_28() { # bug 2091
3417         test_mkdir $DIR/d28
3418         $CREATETEST $DIR/d28/ct || error "createtest failed"
3419 }
3420 run_test 28 "create/mknod/mkdir with bad file types ============"
3421
3422 test_29() {
3423         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3424
3425         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3426                 disable_opencache
3427                 stack_trap "restore_opencache"
3428         }
3429
3430         sync; sleep 1; sync # flush out any dirty pages from previous tests
3431         cancel_lru_locks
3432         test_mkdir $DIR/d29
3433         touch $DIR/d29/foo
3434         log 'first d29'
3435         ls -l $DIR/d29
3436
3437         declare -i LOCKCOUNTORIG=0
3438         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3439                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3440         done
3441         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3442
3443         declare -i LOCKUNUSEDCOUNTORIG=0
3444         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3445                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3446         done
3447
3448         log 'second d29'
3449         ls -l $DIR/d29
3450         log 'done'
3451
3452         declare -i LOCKCOUNTCURRENT=0
3453         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3454                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3455         done
3456
3457         declare -i LOCKUNUSEDCOUNTCURRENT=0
3458         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3459                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3460         done
3461
3462         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3463                 $LCTL set_param -n ldlm.dump_namespaces ""
3464                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3465                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3466                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3467                 return 2
3468         fi
3469         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3470                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3471                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3472                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3473                 return 3
3474         fi
3475 }
3476 run_test 29 "IT_GETATTR regression  ============================"
3477
3478 test_30a() { # was test_30
3479         cp $(which ls) $DIR || cp /bin/ls $DIR
3480         $DIR/ls / || error "Can't execute binary from lustre"
3481         rm $DIR/ls
3482 }
3483 run_test 30a "execute binary from Lustre (execve) =============="
3484
3485 test_30b() {
3486         cp `which ls` $DIR || cp /bin/ls $DIR
3487         chmod go+rx $DIR/ls
3488         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3489         rm $DIR/ls
3490 }
3491 run_test 30b "execute binary from Lustre as non-root ==========="
3492
3493 test_30c() { # b=22376
3494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3495
3496         cp $(which ls) $DIR || cp /bin/ls $DIR
3497         chmod a-rw $DIR/ls
3498         cancel_lru_locks mdc
3499         cancel_lru_locks osc
3500         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3501         rm -f $DIR/ls
3502 }
3503 run_test 30c "execute binary from Lustre without read perms ===="
3504
3505 test_30d() {
3506         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3507
3508         for i in {1..10}; do
3509                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3510                 local PID=$!
3511                 sleep 1
3512                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3513                 wait $PID || error "executing dd from Lustre failed"
3514                 rm -f $DIR/$tfile
3515         done
3516
3517         rm -f $DIR/dd
3518 }
3519 run_test 30d "execute binary from Lustre while clear locks"
3520
3521 test_31a() {
3522         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3523         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3524 }
3525 run_test 31a "open-unlink file =================================="
3526
3527 test_31b() {
3528         touch $DIR/f31 || error "touch $DIR/f31 failed"
3529         ln $DIR/f31 $DIR/f31b || error "ln failed"
3530         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3531         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3532 }
3533 run_test 31b "unlink file with multiple links while open ======="
3534
3535 test_31c() {
3536         touch $DIR/f31 || error "touch $DIR/f31 failed"
3537         ln $DIR/f31 $DIR/f31c || error "ln failed"
3538         multiop_bg_pause $DIR/f31 O_uc ||
3539                 error "multiop_bg_pause for $DIR/f31 failed"
3540         MULTIPID=$!
3541         $MULTIOP $DIR/f31c Ouc
3542         kill -USR1 $MULTIPID
3543         wait $MULTIPID
3544 }
3545 run_test 31c "open-unlink file with multiple links ============="
3546
3547 test_31d() {
3548         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3549         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3550 }
3551 run_test 31d "remove of open directory ========================="
3552
3553 test_31e() { # bug 2904
3554         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3555 }
3556 run_test 31e "remove of open non-empty directory ==============="
3557
3558 test_31f() { # bug 4554
3559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3560
3561         set -vx
3562         test_mkdir $DIR/d31f
3563         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3564         cp /etc/hosts $DIR/d31f
3565         ls -l $DIR/d31f
3566         $LFS getstripe $DIR/d31f/hosts
3567         multiop_bg_pause $DIR/d31f D_c || return 1
3568         MULTIPID=$!
3569
3570         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3571         test_mkdir $DIR/d31f
3572         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3573         cp /etc/hosts $DIR/d31f
3574         ls -l $DIR/d31f
3575         $LFS getstripe $DIR/d31f/hosts
3576         multiop_bg_pause $DIR/d31f D_c || return 1
3577         MULTIPID2=$!
3578
3579         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3580         wait $MULTIPID || error "first opendir $MULTIPID failed"
3581
3582         sleep 6
3583
3584         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3585         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3586         set +vx
3587 }
3588 run_test 31f "remove of open directory with open-unlink file ==="
3589
3590 test_31g() {
3591         echo "-- cross directory link --"
3592         test_mkdir -c1 $DIR/${tdir}ga
3593         test_mkdir -c1 $DIR/${tdir}gb
3594         touch $DIR/${tdir}ga/f
3595         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3596         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3597         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3598         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3599         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3600 }
3601 run_test 31g "cross directory link==============="
3602
3603 test_31h() {
3604         echo "-- cross directory link --"
3605         test_mkdir -c1 $DIR/${tdir}
3606         test_mkdir -c1 $DIR/${tdir}/dir
3607         touch $DIR/${tdir}/f
3608         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3609         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3610         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3611         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3612         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3613 }
3614 run_test 31h "cross directory link under child==============="
3615
3616 test_31i() {
3617         echo "-- cross directory link --"
3618         test_mkdir -c1 $DIR/$tdir
3619         test_mkdir -c1 $DIR/$tdir/dir
3620         touch $DIR/$tdir/dir/f
3621         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3622         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3623         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3624         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3625         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3626 }
3627 run_test 31i "cross directory link under parent==============="
3628
3629 test_31j() {
3630         test_mkdir -c1 -p $DIR/$tdir
3631         test_mkdir -c1 -p $DIR/$tdir/dir1
3632         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3633         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3634         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3635         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3636         return 0
3637 }
3638 run_test 31j "link for directory==============="
3639
3640 test_31k() {
3641         test_mkdir -c1 -p $DIR/$tdir
3642         touch $DIR/$tdir/s
3643         touch $DIR/$tdir/exist
3644         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3645         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3646         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3647         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3648         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3649         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3650         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3651         return 0
3652 }
3653 run_test 31k "link to file: the same, non-existing, dir==============="
3654
3655 test_31m() {
3656         mkdir $DIR/d31m
3657         touch $DIR/d31m/s
3658         mkdir $DIR/d31m2
3659         touch $DIR/d31m2/exist
3660         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3661         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3662         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3663         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3664         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3665         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3666         return 0
3667 }
3668 run_test 31m "link to file: the same, non-existing, dir==============="
3669
3670 test_31n() {
3671         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3672         nlink=$(stat --format=%h $DIR/$tfile)
3673         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3674         local fd=$(free_fd)
3675         local cmd="exec $fd<$DIR/$tfile"
3676         eval $cmd
3677         cmd="exec $fd<&-"
3678         trap "eval $cmd" EXIT
3679         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3680         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3681         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3682         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3683         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3684         eval $cmd
3685 }
3686 run_test 31n "check link count of unlinked file"
3687
3688 link_one() {
3689         local tempfile=$(mktemp $1_XXXXXX)
3690         mlink $tempfile $1 2> /dev/null &&
3691                 echo "$BASHPID: link $tempfile to $1 succeeded"
3692         munlink $tempfile
3693 }
3694
3695 test_31o() { # LU-2901
3696         test_mkdir $DIR/$tdir
3697         for LOOP in $(seq 100); do
3698                 rm -f $DIR/$tdir/$tfile*
3699                 for THREAD in $(seq 8); do
3700                         link_one $DIR/$tdir/$tfile.$LOOP &
3701                 done
3702                 wait
3703                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3704                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3705                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3706                         break || true
3707         done
3708 }
3709 run_test 31o "duplicate hard links with same filename"
3710
3711 test_31p() {
3712         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3713
3714         test_mkdir $DIR/$tdir
3715         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3716         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3717
3718         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3719                 error "open unlink test1 failed"
3720         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3721                 error "open unlink test2 failed"
3722
3723         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3724                 error "test1 still exists"
3725         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3726                 error "test2 still exists"
3727 }
3728 run_test 31p "remove of open striped directory"
3729
3730 test_31q() {
3731         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3732
3733         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3734         index=$($LFS getdirstripe -i $DIR/$tdir)
3735         [ $index -eq 3 ] || error "first stripe index $index != 3"
3736         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3737         [ $index -eq 1 ] || error "second stripe index $index != 1"
3738
3739         # when "-c <stripe_count>" is set, the number of MDTs specified after
3740         # "-i" should equal to the stripe count
3741         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3742 }
3743 run_test 31q "create striped directory on specific MDTs"
3744
3745 #LU-14949
3746 test_31r() {
3747         touch $DIR/$tfile.target
3748         touch $DIR/$tfile.source
3749
3750         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3751         $LCTL set_param fail_loc=0x1419 fail_val=3
3752         cat $DIR/$tfile.target &
3753         CATPID=$!
3754
3755         # Guarantee open is waiting before we get here
3756         sleep 1
3757         mv $DIR/$tfile.source $DIR/$tfile.target
3758
3759         wait $CATPID
3760         RC=$?
3761         if [[ $RC -ne 0 ]]; then
3762                 error "open with cat failed, rc=$RC"
3763         fi
3764 }
3765 run_test 31r "open-rename(replace) race"
3766
3767 cleanup_test32_mount() {
3768         local rc=0
3769         trap 0
3770         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3771         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3772         losetup -d $loopdev || true
3773         rm -rf $DIR/$tdir
3774         return $rc
3775 }
3776
3777 test_32a() {
3778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3779
3780         echo "== more mountpoints and symlinks ================="
3781         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3782         trap cleanup_test32_mount EXIT
3783         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3784         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3785                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3786         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3787                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3788         cleanup_test32_mount
3789 }
3790 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3791
3792 test_32b() {
3793         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3794
3795         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3796         trap cleanup_test32_mount EXIT
3797         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3798         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3799                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3800         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3801                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3802         cleanup_test32_mount
3803 }
3804 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3805
3806 test_32c() {
3807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3808
3809         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3810         trap cleanup_test32_mount EXIT
3811         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3812         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3813                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3814         test_mkdir -p $DIR/$tdir/d2/test_dir
3815         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3816                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3817         cleanup_test32_mount
3818 }
3819 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3820
3821 test_32d() {
3822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3823
3824         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3825         trap cleanup_test32_mount EXIT
3826         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3827         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3828                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3829         test_mkdir -p $DIR/$tdir/d2/test_dir
3830         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3831                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3832         cleanup_test32_mount
3833 }
3834 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3835
3836 test_32e() {
3837         rm -fr $DIR/$tdir
3838         test_mkdir -p $DIR/$tdir/tmp
3839         local tmp_dir=$DIR/$tdir/tmp
3840         ln -s $DIR/$tdir $tmp_dir/symlink11
3841         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3842         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3843         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3844 }
3845 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3846
3847 test_32f() {
3848         rm -fr $DIR/$tdir
3849         test_mkdir -p $DIR/$tdir/tmp
3850         local tmp_dir=$DIR/$tdir/tmp
3851         ln -s $DIR/$tdir $tmp_dir/symlink11
3852         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3853         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3854         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3855 }
3856 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3857
3858 test_32g() {
3859         local tmp_dir=$DIR/$tdir/tmp
3860         test_mkdir -p $tmp_dir
3861         test_mkdir $DIR/${tdir}2
3862         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3863         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3864         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3865         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3866         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3867         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3868 }
3869 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3870
3871 test_32h() {
3872         rm -fr $DIR/$tdir $DIR/${tdir}2
3873         tmp_dir=$DIR/$tdir/tmp
3874         test_mkdir -p $tmp_dir
3875         test_mkdir $DIR/${tdir}2
3876         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3877         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3878         ls $tmp_dir/symlink12 || error "listing symlink12"
3879         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3880 }
3881 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3882
3883 test_32i() {
3884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3885
3886         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3887         trap cleanup_test32_mount EXIT
3888         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3889         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3890                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3891         touch $DIR/$tdir/test_file
3892         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3893                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3894         cleanup_test32_mount
3895 }
3896 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3897
3898 test_32j() {
3899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3900
3901         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3902         trap cleanup_test32_mount EXIT
3903         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3904         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3905                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3906         touch $DIR/$tdir/test_file
3907         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3908                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3909         cleanup_test32_mount
3910 }
3911 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3912
3913 test_32k() {
3914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3915
3916         rm -fr $DIR/$tdir
3917         trap cleanup_test32_mount EXIT
3918         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3919         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3920                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3921         test_mkdir -p $DIR/$tdir/d2
3922         touch $DIR/$tdir/d2/test_file || error "touch failed"
3923         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3924                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3925         cleanup_test32_mount
3926 }
3927 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3928
3929 test_32l() {
3930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3931
3932         rm -fr $DIR/$tdir
3933         trap cleanup_test32_mount EXIT
3934         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3935         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3936                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3937         test_mkdir -p $DIR/$tdir/d2
3938         touch $DIR/$tdir/d2/test_file || error "touch failed"
3939         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3940                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3941         cleanup_test32_mount
3942 }
3943 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3944
3945 test_32m() {
3946         rm -fr $DIR/d32m
3947         test_mkdir -p $DIR/d32m/tmp
3948         TMP_DIR=$DIR/d32m/tmp
3949         ln -s $DIR $TMP_DIR/symlink11
3950         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3951         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3952                 error "symlink11 not a link"
3953         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3954                 error "symlink01 not a link"
3955 }
3956 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3957
3958 test_32n() {
3959         rm -fr $DIR/d32n
3960         test_mkdir -p $DIR/d32n/tmp
3961         TMP_DIR=$DIR/d32n/tmp
3962         ln -s $DIR $TMP_DIR/symlink11
3963         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3964         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3965         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3966 }
3967 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3968
3969 test_32o() {
3970         touch $DIR/$tfile
3971         test_mkdir -p $DIR/d32o/tmp
3972         TMP_DIR=$DIR/d32o/tmp
3973         ln -s $DIR/$tfile $TMP_DIR/symlink12
3974         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3975         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3976                 error "symlink12 not a link"
3977         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3978         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3979                 error "$DIR/d32o/tmp/symlink12 not file type"
3980         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3981                 error "$DIR/d32o/symlink02 not file type"
3982 }
3983 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3984
3985 test_32p() {
3986         log 32p_1
3987         rm -fr $DIR/d32p
3988         log 32p_2
3989         rm -f $DIR/$tfile
3990         log 32p_3
3991         touch $DIR/$tfile
3992         log 32p_4
3993         test_mkdir -p $DIR/d32p/tmp
3994         log 32p_5
3995         TMP_DIR=$DIR/d32p/tmp
3996         log 32p_6
3997         ln -s $DIR/$tfile $TMP_DIR/symlink12
3998         log 32p_7
3999         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4000         log 32p_8
4001         cat $DIR/d32p/tmp/symlink12 ||
4002                 error "Can't open $DIR/d32p/tmp/symlink12"
4003         log 32p_9
4004         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4005         log 32p_10
4006 }
4007 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4008
4009 test_32q() {
4010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4011
4012         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4013         trap cleanup_test32_mount EXIT
4014         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4015         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4016         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4017                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4018         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4019         cleanup_test32_mount
4020 }
4021 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4022
4023 test_32r() {
4024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4025
4026         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4027         trap cleanup_test32_mount EXIT
4028         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4029         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4030         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4031                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4032         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4033         cleanup_test32_mount
4034 }
4035 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4036
4037 test_33aa() {
4038         rm -f $DIR/$tfile
4039         touch $DIR/$tfile
4040         chmod 444 $DIR/$tfile
4041         chown $RUNAS_ID $DIR/$tfile
4042         log 33_1
4043         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4044         log 33_2
4045 }
4046 run_test 33aa "write file with mode 444 (should return error)"
4047
4048 test_33a() {
4049         rm -fr $DIR/$tdir
4050         test_mkdir $DIR/$tdir
4051         chown $RUNAS_ID $DIR/$tdir
4052         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4053                 error "$RUNAS create $tdir/$tfile failed"
4054         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4055                 error "open RDWR" || true
4056 }
4057 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4058
4059 test_33b() {
4060         rm -fr $DIR/$tdir
4061         test_mkdir $DIR/$tdir
4062         chown $RUNAS_ID $DIR/$tdir
4063         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4064 }
4065 run_test 33b "test open file with malformed flags (No panic)"
4066
4067 test_33c() {
4068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4069         remote_ost_nodsh && skip "remote OST with nodsh"
4070
4071         local ostnum
4072         local ostname
4073         local write_bytes
4074         local all_zeros
4075
4076         all_zeros=true
4077         test_mkdir $DIR/$tdir
4078         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4079
4080         sync
4081         for ostnum in $(seq $OSTCOUNT); do
4082                 # test-framework's OST numbering is one-based, while Lustre's
4083                 # is zero-based
4084                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4085                 # check if at least some write_bytes stats are counted
4086                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4087                               obdfilter.$ostname.stats |
4088                               awk '/^write_bytes/ {print $7}' )
4089                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4090                 if (( ${write_bytes:-0} > 0 )); then
4091                         all_zeros=false
4092                         break
4093                 fi
4094         done
4095
4096         $all_zeros || return 0
4097
4098         # Write four bytes
4099         echo foo > $DIR/$tdir/bar
4100         # Really write them
4101         sync
4102
4103         # Total up write_bytes after writing.  We'd better find non-zeros.
4104         for ostnum in $(seq $OSTCOUNT); do
4105                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4106                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4107                               obdfilter/$ostname/stats |
4108                               awk '/^write_bytes/ {print $7}' )
4109                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4110                 if (( ${write_bytes:-0} > 0 )); then
4111                         all_zeros=false
4112                         break
4113                 fi
4114         done
4115
4116         if $all_zeros; then
4117                 for ostnum in $(seq $OSTCOUNT); do
4118                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4119                         echo "Check write_bytes is in obdfilter.*.stats:"
4120                         do_facet ost$ostnum lctl get_param -n \
4121                                 obdfilter.$ostname.stats
4122                 done
4123                 error "OST not keeping write_bytes stats (b=22312)"
4124         fi
4125 }
4126 run_test 33c "test write_bytes stats"
4127
4128 test_33d() {
4129         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4131
4132         local MDTIDX=1
4133         local remote_dir=$DIR/$tdir/remote_dir
4134
4135         test_mkdir $DIR/$tdir
4136         $LFS mkdir -i $MDTIDX $remote_dir ||
4137                 error "create remote directory failed"
4138
4139         touch $remote_dir/$tfile
4140         chmod 444 $remote_dir/$tfile
4141         chown $RUNAS_ID $remote_dir/$tfile
4142
4143         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4144
4145         chown $RUNAS_ID $remote_dir
4146         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4147                                         error "create" || true
4148         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4149                                     error "open RDWR" || true
4150         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4151 }
4152 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4153
4154 test_33e() {
4155         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4156
4157         mkdir $DIR/$tdir
4158
4159         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4160         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4161         mkdir $DIR/$tdir/local_dir
4162
4163         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4164         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4165         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4166
4167         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4168                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4169
4170         rmdir $DIR/$tdir/* || error "rmdir failed"
4171
4172         umask 777
4173         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4174         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4175         mkdir $DIR/$tdir/local_dir
4176
4177         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4178         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4179         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4180
4181         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4182                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4183
4184         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4185
4186         umask 000
4187         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4188         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4189         mkdir $DIR/$tdir/local_dir
4190
4191         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4192         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4193         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4194
4195         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4196                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4197 }
4198 run_test 33e "mkdir and striped directory should have same mode"
4199
4200 cleanup_33f() {
4201         trap 0
4202         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4203 }
4204
4205 test_33f() {
4206         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4207         remote_mds_nodsh && skip "remote MDS with nodsh"
4208
4209         mkdir $DIR/$tdir
4210         chmod go+rwx $DIR/$tdir
4211         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4212         trap cleanup_33f EXIT
4213
4214         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4215                 error "cannot create striped directory"
4216
4217         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4218                 error "cannot create files in striped directory"
4219
4220         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4221                 error "cannot remove files in striped directory"
4222
4223         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4224                 error "cannot remove striped directory"
4225
4226         cleanup_33f
4227 }
4228 run_test 33f "nonroot user can create, access, and remove a striped directory"
4229
4230 test_33g() {
4231         mkdir -p $DIR/$tdir/dir2
4232
4233         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4234         echo $err
4235         [[ $err =~ "exists" ]] || error "Not exists error"
4236 }
4237 run_test 33g "nonroot user create already existing root created file"
4238
4239 test_33h() {
4240         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4241         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4242                 skip "Need MDS version at least 2.13.50"
4243
4244         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4245                 error "mkdir $tdir failed"
4246         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4247
4248         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4249         local index2
4250
4251         for fname in $DIR/$tdir/$tfile.bak \
4252                      $DIR/$tdir/$tfile.SAV \
4253                      $DIR/$tdir/$tfile.orig \
4254                      $DIR/$tdir/$tfile~; do
4255                 touch $fname  || error "touch $fname failed"
4256                 index2=$($LFS getstripe -m $fname)
4257                 [ $index -eq $index2 ] ||
4258                         error "$fname MDT index mismatch $index != $index2"
4259         done
4260
4261         local failed=0
4262         for i in {1..250}; do
4263                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4264                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4265                         touch $fname  || error "touch $fname failed"
4266                         index2=$($LFS getstripe -m $fname)
4267                         if [[ $index != $index2 ]]; then
4268                                 failed=$((failed + 1))
4269                                 echo "$fname MDT index mismatch $index != $index2"
4270                         fi
4271                 done
4272         done
4273         echo "$failed MDT index mismatches"
4274         (( failed < 20 )) || error "MDT index mismatch $failed times"
4275
4276 }
4277 run_test 33h "temp file is located on the same MDT as target"
4278
4279 test_33i()
4280 {
4281         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4282
4283         local FNAME=$(str_repeat 'f' 250)
4284
4285         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4286         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4287
4288         local count
4289         local total
4290
4291         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4292
4293         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4294
4295         lctl --device %$MDC deactivate
4296         stack_trap "lctl --device %$MDC activate"
4297         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4298         total=$(\ls -l $DIR/$tdir | wc -l)
4299         # "ls -l" will list total in the first line
4300         total=$((total - 1))
4301         (( total + count == 1000 )) ||
4302                 error "ls list $total files, $count files on MDT1"
4303 }
4304 run_test 33i "striped directory can be accessed when one MDT is down"
4305
4306 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4307 test_34a() {
4308         rm -f $DIR/f34
4309         $MCREATE $DIR/f34 || error "mcreate failed"
4310         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4311                 error "getstripe failed"
4312         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4313         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4314                 error "getstripe failed"
4315         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4316                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4317 }
4318 run_test 34a "truncate file that has not been opened ==========="
4319
4320 test_34b() {
4321         [ ! -f $DIR/f34 ] && test_34a
4322         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4323                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4324         $OPENFILE -f O_RDONLY $DIR/f34
4325         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4326                 error "getstripe failed"
4327         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4328                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4329 }
4330 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4331
4332 test_34c() {
4333         [ ! -f $DIR/f34 ] && test_34a
4334         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4335                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4336         $OPENFILE -f O_RDWR $DIR/f34
4337         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4338                 error "$LFS getstripe failed"
4339         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4340                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4341 }
4342 run_test 34c "O_RDWR opening file-with-size works =============="
4343
4344 test_34d() {
4345         [ ! -f $DIR/f34 ] && test_34a
4346         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4347                 error "dd failed"
4348         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4349                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4350         rm $DIR/f34
4351 }
4352 run_test 34d "write to sparse file ============================="
4353
4354 test_34e() {
4355         rm -f $DIR/f34e
4356         $MCREATE $DIR/f34e || error "mcreate failed"
4357         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4358         $CHECKSTAT -s 1000 $DIR/f34e ||
4359                 error "Size of $DIR/f34e not equal to 1000 bytes"
4360         $OPENFILE -f O_RDWR $DIR/f34e
4361         $CHECKSTAT -s 1000 $DIR/f34e ||
4362                 error "Size of $DIR/f34e not equal to 1000 bytes"
4363 }
4364 run_test 34e "create objects, some with size and some without =="
4365
4366 test_34f() { # bug 6242, 6243
4367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4368
4369         SIZE34F=48000
4370         rm -f $DIR/f34f
4371         $MCREATE $DIR/f34f || error "mcreate failed"
4372         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4373         dd if=$DIR/f34f of=$TMP/f34f
4374         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4375         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4376         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4377         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4378         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4379 }
4380 run_test 34f "read from a file with no objects until EOF ======="
4381
4382 test_34g() {
4383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4384
4385         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4386                 error "dd failed"
4387         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4388         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4389                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4390         cancel_lru_locks osc
4391         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4392                 error "wrong size after lock cancel"
4393
4394         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4395         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4396                 error "expanding truncate failed"
4397         cancel_lru_locks osc
4398         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4399                 error "wrong expanded size after lock cancel"
4400 }
4401 run_test 34g "truncate long file ==============================="
4402
4403 test_34h() {
4404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4405
4406         local gid=10
4407         local sz=1000
4408
4409         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4410         sync # Flush the cache so that multiop below does not block on cache
4411              # flush when getting the group lock
4412         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4413         MULTIPID=$!
4414
4415         # Since just timed wait is not good enough, let's do a sync write
4416         # that way we are sure enough time for a roundtrip + processing
4417         # passed + 2 seconds of extra margin.
4418         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4419         rm $DIR/${tfile}-1
4420         sleep 2
4421
4422         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4423                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4424                 kill -9 $MULTIPID
4425         fi
4426         wait $MULTIPID
4427         local nsz=`stat -c %s $DIR/$tfile`
4428         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4429 }
4430 run_test 34h "ftruncate file under grouplock should not block"
4431
4432 test_35a() {
4433         cp /bin/sh $DIR/f35a
4434         chmod 444 $DIR/f35a
4435         chown $RUNAS_ID $DIR/f35a
4436         $RUNAS $DIR/f35a && error || true
4437         rm $DIR/f35a
4438 }
4439 run_test 35a "exec file with mode 444 (should return and not leak)"
4440
4441 test_36a() {
4442         rm -f $DIR/f36
4443         utime $DIR/f36 || error "utime failed for MDS"
4444 }
4445 run_test 36a "MDS utime check (mknod, utime)"
4446
4447 test_36b() {
4448         echo "" > $DIR/f36
4449         utime $DIR/f36 || error "utime failed for OST"
4450 }
4451 run_test 36b "OST utime check (open, utime)"
4452
4453 test_36c() {
4454         rm -f $DIR/d36/f36
4455         test_mkdir $DIR/d36
4456         chown $RUNAS_ID $DIR/d36
4457         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4458 }
4459 run_test 36c "non-root MDS utime check (mknod, utime)"
4460
4461 test_36d() {
4462         [ ! -d $DIR/d36 ] && test_36c
4463         echo "" > $DIR/d36/f36
4464         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4465 }
4466 run_test 36d "non-root OST utime check (open, utime)"
4467
4468 test_36e() {
4469         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4470
4471         test_mkdir $DIR/$tdir
4472         touch $DIR/$tdir/$tfile
4473         $RUNAS utime $DIR/$tdir/$tfile &&
4474                 error "utime worked, expected failure" || true
4475 }
4476 run_test 36e "utime on non-owned file (should return error)"
4477
4478 subr_36fh() {
4479         local fl="$1"
4480         local LANG_SAVE=$LANG
4481         local LC_LANG_SAVE=$LC_LANG
4482         export LANG=C LC_LANG=C # for date language
4483
4484         DATESTR="Dec 20  2000"
4485         test_mkdir $DIR/$tdir
4486         lctl set_param fail_loc=$fl
4487         date; date +%s
4488         cp /etc/hosts $DIR/$tdir/$tfile
4489         sync & # write RPC generated with "current" inode timestamp, but delayed
4490         sleep 1
4491         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4492         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4493         cancel_lru_locks $OSC
4494         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4495         date; date +%s
4496         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4497                 echo "BEFORE: $LS_BEFORE" && \
4498                 echo "AFTER : $LS_AFTER" && \
4499                 echo "WANT  : $DATESTR" && \
4500                 error "$DIR/$tdir/$tfile timestamps changed" || true
4501
4502         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4503 }
4504
4505 test_36f() {
4506         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4507
4508         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4509         subr_36fh "0x80000214"
4510 }
4511 run_test 36f "utime on file racing with OST BRW write =========="
4512
4513 test_36g() {
4514         remote_ost_nodsh && skip "remote OST with nodsh"
4515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4516         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4517                 skip "Need MDS version at least 2.12.51"
4518
4519         local fmd_max_age
4520         local fmd
4521         local facet="ost1"
4522         local tgt="obdfilter"
4523
4524         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4525
4526         test_mkdir $DIR/$tdir
4527         fmd_max_age=$(do_facet $facet \
4528                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4529                 head -n 1")
4530
4531         echo "FMD max age: ${fmd_max_age}s"
4532         touch $DIR/$tdir/$tfile
4533         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4534                 gawk '{cnt=cnt+$1}  END{print cnt}')
4535         echo "FMD before: $fmd"
4536         [[ $fmd == 0 ]] &&
4537                 error "FMD wasn't create by touch"
4538         sleep $((fmd_max_age + 12))
4539         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4540                 gawk '{cnt=cnt+$1}  END{print cnt}')
4541         echo "FMD after: $fmd"
4542         [[ $fmd == 0 ]] ||
4543                 error "FMD wasn't expired by ping"
4544 }
4545 run_test 36g "FMD cache expiry ====================="
4546
4547 test_36h() {
4548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4549
4550         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4551         subr_36fh "0x80000227"
4552 }
4553 run_test 36h "utime on file racing with OST BRW write =========="
4554
4555 test_36i() {
4556         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4557
4558         test_mkdir $DIR/$tdir
4559         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4560
4561         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4562         local new_mtime=$((mtime + 200))
4563
4564         #change Modify time of striped dir
4565         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4566                         error "change mtime failed"
4567
4568         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4569
4570         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4571 }
4572 run_test 36i "change mtime on striped directory"
4573
4574 # test_37 - duplicate with tests 32q 32r
4575
4576 test_38() {
4577         local file=$DIR/$tfile
4578         touch $file
4579         openfile -f O_DIRECTORY $file
4580         local RC=$?
4581         local ENOTDIR=20
4582         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4583         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4584 }
4585 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4586
4587 test_39a() { # was test_39
4588         touch $DIR/$tfile
4589         touch $DIR/${tfile}2
4590 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4591 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4592 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4593         sleep 2
4594         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4595         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4596                 echo "mtime"
4597                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4598                 echo "atime"
4599                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4600                 echo "ctime"
4601                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4602                 error "O_TRUNC didn't change timestamps"
4603         fi
4604 }
4605 run_test 39a "mtime changed on create"
4606
4607 test_39b() {
4608         test_mkdir -c1 $DIR/$tdir
4609         cp -p /etc/passwd $DIR/$tdir/fopen
4610         cp -p /etc/passwd $DIR/$tdir/flink
4611         cp -p /etc/passwd $DIR/$tdir/funlink
4612         cp -p /etc/passwd $DIR/$tdir/frename
4613         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4614
4615         sleep 1
4616         echo "aaaaaa" >> $DIR/$tdir/fopen
4617         echo "aaaaaa" >> $DIR/$tdir/flink
4618         echo "aaaaaa" >> $DIR/$tdir/funlink
4619         echo "aaaaaa" >> $DIR/$tdir/frename
4620
4621         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4622         local link_new=`stat -c %Y $DIR/$tdir/flink`
4623         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4624         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4625
4626         cat $DIR/$tdir/fopen > /dev/null
4627         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4628         rm -f $DIR/$tdir/funlink2
4629         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4630
4631         for (( i=0; i < 2; i++ )) ; do
4632                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4633                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4634                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4635                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4636
4637                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4638                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4639                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4640                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4641
4642                 cancel_lru_locks $OSC
4643                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4644         done
4645 }
4646 run_test 39b "mtime change on open, link, unlink, rename  ======"
4647
4648 # this should be set to past
4649 TEST_39_MTIME=`date -d "1 year ago" +%s`
4650
4651 # bug 11063
4652 test_39c() {
4653         touch $DIR1/$tfile
4654         sleep 2
4655         local mtime0=`stat -c %Y $DIR1/$tfile`
4656
4657         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4658         local mtime1=`stat -c %Y $DIR1/$tfile`
4659         [ "$mtime1" = $TEST_39_MTIME ] || \
4660                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4661
4662         local d1=`date +%s`
4663         echo hello >> $DIR1/$tfile
4664         local d2=`date +%s`
4665         local mtime2=`stat -c %Y $DIR1/$tfile`
4666         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4667                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4668
4669         mv $DIR1/$tfile $DIR1/$tfile-1
4670
4671         for (( i=0; i < 2; i++ )) ; do
4672                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4673                 [ "$mtime2" = "$mtime3" ] || \
4674                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4675
4676                 cancel_lru_locks $OSC
4677                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4678         done
4679 }
4680 run_test 39c "mtime change on rename ==========================="
4681
4682 # bug 21114
4683 test_39d() {
4684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4685
4686         touch $DIR1/$tfile
4687         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4688
4689         for (( i=0; i < 2; i++ )) ; do
4690                 local mtime=`stat -c %Y $DIR1/$tfile`
4691                 [ $mtime = $TEST_39_MTIME ] || \
4692                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4693
4694                 cancel_lru_locks $OSC
4695                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4696         done
4697 }
4698 run_test 39d "create, utime, stat =============================="
4699
4700 # bug 21114
4701 test_39e() {
4702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4703
4704         touch $DIR1/$tfile
4705         local mtime1=`stat -c %Y $DIR1/$tfile`
4706
4707         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4708
4709         for (( i=0; i < 2; i++ )) ; do
4710                 local mtime2=`stat -c %Y $DIR1/$tfile`
4711                 [ $mtime2 = $TEST_39_MTIME ] || \
4712                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4713
4714                 cancel_lru_locks $OSC
4715                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4716         done
4717 }
4718 run_test 39e "create, stat, utime, stat ========================"
4719
4720 # bug 21114
4721 test_39f() {
4722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4723
4724         touch $DIR1/$tfile
4725         mtime1=`stat -c %Y $DIR1/$tfile`
4726
4727         sleep 2
4728         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4729
4730         for (( i=0; i < 2; i++ )) ; do
4731                 local mtime2=`stat -c %Y $DIR1/$tfile`
4732                 [ $mtime2 = $TEST_39_MTIME ] || \
4733                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4734
4735                 cancel_lru_locks $OSC
4736                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4737         done
4738 }
4739 run_test 39f "create, stat, sleep, utime, stat ================="
4740
4741 # bug 11063
4742 test_39g() {
4743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4744
4745         echo hello >> $DIR1/$tfile
4746         local mtime1=`stat -c %Y $DIR1/$tfile`
4747
4748         sleep 2
4749         chmod o+r $DIR1/$tfile
4750
4751         for (( i=0; i < 2; i++ )) ; do
4752                 local mtime2=`stat -c %Y $DIR1/$tfile`
4753                 [ "$mtime1" = "$mtime2" ] || \
4754                         error "lost mtime: $mtime2, should be $mtime1"
4755
4756                 cancel_lru_locks $OSC
4757                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4758         done
4759 }
4760 run_test 39g "write, chmod, stat ==============================="
4761
4762 # bug 11063
4763 test_39h() {
4764         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4765
4766         touch $DIR1/$tfile
4767         sleep 1
4768
4769         local d1=`date`
4770         echo hello >> $DIR1/$tfile
4771         local mtime1=`stat -c %Y $DIR1/$tfile`
4772
4773         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4774         local d2=`date`
4775         if [ "$d1" != "$d2" ]; then
4776                 echo "write and touch not within one second"
4777         else
4778                 for (( i=0; i < 2; i++ )) ; do
4779                         local mtime2=`stat -c %Y $DIR1/$tfile`
4780                         [ "$mtime2" = $TEST_39_MTIME ] || \
4781                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4782
4783                         cancel_lru_locks $OSC
4784                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4785                 done
4786         fi
4787 }
4788 run_test 39h "write, utime within one second, stat ============="
4789
4790 test_39i() {
4791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4792
4793         touch $DIR1/$tfile
4794         sleep 1
4795
4796         echo hello >> $DIR1/$tfile
4797         local mtime1=`stat -c %Y $DIR1/$tfile`
4798
4799         mv $DIR1/$tfile $DIR1/$tfile-1
4800
4801         for (( i=0; i < 2; i++ )) ; do
4802                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4803
4804                 [ "$mtime1" = "$mtime2" ] || \
4805                         error "lost mtime: $mtime2, should be $mtime1"
4806
4807                 cancel_lru_locks $OSC
4808                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4809         done
4810 }
4811 run_test 39i "write, rename, stat =============================="
4812
4813 test_39j() {
4814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4815
4816         start_full_debug_logging
4817         touch $DIR1/$tfile
4818         sleep 1
4819
4820         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4821         lctl set_param fail_loc=0x80000412
4822         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4823                 error "multiop failed"
4824         local multipid=$!
4825         local mtime1=`stat -c %Y $DIR1/$tfile`
4826
4827         mv $DIR1/$tfile $DIR1/$tfile-1
4828
4829         kill -USR1 $multipid
4830         wait $multipid || error "multiop close failed"
4831
4832         for (( i=0; i < 2; i++ )) ; do
4833                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4834                 [ "$mtime1" = "$mtime2" ] ||
4835                         error "mtime is lost on close: $mtime2, " \
4836                               "should be $mtime1"
4837
4838                 cancel_lru_locks
4839                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4840         done
4841         lctl set_param fail_loc=0
4842         stop_full_debug_logging
4843 }
4844 run_test 39j "write, rename, close, stat ======================="
4845
4846 test_39k() {
4847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4848
4849         touch $DIR1/$tfile
4850         sleep 1
4851
4852         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4853         local multipid=$!
4854         local mtime1=`stat -c %Y $DIR1/$tfile`
4855
4856         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4857
4858         kill -USR1 $multipid
4859         wait $multipid || error "multiop close failed"
4860
4861         for (( i=0; i < 2; i++ )) ; do
4862                 local mtime2=`stat -c %Y $DIR1/$tfile`
4863
4864                 [ "$mtime2" = $TEST_39_MTIME ] || \
4865                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4866
4867                 cancel_lru_locks
4868                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4869         done
4870 }
4871 run_test 39k "write, utime, close, stat ========================"
4872
4873 # this should be set to future
4874 TEST_39_ATIME=`date -d "1 year" +%s`
4875
4876 test_39l() {
4877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4878         remote_mds_nodsh && skip "remote MDS with nodsh"
4879
4880         local atime_diff=$(do_facet $SINGLEMDS \
4881                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4882         rm -rf $DIR/$tdir
4883         mkdir_on_mdt0 $DIR/$tdir
4884
4885         # test setting directory atime to future
4886         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4887         local atime=$(stat -c %X $DIR/$tdir)
4888         [ "$atime" = $TEST_39_ATIME ] ||
4889                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4890
4891         # test setting directory atime from future to now
4892         local now=$(date +%s)
4893         touch -a -d @$now $DIR/$tdir
4894
4895         atime=$(stat -c %X $DIR/$tdir)
4896         [ "$atime" -eq "$now"  ] ||
4897                 error "atime is not updated from future: $atime, $now"
4898
4899         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4900         sleep 3
4901
4902         # test setting directory atime when now > dir atime + atime_diff
4903         local d1=$(date +%s)
4904         ls $DIR/$tdir
4905         local d2=$(date +%s)
4906         cancel_lru_locks mdc
4907         atime=$(stat -c %X $DIR/$tdir)
4908         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4909                 error "atime is not updated  : $atime, should be $d2"
4910
4911         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4912         sleep 3
4913
4914         # test not setting directory atime when now < dir atime + atime_diff
4915         ls $DIR/$tdir
4916         cancel_lru_locks mdc
4917         atime=$(stat -c %X $DIR/$tdir)
4918         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4919                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4920
4921         do_facet $SINGLEMDS \
4922                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4923 }
4924 run_test 39l "directory atime update ==========================="
4925
4926 test_39m() {
4927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4928
4929         touch $DIR1/$tfile
4930         sleep 2
4931         local far_past_mtime=$(date -d "May 29 1953" +%s)
4932         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4933
4934         touch -m -d @$far_past_mtime $DIR1/$tfile
4935         touch -a -d @$far_past_atime $DIR1/$tfile
4936
4937         for (( i=0; i < 2; i++ )) ; do
4938                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4939                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4940                         error "atime or mtime set incorrectly"
4941
4942                 cancel_lru_locks $OSC
4943                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4944         done
4945 }
4946 run_test 39m "test atime and mtime before 1970"
4947
4948 test_39n() { # LU-3832
4949         remote_mds_nodsh && skip "remote MDS with nodsh"
4950
4951         local atime_diff=$(do_facet $SINGLEMDS \
4952                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4953         local atime0
4954         local atime1
4955         local atime2
4956
4957         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4958
4959         rm -rf $DIR/$tfile
4960         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4961         atime0=$(stat -c %X $DIR/$tfile)
4962
4963         sleep 5
4964         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4965         atime1=$(stat -c %X $DIR/$tfile)
4966
4967         sleep 5
4968         cancel_lru_locks mdc
4969         cancel_lru_locks osc
4970         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4971         atime2=$(stat -c %X $DIR/$tfile)
4972
4973         do_facet $SINGLEMDS \
4974                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4975
4976         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4977         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4978 }
4979 run_test 39n "check that O_NOATIME is honored"
4980
4981 test_39o() {
4982         TESTDIR=$DIR/$tdir/$tfile
4983         [ -e $TESTDIR ] && rm -rf $TESTDIR
4984         mkdir -p $TESTDIR
4985         cd $TESTDIR
4986         links1=2
4987         ls
4988         mkdir a b
4989         ls
4990         links2=$(stat -c %h .)
4991         [ $(($links1 + 2)) != $links2 ] &&
4992                 error "wrong links count $(($links1 + 2)) != $links2"
4993         rmdir b
4994         links3=$(stat -c %h .)
4995         [ $(($links1 + 1)) != $links3 ] &&
4996                 error "wrong links count $links1 != $links3"
4997         return 0
4998 }
4999 run_test 39o "directory cached attributes updated after create"
5000
5001 test_39p() {
5002         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5003
5004         local MDTIDX=1
5005         TESTDIR=$DIR/$tdir/$tdir
5006         [ -e $TESTDIR ] && rm -rf $TESTDIR
5007         test_mkdir -p $TESTDIR
5008         cd $TESTDIR
5009         links1=2
5010         ls
5011         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5012         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5013         ls
5014         links2=$(stat -c %h .)
5015         [ $(($links1 + 2)) != $links2 ] &&
5016                 error "wrong links count $(($links1 + 2)) != $links2"
5017         rmdir remote_dir2
5018         links3=$(stat -c %h .)
5019         [ $(($links1 + 1)) != $links3 ] &&
5020                 error "wrong links count $links1 != $links3"
5021         return 0
5022 }
5023 run_test 39p "remote directory cached attributes updated after create ========"
5024
5025 test_39r() {
5026         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5027                 skip "no atime update on old OST"
5028         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5029                 skip_env "ldiskfs only test"
5030         fi
5031
5032         local saved_adiff
5033         saved_adiff=$(do_facet ost1 \
5034                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5035         stack_trap "do_facet ost1 \
5036                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5037
5038         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5039
5040         $LFS setstripe -i 0 $DIR/$tfile
5041         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5042                 error "can't write initial file"
5043         cancel_lru_locks osc
5044
5045         # exceed atime_diff and access file
5046         sleep 10
5047         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5048                 error "can't udpate atime"
5049
5050         local atime_cli=$(stat -c %X $DIR/$tfile)
5051         echo "client atime: $atime_cli"
5052         # allow atime update to be written to device
5053         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5054         sleep 5
5055
5056         local ostdev=$(ostdevname 1)
5057         local fid=($(lfs getstripe -y $DIR/$tfile |
5058                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
5059         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
5060         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5061
5062         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5063         local atime_ost=$(do_facet ost1 "$cmd" |&
5064                           awk -F'[: ]' '/atime:/ { print $4 }')
5065         (( atime_cli == atime_ost )) ||
5066                 error "atime on client $atime_cli != ost $atime_ost"
5067 }
5068 run_test 39r "lazy atime update on OST"
5069
5070 test_39q() { # LU-8041
5071         local testdir=$DIR/$tdir
5072         mkdir -p $testdir
5073         multiop_bg_pause $testdir D_c || error "multiop failed"
5074         local multipid=$!
5075         cancel_lru_locks mdc
5076         kill -USR1 $multipid
5077         local atime=$(stat -c %X $testdir)
5078         [ "$atime" -ne 0 ] || error "atime is zero"
5079 }
5080 run_test 39q "close won't zero out atime"
5081
5082 test_40() {
5083         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5084         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5085                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5086         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5087                 error "$tfile is not 4096 bytes in size"
5088 }
5089 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5090
5091 test_41() {
5092         # bug 1553
5093         small_write $DIR/f41 18
5094 }
5095 run_test 41 "test small file write + fstat ====================="
5096
5097 count_ost_writes() {
5098         lctl get_param -n ${OSC}.*.stats |
5099                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5100                         END { printf("%0.0f", writes) }'
5101 }
5102
5103 # decent default
5104 WRITEBACK_SAVE=500
5105 DIRTY_RATIO_SAVE=40
5106 MAX_DIRTY_RATIO=50
5107 BG_DIRTY_RATIO_SAVE=10
5108 MAX_BG_DIRTY_RATIO=25
5109
5110 start_writeback() {
5111         trap 0
5112         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5113         # dirty_ratio, dirty_background_ratio
5114         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5115                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5116                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5117                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5118         else
5119                 # if file not here, we are a 2.4 kernel
5120                 kill -CONT `pidof kupdated`
5121         fi
5122 }
5123
5124 stop_writeback() {
5125         # setup the trap first, so someone cannot exit the test at the
5126         # exact wrong time and mess up a machine
5127         trap start_writeback EXIT
5128         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5129         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5130                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5131                 sysctl -w vm.dirty_writeback_centisecs=0
5132                 sysctl -w vm.dirty_writeback_centisecs=0
5133                 # save and increase /proc/sys/vm/dirty_ratio
5134                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5135                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5136                 # save and increase /proc/sys/vm/dirty_background_ratio
5137                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5138                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5139         else
5140                 # if file not here, we are a 2.4 kernel
5141                 kill -STOP `pidof kupdated`
5142         fi
5143 }
5144
5145 # ensure that all stripes have some grant before we test client-side cache
5146 setup_test42() {
5147         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5148                 dd if=/dev/zero of=$i bs=4k count=1
5149                 rm $i
5150         done
5151 }
5152
5153 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5154 # file truncation, and file removal.
5155 test_42a() {
5156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5157
5158         setup_test42
5159         cancel_lru_locks $OSC
5160         stop_writeback
5161         sync; sleep 1; sync # just to be safe
5162         BEFOREWRITES=`count_ost_writes`
5163         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5164         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5165         AFTERWRITES=`count_ost_writes`
5166         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5167                 error "$BEFOREWRITES < $AFTERWRITES"
5168         start_writeback
5169 }
5170 run_test 42a "ensure that we don't flush on close"
5171
5172 test_42b() {
5173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5174
5175         setup_test42
5176         cancel_lru_locks $OSC
5177         stop_writeback
5178         sync
5179         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5180         BEFOREWRITES=$(count_ost_writes)
5181         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5182         AFTERWRITES=$(count_ost_writes)
5183         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5184                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5185         fi
5186         BEFOREWRITES=$(count_ost_writes)
5187         sync || error "sync: $?"
5188         AFTERWRITES=$(count_ost_writes)
5189         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5190                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5191         fi
5192         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5193         start_writeback
5194         return 0
5195 }
5196 run_test 42b "test destroy of file with cached dirty data ======"
5197
5198 # if these tests just want to test the effect of truncation,
5199 # they have to be very careful.  consider:
5200 # - the first open gets a {0,EOF}PR lock
5201 # - the first write conflicts and gets a {0, count-1}PW
5202 # - the rest of the writes are under {count,EOF}PW
5203 # - the open for truncate tries to match a {0,EOF}PR
5204 #   for the filesize and cancels the PWs.
5205 # any number of fixes (don't get {0,EOF} on open, match
5206 # composite locks, do smarter file size management) fix
5207 # this, but for now we want these tests to verify that
5208 # the cancellation with truncate intent works, so we
5209 # start the file with a full-file pw lock to match against
5210 # until the truncate.
5211 trunc_test() {
5212         test=$1
5213         file=$DIR/$test
5214         offset=$2
5215         cancel_lru_locks $OSC
5216         stop_writeback
5217         # prime the file with 0,EOF PW to match
5218         touch $file
5219         $TRUNCATE $file 0
5220         sync; sync
5221         # now the real test..
5222         dd if=/dev/zero of=$file bs=1024 count=100
5223         BEFOREWRITES=`count_ost_writes`
5224         $TRUNCATE $file $offset
5225         cancel_lru_locks $OSC
5226         AFTERWRITES=`count_ost_writes`
5227         start_writeback
5228 }
5229
5230 test_42c() {
5231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5232
5233         trunc_test 42c 1024
5234         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5235                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5236         rm $file
5237 }
5238 run_test 42c "test partial truncate of file with cached dirty data"
5239
5240 test_42d() {
5241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5242
5243         trunc_test 42d 0
5244         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5245                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5246         rm $file
5247 }
5248 run_test 42d "test complete truncate of file with cached dirty data"
5249
5250 test_42e() { # bug22074
5251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5252
5253         local TDIR=$DIR/${tdir}e
5254         local pages=16 # hardcoded 16 pages, don't change it.
5255         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5256         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5257         local max_dirty_mb
5258         local warmup_files
5259
5260         test_mkdir $DIR/${tdir}e
5261         $LFS setstripe -c 1 $TDIR
5262         createmany -o $TDIR/f $files
5263
5264         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5265
5266         # we assume that with $OSTCOUNT files, at least one of them will
5267         # be allocated on OST0.
5268         warmup_files=$((OSTCOUNT * max_dirty_mb))
5269         createmany -o $TDIR/w $warmup_files
5270
5271         # write a large amount of data into one file and sync, to get good
5272         # avail_grant number from OST.
5273         for ((i=0; i<$warmup_files; i++)); do
5274                 idx=$($LFS getstripe -i $TDIR/w$i)
5275                 [ $idx -ne 0 ] && continue
5276                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5277                 break
5278         done
5279         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5280         sync
5281         $LCTL get_param $proc_osc0/cur_dirty_bytes
5282         $LCTL get_param $proc_osc0/cur_grant_bytes
5283
5284         # create as much dirty pages as we can while not to trigger the actual
5285         # RPCs directly. but depends on the env, VFS may trigger flush during this
5286         # period, hopefully we are good.
5287         for ((i=0; i<$warmup_files; i++)); do
5288                 idx=$($LFS getstripe -i $TDIR/w$i)
5289                 [ $idx -ne 0 ] && continue
5290                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5291         done
5292         $LCTL get_param $proc_osc0/cur_dirty_bytes
5293         $LCTL get_param $proc_osc0/cur_grant_bytes
5294
5295         # perform the real test
5296         $LCTL set_param $proc_osc0/rpc_stats 0
5297         for ((;i<$files; i++)); do
5298                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5299                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5300         done
5301         sync
5302         $LCTL get_param $proc_osc0/rpc_stats
5303
5304         local percent=0
5305         local have_ppr=false
5306         $LCTL get_param $proc_osc0/rpc_stats |
5307                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5308                         # skip lines until we are at the RPC histogram data
5309                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5310                         $have_ppr || continue
5311
5312                         # we only want the percent stat for < 16 pages
5313                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5314
5315                         percent=$((percent + WPCT))
5316                         if [[ $percent -gt 15 ]]; then
5317                                 error "less than 16-pages write RPCs" \
5318                                       "$percent% > 15%"
5319                                 break
5320                         fi
5321                 done
5322         rm -rf $TDIR
5323 }
5324 run_test 42e "verify sub-RPC writes are not done synchronously"
5325
5326 test_43A() { # was test_43
5327         test_mkdir $DIR/$tdir
5328         cp -p /bin/ls $DIR/$tdir/$tfile
5329         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5330         pid=$!
5331         # give multiop a chance to open
5332         sleep 1
5333
5334         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5335         kill -USR1 $pid
5336         # Wait for multiop to exit
5337         wait $pid
5338 }
5339 run_test 43A "execution of file opened for write should return -ETXTBSY"
5340
5341 test_43a() {
5342         test_mkdir $DIR/$tdir
5343         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5344         $DIR/$tdir/sleep 60 &
5345         SLEEP_PID=$!
5346         # Make sure exec of $tdir/sleep wins race with truncate
5347         sleep 1
5348         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5349         kill $SLEEP_PID
5350 }
5351 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5352
5353 test_43b() {
5354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5355
5356         test_mkdir $DIR/$tdir
5357         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5358         $DIR/$tdir/sleep 60 &
5359         SLEEP_PID=$!
5360         # Make sure exec of $tdir/sleep wins race with truncate
5361         sleep 1
5362         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5363         kill $SLEEP_PID
5364 }
5365 run_test 43b "truncate of file being executed should return -ETXTBSY"
5366
5367 test_43c() {
5368         local testdir="$DIR/$tdir"
5369         test_mkdir $testdir
5370         cp $SHELL $testdir/
5371         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5372                 ( cd $testdir && md5sum -c )
5373 }
5374 run_test 43c "md5sum of copy into lustre"
5375
5376 test_44A() { # was test_44
5377         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5378
5379         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5380         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5381 }
5382 run_test 44A "zero length read from a sparse stripe"
5383
5384 test_44a() {
5385         local nstripe=$($LFS getstripe -c -d $DIR)
5386         [ -z "$nstripe" ] && skip "can't get stripe info"
5387         [[ $nstripe -gt $OSTCOUNT ]] &&
5388                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5389
5390         local stride=$($LFS getstripe -S -d $DIR)
5391         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5392                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5393         fi
5394
5395         OFFSETS="0 $((stride/2)) $((stride-1))"
5396         for offset in $OFFSETS; do
5397                 for i in $(seq 0 $((nstripe-1))); do
5398                         local GLOBALOFFSETS=""
5399                         # size in Bytes
5400                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5401                         local myfn=$DIR/d44a-$size
5402                         echo "--------writing $myfn at $size"
5403                         ll_sparseness_write $myfn $size ||
5404                                 error "ll_sparseness_write"
5405                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5406                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5407                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5408
5409                         for j in $(seq 0 $((nstripe-1))); do
5410                                 # size in Bytes
5411                                 size=$((((j + $nstripe )*$stride + $offset)))
5412                                 ll_sparseness_write $myfn $size ||
5413                                         error "ll_sparseness_write"
5414                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5415                         done
5416                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5417                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5418                         rm -f $myfn
5419                 done
5420         done
5421 }
5422 run_test 44a "test sparse pwrite ==============================="
5423
5424 dirty_osc_total() {
5425         tot=0
5426         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5427                 tot=$(($tot + $d))
5428         done
5429         echo $tot
5430 }
5431 do_dirty_record() {
5432         before=`dirty_osc_total`
5433         echo executing "\"$*\""
5434         eval $*
5435         after=`dirty_osc_total`
5436         echo before $before, after $after
5437 }
5438 test_45() {
5439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5440
5441         f="$DIR/f45"
5442         # Obtain grants from OST if it supports it
5443         echo blah > ${f}_grant
5444         stop_writeback
5445         sync
5446         do_dirty_record "echo blah > $f"
5447         [[ $before -eq $after ]] && error "write wasn't cached"
5448         do_dirty_record "> $f"
5449         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5450         do_dirty_record "echo blah > $f"
5451         [[ $before -eq $after ]] && error "write wasn't cached"
5452         do_dirty_record "sync"
5453         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5454         do_dirty_record "echo blah > $f"
5455         [[ $before -eq $after ]] && error "write wasn't cached"
5456         do_dirty_record "cancel_lru_locks osc"
5457         [[ $before -gt $after ]] ||
5458                 error "lock cancellation didn't lower dirty count"
5459         start_writeback
5460 }
5461 run_test 45 "osc io page accounting ============================"
5462
5463 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5464 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5465 # objects offset and an assert hit when an rpc was built with 1023's mapped
5466 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5467 test_46() {
5468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5469
5470         f="$DIR/f46"
5471         stop_writeback
5472         sync
5473         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5474         sync
5475         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5476         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5477         sync
5478         start_writeback
5479 }
5480 run_test 46 "dirtying a previously written page ================"
5481
5482 # test_47 is removed "Device nodes check" is moved to test_28
5483
5484 test_48a() { # bug 2399
5485         [ "$mds1_FSTYPE" = "zfs" ] &&
5486         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5487                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5488
5489         test_mkdir $DIR/$tdir
5490         cd $DIR/$tdir
5491         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5492         test_mkdir $DIR/$tdir
5493         touch foo || error "'touch foo' failed after recreating cwd"
5494         test_mkdir bar
5495         touch .foo || error "'touch .foo' failed after recreating cwd"
5496         test_mkdir .bar
5497         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5498         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5499         cd . || error "'cd .' failed after recreating cwd"
5500         mkdir . && error "'mkdir .' worked after recreating cwd"
5501         rmdir . && error "'rmdir .' worked after recreating cwd"
5502         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5503         cd .. || error "'cd ..' failed after recreating cwd"
5504 }
5505 run_test 48a "Access renamed working dir (should return errors)="
5506
5507 test_48b() { # bug 2399
5508         rm -rf $DIR/$tdir
5509         test_mkdir $DIR/$tdir
5510         cd $DIR/$tdir
5511         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5512         touch foo && error "'touch foo' worked after removing cwd"
5513         mkdir foo && error "'mkdir foo' worked after removing cwd"
5514         touch .foo && error "'touch .foo' worked after removing cwd"
5515         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5516         ls . > /dev/null && error "'ls .' worked after removing cwd"
5517         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5518         mkdir . && error "'mkdir .' worked after removing cwd"
5519         rmdir . && error "'rmdir .' worked after removing cwd"
5520         ln -s . foo && error "'ln -s .' worked after removing cwd"
5521         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5522 }
5523 run_test 48b "Access removed working dir (should return errors)="
5524
5525 test_48c() { # bug 2350
5526         #lctl set_param debug=-1
5527         #set -vx
5528         rm -rf $DIR/$tdir
5529         test_mkdir -p $DIR/$tdir/dir
5530         cd $DIR/$tdir/dir
5531         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5532         $TRACE touch foo && error "touch foo worked after removing cwd"
5533         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5534         touch .foo && error "touch .foo worked after removing cwd"
5535         mkdir .foo && error "mkdir .foo worked after removing cwd"
5536         $TRACE ls . && error "'ls .' worked after removing cwd"
5537         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5538         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5539         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5540         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5541         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5542 }
5543 run_test 48c "Access removed working subdir (should return errors)"
5544
5545 test_48d() { # bug 2350
5546         #lctl set_param debug=-1
5547         #set -vx
5548         rm -rf $DIR/$tdir
5549         test_mkdir -p $DIR/$tdir/dir
5550         cd $DIR/$tdir/dir
5551         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5552         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5553         $TRACE touch foo && error "'touch foo' worked after removing parent"
5554         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5555         touch .foo && error "'touch .foo' worked after removing parent"
5556         mkdir .foo && error "mkdir .foo worked after removing parent"
5557         $TRACE ls . && error "'ls .' worked after removing parent"
5558         $TRACE ls .. && error "'ls ..' worked after removing parent"
5559         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5560         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5561         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5562         true
5563 }
5564 run_test 48d "Access removed parent subdir (should return errors)"
5565
5566 test_48e() { # bug 4134
5567         #lctl set_param debug=-1
5568         #set -vx
5569         rm -rf $DIR/$tdir
5570         test_mkdir -p $DIR/$tdir/dir
5571         cd $DIR/$tdir/dir
5572         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5573         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5574         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5575         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5576         # On a buggy kernel addition of "touch foo" after cd .. will
5577         # produce kernel oops in lookup_hash_it
5578         touch ../foo && error "'cd ..' worked after recreate parent"
5579         cd $DIR
5580         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5581 }
5582 run_test 48e "Access to recreated parent subdir (should return errors)"
5583
5584 test_48f() {
5585         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5586                 skip "need MDS >= 2.13.55"
5587         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5588         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5589                 skip "needs different host for mdt1 mdt2"
5590         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5591
5592         $LFS mkdir -i0 $DIR/$tdir
5593         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5594
5595         for d in sub1 sub2 sub3; do
5596                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5597                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5598                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5599         done
5600
5601         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5602 }
5603 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5604
5605 test_49() { # LU-1030
5606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5607         remote_ost_nodsh && skip "remote OST with nodsh"
5608
5609         # get ost1 size - $FSNAME-OST0000
5610         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5611                 awk '{ print $4 }')
5612         # write 800M at maximum
5613         [[ $ost1_size -lt 2 ]] && ost1_size=2
5614         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5615
5616         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5617         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5618         local dd_pid=$!
5619
5620         # change max_pages_per_rpc while writing the file
5621         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5622         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5623         # loop until dd process exits
5624         while ps ax -opid | grep -wq $dd_pid; do
5625                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5626                 sleep $((RANDOM % 5 + 1))
5627         done
5628         # restore original max_pages_per_rpc
5629         $LCTL set_param $osc1_mppc=$orig_mppc
5630         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5631 }
5632 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5633
5634 test_50() {
5635         # bug 1485
5636         test_mkdir $DIR/$tdir
5637         cd $DIR/$tdir
5638         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5639 }
5640 run_test 50 "special situations: /proc symlinks  ==============="
5641
5642 test_51a() {    # was test_51
5643         # bug 1516 - create an empty entry right after ".." then split dir
5644         test_mkdir -c1 $DIR/$tdir
5645         touch $DIR/$tdir/foo
5646         $MCREATE $DIR/$tdir/bar
5647         rm $DIR/$tdir/foo
5648         createmany -m $DIR/$tdir/longfile 201
5649         FNUM=202
5650         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5651                 $MCREATE $DIR/$tdir/longfile$FNUM
5652                 FNUM=$(($FNUM + 1))
5653                 echo -n "+"
5654         done
5655         echo
5656         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5657 }
5658 run_test 51a "special situations: split htree with empty entry =="
5659
5660 cleanup_print_lfs_df () {
5661         trap 0
5662         $LFS df
5663         $LFS df -i
5664 }
5665
5666 test_51b() {
5667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5668
5669         local dir=$DIR/$tdir
5670         local nrdirs=$((65536 + 100))
5671
5672         # cleanup the directory
5673         rm -fr $dir
5674
5675         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5676
5677         $LFS df
5678         $LFS df -i
5679         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5680         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5681         [[ $numfree -lt $nrdirs ]] &&
5682                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5683
5684         # need to check free space for the directories as well
5685         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5686         numfree=$(( blkfree / $(fs_inode_ksize) ))
5687         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5688
5689         trap cleanup_print_lfs_df EXIT
5690
5691         # create files
5692         createmany -d $dir/d $nrdirs || {
5693                 unlinkmany $dir/d $nrdirs
5694                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5695         }
5696
5697         # really created :
5698         nrdirs=$(ls -U $dir | wc -l)
5699
5700         # unlink all but 100 subdirectories, then check it still works
5701         local left=100
5702         local delete=$((nrdirs - left))
5703
5704         $LFS df
5705         $LFS df -i
5706
5707         # for ldiskfs the nlink count should be 1, but this is OSD specific
5708         # and so this is listed for informational purposes only
5709         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5710         unlinkmany -d $dir/d $delete ||
5711                 error "unlink of first $delete subdirs failed"
5712
5713         echo "nlink between: $(stat -c %h $dir)"
5714         local found=$(ls -U $dir | wc -l)
5715         [ $found -ne $left ] &&
5716                 error "can't find subdirs: found only $found, expected $left"
5717
5718         unlinkmany -d $dir/d $delete $left ||
5719                 error "unlink of second $left subdirs failed"
5720         # regardless of whether the backing filesystem tracks nlink accurately
5721         # or not, the nlink count shouldn't be more than "." and ".." here
5722         local after=$(stat -c %h $dir)
5723         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5724                 echo "nlink after: $after"
5725
5726         cleanup_print_lfs_df
5727 }
5728 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5729
5730 test_51d() {
5731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5732         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5733         local qos_old
5734
5735         test_mkdir $DIR/$tdir
5736         $LFS setstripe -c $OSTCOUNT $DIR/$tdir
5737
5738         qos_old=$(do_facet mds1 \
5739                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5740         do_nodes $(comma_list $(mdts_nodes)) \
5741                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5742         stack_trap "do_nodes $(comma_list $(mdts_nodes)) \
5743                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5744
5745         createmany -o $DIR/$tdir/t- 1000
5746         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5747         for ((n = 0; n < $OSTCOUNT; n++)); do
5748                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5749                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5750                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5751                             '($1 == '$n') { objs += 1 } \
5752                             END { printf("%0.0f", objs) }')
5753                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5754         done
5755         unlinkmany $DIR/$tdir/t- 1000
5756
5757         nlast=0
5758         for ((n = 0; n < $OSTCOUNT; n++)); do
5759                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5760                         { $LFS df && $LFS df -i &&
5761                         error "OST $n has fewer objects vs. OST $nlast" \
5762                               " (${objs[$n]} < ${objs[$nlast]}"; }
5763                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5764                         { $LFS df && $LFS df -i &&
5765                         error "OST $n has fewer objects vs. OST $nlast" \
5766                               " (${objs[$n]} < ${objs[$nlast]}"; }
5767
5768                 (( ${objs0[$n]} > ${objs0[$nlast]} * 4 / 5 )) ||
5769                         { $LFS df && $LFS df -i &&
5770                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5771                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5772                 (( ${objs0[$n]} < ${objs0[$nlast]} * 5 / 4 )) ||
5773                         { $LFS df && $LFS df -i &&
5774                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5775                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5776                 nlast=$n
5777         done
5778 }
5779 run_test 51d "check object distribution"
5780
5781 test_51e() {
5782         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5783                 skip_env "ldiskfs only test"
5784         fi
5785
5786         test_mkdir -c1 $DIR/$tdir
5787         test_mkdir -c1 $DIR/$tdir/d0
5788
5789         touch $DIR/$tdir/d0/foo
5790         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5791                 error "file exceed 65000 nlink limit!"
5792         unlinkmany $DIR/$tdir/d0/f- 65001
5793         return 0
5794 }
5795 run_test 51e "check file nlink limit"
5796
5797 test_51f() {
5798         test_mkdir $DIR/$tdir
5799
5800         local max=100000
5801         local ulimit_old=$(ulimit -n)
5802         local spare=20 # number of spare fd's for scripts/libraries, etc.
5803         local mdt=$($LFS getstripe -m $DIR/$tdir)
5804         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5805
5806         echo "MDT$mdt numfree=$numfree, max=$max"
5807         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5808         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5809                 while ! ulimit -n $((numfree + spare)); do
5810                         numfree=$((numfree * 3 / 4))
5811                 done
5812                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5813         else
5814                 echo "left ulimit at $ulimit_old"
5815         fi
5816
5817         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5818                 unlinkmany $DIR/$tdir/f $numfree
5819                 error "create+open $numfree files in $DIR/$tdir failed"
5820         }
5821         ulimit -n $ulimit_old
5822
5823         # if createmany exits at 120s there will be fewer than $numfree files
5824         unlinkmany $DIR/$tdir/f $numfree || true
5825 }
5826 run_test 51f "check many open files limit"
5827
5828 test_52a() {
5829         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5830         test_mkdir $DIR/$tdir
5831         touch $DIR/$tdir/foo
5832         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5833         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5834         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5835         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5836         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5837                                         error "link worked"
5838         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5839         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5840         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5841                                                      error "lsattr"
5842         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5843         cp -r $DIR/$tdir $TMP/
5844         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5845 }
5846 run_test 52a "append-only flag test (should return errors)"
5847
5848 test_52b() {
5849         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5850         test_mkdir $DIR/$tdir
5851         touch $DIR/$tdir/foo
5852         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5853         cat test > $DIR/$tdir/foo && error "cat test worked"
5854         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5855         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5856         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5857                                         error "link worked"
5858         echo foo >> $DIR/$tdir/foo && error "echo worked"
5859         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5860         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5861         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5862         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5863                                                         error "lsattr"
5864         chattr -i $DIR/$tdir/foo || error "chattr failed"
5865
5866         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5867 }
5868 run_test 52b "immutable flag test (should return errors) ======="
5869
5870 test_53() {
5871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5872         remote_mds_nodsh && skip "remote MDS with nodsh"
5873         remote_ost_nodsh && skip "remote OST with nodsh"
5874
5875         local param
5876         local param_seq
5877         local ostname
5878         local mds_last
5879         local mds_last_seq
5880         local ost_last
5881         local ost_last_seq
5882         local ost_last_id
5883         local ostnum
5884         local node
5885         local found=false
5886         local support_last_seq=true
5887
5888         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5889                 support_last_seq=false
5890
5891         # only test MDT0000
5892         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5893         local value
5894         for value in $(do_facet $SINGLEMDS \
5895                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5896                 param=$(echo ${value[0]} | cut -d "=" -f1)
5897                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5898
5899                 if $support_last_seq; then
5900                         param_seq=$(echo $param |
5901                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5902                         mds_last_seq=$(do_facet $SINGLEMDS \
5903                                        $LCTL get_param -n $param_seq)
5904                 fi
5905                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5906
5907                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5908                 node=$(facet_active_host ost$((ostnum+1)))
5909                 param="obdfilter.$ostname.last_id"
5910                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5911                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5912                         ost_last_id=$ost_last
5913
5914                         if $support_last_seq; then
5915                                 ost_last_id=$(echo $ost_last |
5916                                               awk -F':' '{print $2}' |
5917                                               sed -e "s/^0x//g")
5918                                 ost_last_seq=$(echo $ost_last |
5919                                                awk -F':' '{print $1}')
5920                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5921                         fi
5922
5923                         if [[ $ost_last_id != $mds_last ]]; then
5924                                 error "$ost_last_id != $mds_last"
5925                         else
5926                                 found=true
5927                                 break
5928                         fi
5929                 done
5930         done
5931         $found || error "can not match last_seq/last_id for $mdtosc"
5932         return 0
5933 }
5934 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5935
5936 test_54a() {
5937         perl -MSocket -e ';' || skip "no Socket perl module installed"
5938
5939         $SOCKETSERVER $DIR/socket ||
5940                 error "$SOCKETSERVER $DIR/socket failed: $?"
5941         $SOCKETCLIENT $DIR/socket ||
5942                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5943         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5944 }
5945 run_test 54a "unix domain socket test =========================="
5946
5947 test_54b() {
5948         f="$DIR/f54b"
5949         mknod $f c 1 3
5950         chmod 0666 $f
5951         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5952 }
5953 run_test 54b "char device works in lustre ======================"
5954
5955 find_loop_dev() {
5956         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5957         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5958         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5959
5960         for i in $(seq 3 7); do
5961                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5962                 LOOPDEV=$LOOPBASE$i
5963                 LOOPNUM=$i
5964                 break
5965         done
5966 }
5967
5968 cleanup_54c() {
5969         local rc=0
5970         loopdev="$DIR/loop54c"
5971
5972         trap 0
5973         $UMOUNT $DIR/$tdir || rc=$?
5974         losetup -d $loopdev || true
5975         losetup -d $LOOPDEV || true
5976         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5977         return $rc
5978 }
5979
5980 test_54c() {
5981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5982
5983         loopdev="$DIR/loop54c"
5984
5985         find_loop_dev
5986         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5987         trap cleanup_54c EXIT
5988         mknod $loopdev b 7 $LOOPNUM
5989         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5990         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5991         losetup $loopdev $DIR/$tfile ||
5992                 error "can't set up $loopdev for $DIR/$tfile"
5993         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5994         test_mkdir $DIR/$tdir
5995         mount -t ext2 $loopdev $DIR/$tdir ||
5996                 error "error mounting $loopdev on $DIR/$tdir"
5997         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5998                 error "dd write"
5999         df $DIR/$tdir
6000         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6001                 error "dd read"
6002         cleanup_54c
6003 }
6004 run_test 54c "block device works in lustre ====================="
6005
6006 test_54d() {
6007         local pipe="$DIR/$tfile.pipe"
6008         local string="aaaaaa"
6009
6010         mknod $pipe p
6011         echo -n "$string" > $pipe &
6012         local result=$(cat $pipe)
6013         [[ "$result" == "$string" ]] || error "$result != $string"
6014 }
6015 run_test 54d "fifo device works in lustre ======================"
6016
6017 test_54e() {
6018         f="$DIR/f54e"
6019         string="aaaaaa"
6020         cp -aL /dev/console $f
6021         echo $string > $f || error "echo $string to $f failed"
6022 }
6023 run_test 54e "console/tty device works in lustre ======================"
6024
6025 test_56a() {
6026         local numfiles=3
6027         local numdirs=2
6028         local dir=$DIR/$tdir
6029
6030         rm -rf $dir
6031         test_mkdir -p $dir/dir
6032         for i in $(seq $numfiles); do
6033                 touch $dir/file$i
6034                 touch $dir/dir/file$i
6035         done
6036
6037         local numcomp=$($LFS getstripe --component-count $dir)
6038
6039         [[ $numcomp == 0 ]] && numcomp=1
6040
6041         # test lfs getstripe with --recursive
6042         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6043
6044         [[ $filenum -eq $((numfiles * 2)) ]] ||
6045                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6046         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6047         [[ $filenum -eq $numfiles ]] ||
6048                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6049         echo "$LFS getstripe showed obdidx or l_ost_idx"
6050
6051         # test lfs getstripe with file instead of dir
6052         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6053         [[ $filenum -eq 1 ]] ||
6054                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6055         echo "$LFS getstripe file1 passed"
6056
6057         #test lfs getstripe with --verbose
6058         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6059         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6060                 error "$LFS getstripe --verbose $dir: "\
6061                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6062         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6063                 error "$LFS getstripe $dir: showed lmm_magic"
6064
6065         #test lfs getstripe with -v prints lmm_fid
6066         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6067         local countfids=$((numdirs + numfiles * numcomp))
6068         [[ $filenum -eq $countfids ]] ||
6069                 error "$LFS getstripe -v $dir: "\
6070                       "got $filenum want $countfids lmm_fid"
6071         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6072                 error "$LFS getstripe $dir: showed lmm_fid by default"
6073         echo "$LFS getstripe --verbose passed"
6074
6075         #check for FID information
6076         local fid1=$($LFS getstripe --fid $dir/file1)
6077         local fid2=$($LFS getstripe --verbose $dir/file1 |
6078                      awk '/lmm_fid: / { print $2; exit; }')
6079         local fid3=$($LFS path2fid $dir/file1)
6080
6081         [ "$fid1" != "$fid2" ] &&
6082                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6083         [ "$fid1" != "$fid3" ] &&
6084                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6085         echo "$LFS getstripe --fid passed"
6086
6087         #test lfs getstripe with --obd
6088         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6089                 error "$LFS getstripe --obd wrong_uuid: should return error"
6090
6091         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6092
6093         local ostidx=1
6094         local obduuid=$(ostuuid_from_index $ostidx)
6095         local found=$($LFS getstripe -r --obd $obduuid $dir |
6096                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6097
6098         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6099         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6100                 ((filenum--))
6101         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6102                 ((filenum--))
6103
6104         [[ $found -eq $filenum ]] ||
6105                 error "$LFS getstripe --obd: found $found expect $filenum"
6106         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6107                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6108                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6109                 error "$LFS getstripe --obd: should not show file on other obd"
6110         echo "$LFS getstripe --obd passed"
6111 }
6112 run_test 56a "check $LFS getstripe"
6113
6114 test_56b() {
6115         local dir=$DIR/$tdir
6116         local numdirs=3
6117
6118         test_mkdir $dir
6119         for i in $(seq $numdirs); do
6120                 test_mkdir $dir/dir$i
6121         done
6122
6123         # test lfs getdirstripe default mode is non-recursion, which is
6124         # different from lfs getstripe
6125         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6126
6127         [[ $dircnt -eq 1 ]] ||
6128                 error "$LFS getdirstripe: found $dircnt, not 1"
6129         dircnt=$($LFS getdirstripe --recursive $dir |
6130                 grep -c lmv_stripe_count)
6131         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6132                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6133 }
6134 run_test 56b "check $LFS getdirstripe"
6135
6136 test_56c() {
6137         remote_ost_nodsh && skip "remote OST with nodsh"
6138
6139         local ost_idx=0
6140         local ost_name=$(ostname_from_index $ost_idx)
6141         local old_status=$(ost_dev_status $ost_idx)
6142         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6143
6144         [[ -z "$old_status" ]] ||
6145                 skip_env "OST $ost_name is in $old_status status"
6146
6147         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6148         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6149                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6150         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6151                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6152                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6153         fi
6154
6155         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6156                 error "$LFS df -v showing inactive devices"
6157         sleep_maxage
6158
6159         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6160
6161         [[ "$new_status" =~ "D" ]] ||
6162                 error "$ost_name status is '$new_status', missing 'D'"
6163         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6164                 [[ "$new_status" =~ "N" ]] ||
6165                         error "$ost_name status is '$new_status', missing 'N'"
6166         fi
6167         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6168                 [[ "$new_status" =~ "f" ]] ||
6169                         error "$ost_name status is '$new_status', missing 'f'"
6170         fi
6171
6172         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6173         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6174                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6175         [[ -z "$p" ]] && restore_lustre_params < $p || true
6176         sleep_maxage
6177
6178         new_status=$(ost_dev_status $ost_idx)
6179         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6180                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6181         # can't check 'f' as devices may actually be on flash
6182 }
6183 run_test 56c "check 'lfs df' showing device status"
6184
6185 test_56d() {
6186         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6187         local osts=$($LFS df -v $MOUNT | grep -c OST)
6188
6189         $LFS df $MOUNT
6190
6191         (( mdts == MDSCOUNT )) ||
6192                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6193         (( osts == OSTCOUNT )) ||
6194                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6195 }
6196 run_test 56d "'lfs df -v' prints only configured devices"
6197
6198 test_56e() {
6199         err_enoent=2 # No such file or directory
6200         err_eopnotsupp=95 # Operation not supported
6201
6202         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6203         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6204
6205         # Check for handling of path not exists
6206         output=$($LFS df $enoent_mnt 2>&1)
6207         ret=$?
6208
6209         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6210         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6211                 error "expect failure $err_enoent, not $ret"
6212
6213         # Check for handling of non-Lustre FS
6214         output=$($LFS df $notsup_mnt)
6215         ret=$?
6216
6217         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6218         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6219                 error "expect success $err_eopnotsupp, not $ret"
6220
6221         # Check for multiple LustreFS argument
6222         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6223         ret=$?
6224
6225         [[ $output -eq 3 && $ret -eq 0 ]] ||
6226                 error "expect success 3, not $output, rc = $ret"
6227
6228         # Check for correct non-Lustre FS handling among multiple
6229         # LustreFS argument
6230         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6231                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6232         ret=$?
6233
6234         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6235                 error "expect success 2, not $output, rc = $ret"
6236 }
6237 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6238
6239 NUMFILES=3
6240 NUMDIRS=3
6241 setup_56() {
6242         local local_tdir="$1"
6243         local local_numfiles="$2"
6244         local local_numdirs="$3"
6245         local dir_params="$4"
6246         local dir_stripe_params="$5"
6247
6248         if [ ! -d "$local_tdir" ] ; then
6249                 test_mkdir -p $dir_stripe_params $local_tdir
6250                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6251                 for i in $(seq $local_numfiles) ; do
6252                         touch $local_tdir/file$i
6253                 done
6254                 for i in $(seq $local_numdirs) ; do
6255                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6256                         for j in $(seq $local_numfiles) ; do
6257                                 touch $local_tdir/dir$i/file$j
6258                         done
6259                 done
6260         fi
6261 }
6262
6263 setup_56_special() {
6264         local local_tdir=$1
6265         local local_numfiles=$2
6266         local local_numdirs=$3
6267
6268         setup_56 $local_tdir $local_numfiles $local_numdirs
6269
6270         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6271                 for i in $(seq $local_numfiles) ; do
6272                         mknod $local_tdir/loop${i}b b 7 $i
6273                         mknod $local_tdir/null${i}c c 1 3
6274                         ln -s $local_tdir/file1 $local_tdir/link${i}
6275                 done
6276                 for i in $(seq $local_numdirs) ; do
6277                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6278                         mknod $local_tdir/dir$i/null${i}c c 1 3
6279                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6280                 done
6281         fi
6282 }
6283
6284 test_56g() {
6285         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6286         local expected=$(($NUMDIRS + 2))
6287
6288         setup_56 $dir $NUMFILES $NUMDIRS
6289
6290         # test lfs find with -name
6291         for i in $(seq $NUMFILES) ; do
6292                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6293
6294                 [ $nums -eq $expected ] ||
6295                         error "lfs find -name '*$i' $dir wrong: "\
6296                               "found $nums, expected $expected"
6297         done
6298 }
6299 run_test 56g "check lfs find -name"
6300
6301 test_56h() {
6302         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6303         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6304
6305         setup_56 $dir $NUMFILES $NUMDIRS
6306
6307         # test lfs find with ! -name
6308         for i in $(seq $NUMFILES) ; do
6309                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6310
6311                 [ $nums -eq $expected ] ||
6312                         error "lfs find ! -name '*$i' $dir wrong: "\
6313                               "found $nums, expected $expected"
6314         done
6315 }
6316 run_test 56h "check lfs find ! -name"
6317
6318 test_56i() {
6319         local dir=$DIR/$tdir
6320
6321         test_mkdir $dir
6322
6323         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6324         local out=$($cmd)
6325
6326         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6327 }
6328 run_test 56i "check 'lfs find -ost UUID' skips directories"
6329
6330 test_56j() {
6331         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6332
6333         setup_56_special $dir $NUMFILES $NUMDIRS
6334
6335         local expected=$((NUMDIRS + 1))
6336         local cmd="$LFS find -type d $dir"
6337         local nums=$($cmd | wc -l)
6338
6339         [ $nums -eq $expected ] ||
6340                 error "'$cmd' wrong: found $nums, expected $expected"
6341 }
6342 run_test 56j "check lfs find -type d"
6343
6344 test_56k() {
6345         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6346
6347         setup_56_special $dir $NUMFILES $NUMDIRS
6348
6349         local expected=$(((NUMDIRS + 1) * NUMFILES))
6350         local cmd="$LFS find -type f $dir"
6351         local nums=$($cmd | wc -l)
6352
6353         [ $nums -eq $expected ] ||
6354                 error "'$cmd' wrong: found $nums, expected $expected"
6355 }
6356 run_test 56k "check lfs find -type f"
6357
6358 test_56l() {
6359         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6360
6361         setup_56_special $dir $NUMFILES $NUMDIRS
6362
6363         local expected=$((NUMDIRS + NUMFILES))
6364         local cmd="$LFS find -type b $dir"
6365         local nums=$($cmd | wc -l)
6366
6367         [ $nums -eq $expected ] ||
6368                 error "'$cmd' wrong: found $nums, expected $expected"
6369 }
6370 run_test 56l "check lfs find -type b"
6371
6372 test_56m() {
6373         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6374
6375         setup_56_special $dir $NUMFILES $NUMDIRS
6376
6377         local expected=$((NUMDIRS + NUMFILES))
6378         local cmd="$LFS find -type c $dir"
6379         local nums=$($cmd | wc -l)
6380         [ $nums -eq $expected ] ||
6381                 error "'$cmd' wrong: found $nums, expected $expected"
6382 }
6383 run_test 56m "check lfs find -type c"
6384
6385 test_56n() {
6386         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6387         setup_56_special $dir $NUMFILES $NUMDIRS
6388
6389         local expected=$((NUMDIRS + NUMFILES))
6390         local cmd="$LFS find -type l $dir"
6391         local nums=$($cmd | wc -l)
6392
6393         [ $nums -eq $expected ] ||
6394                 error "'$cmd' wrong: found $nums, expected $expected"
6395 }
6396 run_test 56n "check lfs find -type l"
6397
6398 test_56o() {
6399         local dir=$DIR/$tdir
6400
6401         setup_56 $dir $NUMFILES $NUMDIRS
6402         utime $dir/file1 > /dev/null || error "utime (1)"
6403         utime $dir/file2 > /dev/null || error "utime (2)"
6404         utime $dir/dir1 > /dev/null || error "utime (3)"
6405         utime $dir/dir2 > /dev/null || error "utime (4)"
6406         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6407         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6408
6409         local expected=4
6410         local nums=$($LFS find -mtime +0 $dir | wc -l)
6411
6412         [ $nums -eq $expected ] ||
6413                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6414
6415         expected=12
6416         cmd="$LFS find -mtime 0 $dir"
6417         nums=$($cmd | wc -l)
6418         [ $nums -eq $expected ] ||
6419                 error "'$cmd' wrong: found $nums, expected $expected"
6420 }
6421 run_test 56o "check lfs find -mtime for old files"
6422
6423 test_56ob() {
6424         local dir=$DIR/$tdir
6425         local expected=1
6426         local count=0
6427
6428         # just to make sure there is something that won't be found
6429         test_mkdir $dir
6430         touch $dir/$tfile.now
6431
6432         for age in year week day hour min; do
6433                 count=$((count + 1))
6434
6435                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6436                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6437                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6438
6439                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6440                 local nums=$($cmd | wc -l)
6441                 [ $nums -eq $expected ] ||
6442                         error "'$cmd' wrong: found $nums, expected $expected"
6443
6444                 cmd="$LFS find $dir -atime $count${age:0:1}"
6445                 nums=$($cmd | wc -l)
6446                 [ $nums -eq $expected ] ||
6447                         error "'$cmd' wrong: found $nums, expected $expected"
6448         done
6449
6450         sleep 2
6451         cmd="$LFS find $dir -ctime +1s -type f"
6452         nums=$($cmd | wc -l)
6453         (( $nums == $count * 2 + 1)) ||
6454                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6455 }
6456 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6457
6458 test_newerXY_base() {
6459         local x=$1
6460         local y=$2
6461         local dir=$DIR/$tdir
6462         local ref
6463         local negref
6464
6465         if [ $y == "t" ]; then
6466                 if [ $x == "b" ]; then
6467                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6468                 else
6469                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6470                 fi
6471         else
6472                 ref=$DIR/$tfile.newer.$x$y
6473                 touch $ref || error "touch $ref failed"
6474         fi
6475
6476         echo "before = $ref"
6477         sleep 2
6478         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6479         sleep 2
6480         if [ $y == "t" ]; then
6481                 if [ $x == "b" ]; then
6482                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6483                 else
6484                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6485                 fi
6486         else
6487                 negref=$DIR/$tfile.negnewer.$x$y
6488                 touch $negref || error "touch $negref failed"
6489         fi
6490
6491         echo "after = $negref"
6492         local cmd="$LFS find $dir -newer$x$y $ref"
6493         local nums=$(eval $cmd | wc -l)
6494         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6495
6496         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6497                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6498
6499         cmd="$LFS find $dir ! -newer$x$y $negref"
6500         nums=$(eval $cmd | wc -l)
6501         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6502                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6503
6504         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6505         nums=$(eval $cmd | wc -l)
6506         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6507                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6508
6509         rm -rf $DIR/*
6510 }
6511
6512 test_56oc() {
6513         test_newerXY_base "a" "a"
6514         test_newerXY_base "a" "m"
6515         test_newerXY_base "a" "c"
6516         test_newerXY_base "m" "a"
6517         test_newerXY_base "m" "m"
6518         test_newerXY_base "m" "c"
6519         test_newerXY_base "c" "a"
6520         test_newerXY_base "c" "m"
6521         test_newerXY_base "c" "c"
6522
6523         [[ -n "$sles_version" ]] &&
6524                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6525
6526         test_newerXY_base "a" "t"
6527         test_newerXY_base "m" "t"
6528         test_newerXY_base "c" "t"
6529
6530         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6531            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6532                 ! btime_supported && echo "btime unsupported" && return 0
6533
6534         test_newerXY_base "b" "b"
6535         test_newerXY_base "b" "t"
6536 }
6537 run_test 56oc "check lfs find -newerXY work"
6538
6539 btime_supported() {
6540         local dir=$DIR/$tdir
6541         local rc
6542
6543         mkdir -p $dir
6544         touch $dir/$tfile
6545         $LFS find $dir -btime -1d -type f
6546         rc=$?
6547         rm -rf $dir
6548         return $rc
6549 }
6550
6551 test_56od() {
6552         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6553                 ! btime_supported && skip "btime unsupported on MDS"
6554
6555         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6556                 ! btime_supported && skip "btime unsupported on clients"
6557
6558         local dir=$DIR/$tdir
6559         local ref=$DIR/$tfile.ref
6560         local negref=$DIR/$tfile.negref
6561
6562         mkdir $dir || error "mkdir $dir failed"
6563         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6564         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6565         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6566         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6567         touch $ref || error "touch $ref failed"
6568         # sleep 3 seconds at least
6569         sleep 3
6570
6571         local before=$(do_facet mds1 date +%s)
6572         local skew=$(($(date +%s) - before + 1))
6573
6574         if (( skew < 0 && skew > -5 )); then
6575                 sleep $((0 - skew + 1))
6576                 skew=0
6577         fi
6578
6579         # Set the dir stripe params to limit files all on MDT0,
6580         # otherwise we need to calc the max clock skew between
6581         # the client and MDTs.
6582         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6583         sleep 2
6584         touch $negref || error "touch $negref failed"
6585
6586         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6587         local nums=$($cmd | wc -l)
6588         local expected=$(((NUMFILES + 1) * NUMDIRS))
6589
6590         [ $nums -eq $expected ] ||
6591                 error "'$cmd' wrong: found $nums, expected $expected"
6592
6593         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6594         nums=$($cmd | wc -l)
6595         expected=$((NUMFILES + 1))
6596         [ $nums -eq $expected ] ||
6597                 error "'$cmd' wrong: found $nums, expected $expected"
6598
6599         [ $skew -lt 0 ] && return
6600
6601         local after=$(do_facet mds1 date +%s)
6602         local age=$((after - before + 1 + skew))
6603
6604         cmd="$LFS find $dir -btime -${age}s -type f"
6605         nums=$($cmd | wc -l)
6606         expected=$(((NUMFILES + 1) * NUMDIRS))
6607
6608         echo "Clock skew between client and server: $skew, age:$age"
6609         [ $nums -eq $expected ] ||
6610                 error "'$cmd' wrong: found $nums, expected $expected"
6611
6612         expected=$(($NUMDIRS + 1))
6613         cmd="$LFS find $dir -btime -${age}s -type d"
6614         nums=$($cmd | wc -l)
6615         [ $nums -eq $expected ] ||
6616                 error "'$cmd' wrong: found $nums, expected $expected"
6617         rm -f $ref $negref || error "Failed to remove $ref $negref"
6618 }
6619 run_test 56od "check lfs find -btime with units"
6620
6621 test_56p() {
6622         [ $RUNAS_ID -eq $UID ] &&
6623                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6624
6625         local dir=$DIR/$tdir
6626
6627         setup_56 $dir $NUMFILES $NUMDIRS
6628         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6629
6630         local expected=$NUMFILES
6631         local cmd="$LFS find -uid $RUNAS_ID $dir"
6632         local nums=$($cmd | wc -l)
6633
6634         [ $nums -eq $expected ] ||
6635                 error "'$cmd' wrong: found $nums, expected $expected"
6636
6637         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6638         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6639         nums=$($cmd | wc -l)
6640         [ $nums -eq $expected ] ||
6641                 error "'$cmd' wrong: found $nums, expected $expected"
6642 }
6643 run_test 56p "check lfs find -uid and ! -uid"
6644
6645 test_56q() {
6646         [ $RUNAS_ID -eq $UID ] &&
6647                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6648
6649         local dir=$DIR/$tdir
6650
6651         setup_56 $dir $NUMFILES $NUMDIRS
6652         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6653
6654         local expected=$NUMFILES
6655         local cmd="$LFS find -gid $RUNAS_GID $dir"
6656         local nums=$($cmd | wc -l)
6657
6658         [ $nums -eq $expected ] ||
6659                 error "'$cmd' wrong: found $nums, expected $expected"
6660
6661         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6662         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6663         nums=$($cmd | wc -l)
6664         [ $nums -eq $expected ] ||
6665                 error "'$cmd' wrong: found $nums, expected $expected"
6666 }
6667 run_test 56q "check lfs find -gid and ! -gid"
6668
6669 test_56r() {
6670         local dir=$DIR/$tdir
6671
6672         setup_56 $dir $NUMFILES $NUMDIRS
6673
6674         local expected=12
6675         local cmd="$LFS find -size 0 -type f -lazy $dir"
6676         local nums=$($cmd | wc -l)
6677
6678         [ $nums -eq $expected ] ||
6679                 error "'$cmd' wrong: found $nums, expected $expected"
6680         cmd="$LFS find -size 0 -type f $dir"
6681         nums=$($cmd | wc -l)
6682         [ $nums -eq $expected ] ||
6683                 error "'$cmd' wrong: found $nums, expected $expected"
6684
6685         expected=0
6686         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6687         nums=$($cmd | wc -l)
6688         [ $nums -eq $expected ] ||
6689                 error "'$cmd' wrong: found $nums, expected $expected"
6690         cmd="$LFS find ! -size 0 -type f $dir"
6691         nums=$($cmd | wc -l)
6692         [ $nums -eq $expected ] ||
6693                 error "'$cmd' wrong: found $nums, expected $expected"
6694
6695         echo "test" > $dir/$tfile
6696         echo "test2" > $dir/$tfile.2 && sync
6697         expected=1
6698         cmd="$LFS find -size 5 -type f -lazy $dir"
6699         nums=$($cmd | wc -l)
6700         [ $nums -eq $expected ] ||
6701                 error "'$cmd' wrong: found $nums, expected $expected"
6702         cmd="$LFS find -size 5 -type f $dir"
6703         nums=$($cmd | wc -l)
6704         [ $nums -eq $expected ] ||
6705                 error "'$cmd' wrong: found $nums, expected $expected"
6706
6707         expected=1
6708         cmd="$LFS find -size +5 -type f -lazy $dir"
6709         nums=$($cmd | wc -l)
6710         [ $nums -eq $expected ] ||
6711                 error "'$cmd' wrong: found $nums, expected $expected"
6712         cmd="$LFS find -size +5 -type f $dir"
6713         nums=$($cmd | wc -l)
6714         [ $nums -eq $expected ] ||
6715                 error "'$cmd' wrong: found $nums, expected $expected"
6716
6717         expected=2
6718         cmd="$LFS find -size +0 -type f -lazy $dir"
6719         nums=$($cmd | wc -l)
6720         [ $nums -eq $expected ] ||
6721                 error "'$cmd' wrong: found $nums, expected $expected"
6722         cmd="$LFS find -size +0 -type f $dir"
6723         nums=$($cmd | wc -l)
6724         [ $nums -eq $expected ] ||
6725                 error "'$cmd' wrong: found $nums, expected $expected"
6726
6727         expected=2
6728         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6729         nums=$($cmd | wc -l)
6730         [ $nums -eq $expected ] ||
6731                 error "'$cmd' wrong: found $nums, expected $expected"
6732         cmd="$LFS find ! -size -5 -type f $dir"
6733         nums=$($cmd | wc -l)
6734         [ $nums -eq $expected ] ||
6735                 error "'$cmd' wrong: found $nums, expected $expected"
6736
6737         expected=12
6738         cmd="$LFS find -size -5 -type f -lazy $dir"
6739         nums=$($cmd | wc -l)
6740         [ $nums -eq $expected ] ||
6741                 error "'$cmd' wrong: found $nums, expected $expected"
6742         cmd="$LFS find -size -5 -type f $dir"
6743         nums=$($cmd | wc -l)
6744         [ $nums -eq $expected ] ||
6745                 error "'$cmd' wrong: found $nums, expected $expected"
6746 }
6747 run_test 56r "check lfs find -size works"
6748
6749 test_56ra_sub() {
6750         local expected=$1
6751         local glimpses=$2
6752         local cmd="$3"
6753
6754         cancel_lru_locks $OSC
6755
6756         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6757         local nums=$($cmd | wc -l)
6758
6759         [ $nums -eq $expected ] ||
6760                 error "'$cmd' wrong: found $nums, expected $expected"
6761
6762         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6763
6764         if (( rpcs_before + glimpses != rpcs_after )); then
6765                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6766                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6767
6768                 if [[ $glimpses == 0 ]]; then
6769                         error "'$cmd' should not send glimpse RPCs to OST"
6770                 else
6771                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6772                 fi
6773         fi
6774 }
6775
6776 test_56ra() {
6777         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6778                 skip "MDS < 2.12.58 doesn't return LSOM data"
6779         local dir=$DIR/$tdir
6780         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6781
6782         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6783
6784         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6785         $LCTL set_param -n llite.*.statahead_agl=0
6786         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6787
6788         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6789         # open and close all files to ensure LSOM is updated
6790         cancel_lru_locks $OSC
6791         find $dir -type f | xargs cat > /dev/null
6792
6793         #   expect_found  glimpse_rpcs  command_to_run
6794         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6795         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6796         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6797         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6798
6799         echo "test" > $dir/$tfile
6800         echo "test2" > $dir/$tfile.2 && sync
6801         cancel_lru_locks $OSC
6802         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6803
6804         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6805         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6806         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6807         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6808
6809         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6810         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6811         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6812         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6813         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6814         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6815 }
6816 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6817
6818 test_56rb() {
6819         local dir=$DIR/$tdir
6820         local tmp=$TMP/$tfile.log
6821         local mdt_idx;
6822
6823         test_mkdir -p $dir || error "failed to mkdir $dir"
6824         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6825                 error "failed to setstripe $dir/$tfile"
6826         mdt_idx=$($LFS getdirstripe -i $dir)
6827         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6828
6829         stack_trap "rm -f $tmp" EXIT
6830         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6831         ! grep -q obd_uuid $tmp ||
6832                 error "failed to find --size +100K --ost 0 $dir"
6833         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6834         ! grep -q obd_uuid $tmp ||
6835                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6836 }
6837 run_test 56rb "check lfs find --size --ost/--mdt works"
6838
6839 test_56rc() {
6840         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6841         local dir=$DIR/$tdir
6842         local found
6843
6844         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6845         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6846         (( $MDSCOUNT > 2 )) &&
6847                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6848         mkdir $dir/$tdir-{1..10}
6849         touch $dir/$tfile-{1..10}
6850
6851         found=$($LFS find $dir --mdt-count 2 | wc -l)
6852         expect=11
6853         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6854
6855         found=$($LFS find $dir -T +1 | wc -l)
6856         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6857         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6858
6859         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6860         expect=11
6861         (( $found == $expect )) || error "found $found all_char, expect $expect"
6862
6863         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
6864         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
6865         (( $found == $expect )) || error "found $found all_char, expect $expect"
6866 }
6867 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
6868
6869 test_56s() { # LU-611 #LU-9369
6870         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6871
6872         local dir=$DIR/$tdir
6873         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6874
6875         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6876         for i in $(seq $NUMDIRS); do
6877                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6878         done
6879
6880         local expected=$NUMDIRS
6881         local cmd="$LFS find -c $OSTCOUNT $dir"
6882         local nums=$($cmd | wc -l)
6883
6884         [ $nums -eq $expected ] || {
6885                 $LFS getstripe -R $dir
6886                 error "'$cmd' wrong: found $nums, expected $expected"
6887         }
6888
6889         expected=$((NUMDIRS + onestripe))
6890         cmd="$LFS find -stripe-count +0 -type f $dir"
6891         nums=$($cmd | wc -l)
6892         [ $nums -eq $expected ] || {
6893                 $LFS getstripe -R $dir
6894                 error "'$cmd' wrong: found $nums, expected $expected"
6895         }
6896
6897         expected=$onestripe
6898         cmd="$LFS find -stripe-count 1 -type f $dir"
6899         nums=$($cmd | wc -l)
6900         [ $nums -eq $expected ] || {
6901                 $LFS getstripe -R $dir
6902                 error "'$cmd' wrong: found $nums, expected $expected"
6903         }
6904
6905         cmd="$LFS find -stripe-count -2 -type f $dir"
6906         nums=$($cmd | wc -l)
6907         [ $nums -eq $expected ] || {
6908                 $LFS getstripe -R $dir
6909                 error "'$cmd' wrong: found $nums, expected $expected"
6910         }
6911
6912         expected=0
6913         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6914         nums=$($cmd | wc -l)
6915         [ $nums -eq $expected ] || {
6916                 $LFS getstripe -R $dir
6917                 error "'$cmd' wrong: found $nums, expected $expected"
6918         }
6919 }
6920 run_test 56s "check lfs find -stripe-count works"
6921
6922 test_56t() { # LU-611 #LU-9369
6923         local dir=$DIR/$tdir
6924
6925         setup_56 $dir 0 $NUMDIRS
6926         for i in $(seq $NUMDIRS); do
6927                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6928         done
6929
6930         local expected=$NUMDIRS
6931         local cmd="$LFS find -S 8M $dir"
6932         local nums=$($cmd | wc -l)
6933
6934         [ $nums -eq $expected ] || {
6935                 $LFS getstripe -R $dir
6936                 error "'$cmd' wrong: found $nums, expected $expected"
6937         }
6938         rm -rf $dir
6939
6940         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6941
6942         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6943
6944         expected=$(((NUMDIRS + 1) * NUMFILES))
6945         cmd="$LFS find -stripe-size 512k -type f $dir"
6946         nums=$($cmd | wc -l)
6947         [ $nums -eq $expected ] ||
6948                 error "'$cmd' wrong: found $nums, expected $expected"
6949
6950         cmd="$LFS find -stripe-size +320k -type f $dir"
6951         nums=$($cmd | wc -l)
6952         [ $nums -eq $expected ] ||
6953                 error "'$cmd' wrong: found $nums, expected $expected"
6954
6955         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6956         cmd="$LFS find -stripe-size +200k -type f $dir"
6957         nums=$($cmd | wc -l)
6958         [ $nums -eq $expected ] ||
6959                 error "'$cmd' wrong: found $nums, expected $expected"
6960
6961         cmd="$LFS find -stripe-size -640k -type f $dir"
6962         nums=$($cmd | wc -l)
6963         [ $nums -eq $expected ] ||
6964                 error "'$cmd' wrong: found $nums, expected $expected"
6965
6966         expected=4
6967         cmd="$LFS find -stripe-size 256k -type f $dir"
6968         nums=$($cmd | wc -l)
6969         [ $nums -eq $expected ] ||
6970                 error "'$cmd' wrong: found $nums, expected $expected"
6971
6972         cmd="$LFS find -stripe-size -320k -type f $dir"
6973         nums=$($cmd | wc -l)
6974         [ $nums -eq $expected ] ||
6975                 error "'$cmd' wrong: found $nums, expected $expected"
6976
6977         expected=0
6978         cmd="$LFS find -stripe-size 1024k -type f $dir"
6979         nums=$($cmd | wc -l)
6980         [ $nums -eq $expected ] ||
6981                 error "'$cmd' wrong: found $nums, expected $expected"
6982 }
6983 run_test 56t "check lfs find -stripe-size works"
6984
6985 test_56u() { # LU-611
6986         local dir=$DIR/$tdir
6987
6988         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6989
6990         if [[ $OSTCOUNT -gt 1 ]]; then
6991                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6992                 onestripe=4
6993         else
6994                 onestripe=0
6995         fi
6996
6997         local expected=$(((NUMDIRS + 1) * NUMFILES))
6998         local cmd="$LFS find -stripe-index 0 -type f $dir"
6999         local nums=$($cmd | wc -l)
7000
7001         [ $nums -eq $expected ] ||
7002                 error "'$cmd' wrong: found $nums, expected $expected"
7003
7004         expected=$onestripe
7005         cmd="$LFS find -stripe-index 1 -type f $dir"
7006         nums=$($cmd | wc -l)
7007         [ $nums -eq $expected ] ||
7008                 error "'$cmd' wrong: found $nums, expected $expected"
7009
7010         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7011         nums=$($cmd | wc -l)
7012         [ $nums -eq $expected ] ||
7013                 error "'$cmd' wrong: found $nums, expected $expected"
7014
7015         expected=0
7016         # This should produce an error and not return any files
7017         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7018         nums=$($cmd 2>/dev/null | wc -l)
7019         [ $nums -eq $expected ] ||
7020                 error "'$cmd' wrong: found $nums, expected $expected"
7021
7022         if [[ $OSTCOUNT -gt 1 ]]; then
7023                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7024                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7025                 nums=$($cmd | wc -l)
7026                 [ $nums -eq $expected ] ||
7027                         error "'$cmd' wrong: found $nums, expected $expected"
7028         fi
7029 }
7030 run_test 56u "check lfs find -stripe-index works"
7031
7032 test_56v() {
7033         local mdt_idx=0
7034         local dir=$DIR/$tdir
7035
7036         setup_56 $dir $NUMFILES $NUMDIRS
7037
7038         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7039         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7040
7041         for file in $($LFS find -m $UUID $dir); do
7042                 file_midx=$($LFS getstripe -m $file)
7043                 [ $file_midx -eq $mdt_idx ] ||
7044                         error "lfs find -m $UUID != getstripe -m $file_midx"
7045         done
7046 }
7047 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7048
7049 test_56w() {
7050         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7052
7053         local dir=$DIR/$tdir
7054
7055         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7056
7057         local stripe_size=$($LFS getstripe -S -d $dir) ||
7058                 error "$LFS getstripe -S -d $dir failed"
7059         stripe_size=${stripe_size%% *}
7060
7061         local file_size=$((stripe_size * OSTCOUNT))
7062         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7063         local required_space=$((file_num * file_size))
7064         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7065                            head -n1)
7066         [[ $free_space -le $((required_space / 1024)) ]] &&
7067                 skip_env "need $required_space, have $free_space kbytes"
7068
7069         local dd_bs=65536
7070         local dd_count=$((file_size / dd_bs))
7071
7072         # write data into the files
7073         local i
7074         local j
7075         local file
7076
7077         for i in $(seq $NUMFILES); do
7078                 file=$dir/file$i
7079                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7080                         error "write data into $file failed"
7081         done
7082         for i in $(seq $NUMDIRS); do
7083                 for j in $(seq $NUMFILES); do
7084                         file=$dir/dir$i/file$j
7085                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7086                                 error "write data into $file failed"
7087                 done
7088         done
7089
7090         # $LFS_MIGRATE will fail if hard link migration is unsupported
7091         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7092                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7093                         error "creating links to $dir/dir1/file1 failed"
7094         fi
7095
7096         local expected=-1
7097
7098         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7099
7100         # lfs_migrate file
7101         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7102
7103         echo "$cmd"
7104         eval $cmd || error "$cmd failed"
7105
7106         check_stripe_count $dir/file1 $expected
7107
7108         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7109         then
7110                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7111                 # OST 1 if it is on OST 0. This file is small enough to
7112                 # be on only one stripe.
7113                 file=$dir/migr_1_ost
7114                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7115                         error "write data into $file failed"
7116                 local obdidx=$($LFS getstripe -i $file)
7117                 local oldmd5=$(md5sum $file)
7118                 local newobdidx=0
7119
7120                 [[ $obdidx -eq 0 ]] && newobdidx=1
7121                 cmd="$LFS migrate -i $newobdidx $file"
7122                 echo $cmd
7123                 eval $cmd || error "$cmd failed"
7124
7125                 local realobdix=$($LFS getstripe -i $file)
7126                 local newmd5=$(md5sum $file)
7127
7128                 [[ $newobdidx -ne $realobdix ]] &&
7129                         error "new OST is different (was=$obdidx, "\
7130                               "wanted=$newobdidx, got=$realobdix)"
7131                 [[ "$oldmd5" != "$newmd5" ]] &&
7132                         error "md5sum differ: $oldmd5, $newmd5"
7133         fi
7134
7135         # lfs_migrate dir
7136         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7137         echo "$cmd"
7138         eval $cmd || error "$cmd failed"
7139
7140         for j in $(seq $NUMFILES); do
7141                 check_stripe_count $dir/dir1/file$j $expected
7142         done
7143
7144         # lfs_migrate works with lfs find
7145         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7146              $LFS_MIGRATE -y -c $expected"
7147         echo "$cmd"
7148         eval $cmd || error "$cmd failed"
7149
7150         for i in $(seq 2 $NUMFILES); do
7151                 check_stripe_count $dir/file$i $expected
7152         done
7153         for i in $(seq 2 $NUMDIRS); do
7154                 for j in $(seq $NUMFILES); do
7155                 check_stripe_count $dir/dir$i/file$j $expected
7156                 done
7157         done
7158 }
7159 run_test 56w "check lfs_migrate -c stripe_count works"
7160
7161 test_56wb() {
7162         local file1=$DIR/$tdir/file1
7163         local create_pool=false
7164         local initial_pool=$($LFS getstripe -p $DIR)
7165         local pool_list=()
7166         local pool=""
7167
7168         echo -n "Creating test dir..."
7169         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7170         echo "done."
7171
7172         echo -n "Creating test file..."
7173         touch $file1 || error "cannot create file"
7174         echo "done."
7175
7176         echo -n "Detecting existing pools..."
7177         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7178
7179         if [ ${#pool_list[@]} -gt 0 ]; then
7180                 echo "${pool_list[@]}"
7181                 for thispool in "${pool_list[@]}"; do
7182                         if [[ -z "$initial_pool" ||
7183                               "$initial_pool" != "$thispool" ]]; then
7184                                 pool="$thispool"
7185                                 echo "Using existing pool '$pool'"
7186                                 break
7187                         fi
7188                 done
7189         else
7190                 echo "none detected."
7191         fi
7192         if [ -z "$pool" ]; then
7193                 pool=${POOL:-testpool}
7194                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7195                 echo -n "Creating pool '$pool'..."
7196                 create_pool=true
7197                 pool_add $pool &> /dev/null ||
7198                         error "pool_add failed"
7199                 echo "done."
7200
7201                 echo -n "Adding target to pool..."
7202                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7203                         error "pool_add_targets failed"
7204                 echo "done."
7205         fi
7206
7207         echo -n "Setting pool using -p option..."
7208         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7209                 error "migrate failed rc = $?"
7210         echo "done."
7211
7212         echo -n "Verifying test file is in pool after migrating..."
7213         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7214                 error "file was not migrated to pool $pool"
7215         echo "done."
7216
7217         echo -n "Removing test file from pool '$pool'..."
7218         # "lfs migrate $file" won't remove the file from the pool
7219         # until some striping information is changed.
7220         $LFS migrate -c 1 $file1 &> /dev/null ||
7221                 error "cannot remove from pool"
7222         [ "$($LFS getstripe -p $file1)" ] &&
7223                 error "pool still set"
7224         echo "done."
7225
7226         echo -n "Setting pool using --pool option..."
7227         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7228                 error "migrate failed rc = $?"
7229         echo "done."
7230
7231         # Clean up
7232         rm -f $file1
7233         if $create_pool; then
7234                 destroy_test_pools 2> /dev/null ||
7235                         error "destroy test pools failed"
7236         fi
7237 }
7238 run_test 56wb "check lfs_migrate pool support"
7239
7240 test_56wc() {
7241         local file1="$DIR/$tdir/file1"
7242         local parent_ssize
7243         local parent_scount
7244         local cur_ssize
7245         local cur_scount
7246         local orig_ssize
7247
7248         echo -n "Creating test dir..."
7249         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7250         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7251                 error "cannot set stripe by '-S 1M -c 1'"
7252         echo "done"
7253
7254         echo -n "Setting initial stripe for test file..."
7255         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7256                 error "cannot set stripe"
7257         cur_ssize=$($LFS getstripe -S "$file1")
7258         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7259         echo "done."
7260
7261         # File currently set to -S 512K -c 1
7262
7263         # Ensure -c and -S options are rejected when -R is set
7264         echo -n "Verifying incompatible options are detected..."
7265         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7266                 error "incompatible -c and -R options not detected"
7267         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7268                 error "incompatible -S and -R options not detected"
7269         echo "done."
7270
7271         # Ensure unrecognized options are passed through to 'lfs migrate'
7272         echo -n "Verifying -S option is passed through to lfs migrate..."
7273         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7274                 error "migration failed"
7275         cur_ssize=$($LFS getstripe -S "$file1")
7276         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7277         echo "done."
7278
7279         # File currently set to -S 1M -c 1
7280
7281         # Ensure long options are supported
7282         echo -n "Verifying long options supported..."
7283         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7284                 error "long option without argument not supported"
7285         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7286                 error "long option with argument not supported"
7287         cur_ssize=$($LFS getstripe -S "$file1")
7288         [ $cur_ssize -eq 524288 ] ||
7289                 error "migrate --stripe-size $cur_ssize != 524288"
7290         echo "done."
7291
7292         # File currently set to -S 512K -c 1
7293
7294         if [ "$OSTCOUNT" -gt 1 ]; then
7295                 echo -n "Verifying explicit stripe count can be set..."
7296                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7297                         error "migrate failed"
7298                 cur_scount=$($LFS getstripe -c "$file1")
7299                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7300                 echo "done."
7301         fi
7302
7303         # File currently set to -S 512K -c 1 or -S 512K -c 2
7304
7305         # Ensure parent striping is used if -R is set, and no stripe
7306         # count or size is specified
7307         echo -n "Setting stripe for parent directory..."
7308         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7309                 error "cannot set stripe '-S 2M -c 1'"
7310         echo "done."
7311
7312         echo -n "Verifying restripe option uses parent stripe settings..."
7313         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7314         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7315         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7316                 error "migrate failed"
7317         cur_ssize=$($LFS getstripe -S "$file1")
7318         [ $cur_ssize -eq $parent_ssize ] ||
7319                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7320         cur_scount=$($LFS getstripe -c "$file1")
7321         [ $cur_scount -eq $parent_scount ] ||
7322                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7323         echo "done."
7324
7325         # File currently set to -S 1M -c 1
7326
7327         # Ensure striping is preserved if -R is not set, and no stripe
7328         # count or size is specified
7329         echo -n "Verifying striping size preserved when not specified..."
7330         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7331         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7332                 error "cannot set stripe on parent directory"
7333         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7334                 error "migrate failed"
7335         cur_ssize=$($LFS getstripe -S "$file1")
7336         [ $cur_ssize -eq $orig_ssize ] ||
7337                 error "migrate by default $cur_ssize != $orig_ssize"
7338         echo "done."
7339
7340         # Ensure file name properly detected when final option has no argument
7341         echo -n "Verifying file name properly detected..."
7342         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7343                 error "file name interpreted as option argument"
7344         echo "done."
7345
7346         # Clean up
7347         rm -f "$file1"
7348 }
7349 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7350
7351 test_56wd() {
7352         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7353
7354         local file1=$DIR/$tdir/file1
7355
7356         echo -n "Creating test dir..."
7357         test_mkdir $DIR/$tdir || error "cannot create dir"
7358         echo "done."
7359
7360         echo -n "Creating test file..."
7361         touch $file1
7362         echo "done."
7363
7364         # Ensure 'lfs migrate' will fail by using a non-existent option,
7365         # and make sure rsync is not called to recover
7366         echo -n "Make sure --no-rsync option works..."
7367         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7368                 grep -q 'refusing to fall back to rsync' ||
7369                 error "rsync was called with --no-rsync set"
7370         echo "done."
7371
7372         # Ensure rsync is called without trying 'lfs migrate' first
7373         echo -n "Make sure --rsync option works..."
7374         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7375                 grep -q 'falling back to rsync' &&
7376                 error "lfs migrate was called with --rsync set"
7377         echo "done."
7378
7379         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7380         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7381                 grep -q 'at the same time' ||
7382                 error "--rsync and --no-rsync accepted concurrently"
7383         echo "done."
7384
7385         # Clean up
7386         rm -f $file1
7387 }
7388 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7389
7390 test_56we() {
7391         local td=$DIR/$tdir
7392         local tf=$td/$tfile
7393
7394         test_mkdir $td || error "cannot create $td"
7395         touch $tf || error "cannot touch $tf"
7396
7397         echo -n "Make sure --non-direct|-D works..."
7398         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7399                 grep -q "lfs migrate --non-direct" ||
7400                 error "--non-direct option cannot work correctly"
7401         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7402                 grep -q "lfs migrate -D" ||
7403                 error "-D option cannot work correctly"
7404         echo "done."
7405 }
7406 run_test 56we "check lfs_migrate --non-direct|-D support"
7407
7408 test_56x() {
7409         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7410         check_swap_layouts_support
7411
7412         local dir=$DIR/$tdir
7413         local ref1=/etc/passwd
7414         local file1=$dir/file1
7415
7416         test_mkdir $dir || error "creating dir $dir"
7417         $LFS setstripe -c 2 $file1
7418         cp $ref1 $file1
7419         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7420         stripe=$($LFS getstripe -c $file1)
7421         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7422         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7423
7424         # clean up
7425         rm -f $file1
7426 }
7427 run_test 56x "lfs migration support"
7428
7429 test_56xa() {
7430         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7431         check_swap_layouts_support
7432
7433         local dir=$DIR/$tdir/$testnum
7434
7435         test_mkdir -p $dir
7436
7437         local ref1=/etc/passwd
7438         local file1=$dir/file1
7439
7440         $LFS setstripe -c 2 $file1
7441         cp $ref1 $file1
7442         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7443
7444         local stripe=$($LFS getstripe -c $file1)
7445
7446         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7447         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7448
7449         # clean up
7450         rm -f $file1
7451 }
7452 run_test 56xa "lfs migration --block support"
7453
7454 check_migrate_links() {
7455         local dir="$1"
7456         local file1="$dir/file1"
7457         local begin="$2"
7458         local count="$3"
7459         local runas="$4"
7460         local total_count=$(($begin + $count - 1))
7461         local symlink_count=10
7462         local uniq_count=10
7463
7464         if [ ! -f "$file1" ]; then
7465                 echo -n "creating initial file..."
7466                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7467                         error "cannot setstripe initial file"
7468                 echo "done"
7469
7470                 echo -n "creating symlinks..."
7471                 for s in $(seq 1 $symlink_count); do
7472                         ln -s "$file1" "$dir/slink$s" ||
7473                                 error "cannot create symlinks"
7474                 done
7475                 echo "done"
7476
7477                 echo -n "creating nonlinked files..."
7478                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7479                         error "cannot create nonlinked files"
7480                 echo "done"
7481         fi
7482
7483         # create hard links
7484         if [ ! -f "$dir/file$total_count" ]; then
7485                 echo -n "creating hard links $begin:$total_count..."
7486                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7487                         /dev/null || error "cannot create hard links"
7488                 echo "done"
7489         fi
7490
7491         echo -n "checking number of hard links listed in xattrs..."
7492         local fid=$($LFS getstripe -F "$file1")
7493         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7494
7495         echo "${#paths[*]}"
7496         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7497                         skip "hard link list has unexpected size, skipping test"
7498         fi
7499         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7500                         error "link names should exceed xattrs size"
7501         fi
7502
7503         echo -n "migrating files..."
7504         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7505         local rc=$?
7506         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7507         echo "done"
7508
7509         # make sure all links have been properly migrated
7510         echo -n "verifying files..."
7511         fid=$($LFS getstripe -F "$file1") ||
7512                 error "cannot get fid for file $file1"
7513         for i in $(seq 2 $total_count); do
7514                 local fid2=$($LFS getstripe -F $dir/file$i)
7515
7516                 [ "$fid2" == "$fid" ] ||
7517                         error "migrated hard link has mismatched FID"
7518         done
7519
7520         # make sure hard links were properly detected, and migration was
7521         # performed only once for the entire link set; nonlinked files should
7522         # also be migrated
7523         local actual=$(grep -c 'done' <<< "$migrate_out")
7524         local expected=$(($uniq_count + 1))
7525
7526         [ "$actual" -eq  "$expected" ] ||
7527                 error "hard links individually migrated ($actual != $expected)"
7528
7529         # make sure the correct number of hard links are present
7530         local hardlinks=$(stat -c '%h' "$file1")
7531
7532         [ $hardlinks -eq $total_count ] ||
7533                 error "num hard links $hardlinks != $total_count"
7534         echo "done"
7535
7536         return 0
7537 }
7538
7539 test_56xb() {
7540         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7541                 skip "Need MDS version at least 2.10.55"
7542
7543         local dir="$DIR/$tdir"
7544
7545         test_mkdir "$dir" || error "cannot create dir $dir"
7546
7547         echo "testing lfs migrate mode when all links fit within xattrs"
7548         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7549
7550         echo "testing rsync mode when all links fit within xattrs"
7551         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7552
7553         echo "testing lfs migrate mode when all links do not fit within xattrs"
7554         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7555
7556         echo "testing rsync mode when all links do not fit within xattrs"
7557         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7558
7559         chown -R $RUNAS_ID $dir
7560         echo "testing non-root lfs migrate mode when not all links are in xattr"
7561         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7562
7563         # clean up
7564         rm -rf $dir
7565 }
7566 run_test 56xb "lfs migration hard link support"
7567
7568 test_56xc() {
7569         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7570
7571         local dir="$DIR/$tdir"
7572
7573         test_mkdir "$dir" || error "cannot create dir $dir"
7574
7575         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7576         echo -n "Setting initial stripe for 20MB test file..."
7577         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7578                 error "cannot setstripe 20MB file"
7579         echo "done"
7580         echo -n "Sizing 20MB test file..."
7581         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7582         echo "done"
7583         echo -n "Verifying small file autostripe count is 1..."
7584         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7585                 error "cannot migrate 20MB file"
7586         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7587                 error "cannot get stripe for $dir/20mb"
7588         [ $stripe_count -eq 1 ] ||
7589                 error "unexpected stripe count $stripe_count for 20MB file"
7590         rm -f "$dir/20mb"
7591         echo "done"
7592
7593         # Test 2: File is small enough to fit within the available space on
7594         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7595         # have at least an additional 1KB for each desired stripe for test 3
7596         echo -n "Setting stripe for 1GB test file..."
7597         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7598         echo "done"
7599         echo -n "Sizing 1GB test file..."
7600         # File size is 1GB + 3KB
7601         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7602         echo "done"
7603
7604         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7605         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7606         if (( avail > 524288 * OSTCOUNT )); then
7607                 echo -n "Migrating 1GB file..."
7608                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7609                         error "cannot migrate 1GB file"
7610                 echo "done"
7611                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7612                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7613                         error "cannot getstripe for 1GB file"
7614                 [ $stripe_count -eq 2 ] ||
7615                         error "unexpected stripe count $stripe_count != 2"
7616                 echo "done"
7617         fi
7618
7619         # Test 3: File is too large to fit within the available space on
7620         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7621         if [ $OSTCOUNT -ge 3 ]; then
7622                 # The required available space is calculated as
7623                 # file size (1GB + 3KB) / OST count (3).
7624                 local kb_per_ost=349526
7625
7626                 echo -n "Migrating 1GB file with limit..."
7627                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7628                         error "cannot migrate 1GB file with limit"
7629                 echo "done"
7630
7631                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7632                 echo -n "Verifying 1GB autostripe count with limited space..."
7633                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7634                         error "unexpected stripe count $stripe_count (min 3)"
7635                 echo "done"
7636         fi
7637
7638         # clean up
7639         rm -rf $dir
7640 }
7641 run_test 56xc "lfs migration autostripe"
7642
7643 test_56xd() {
7644         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7645
7646         local dir=$DIR/$tdir
7647         local f_mgrt=$dir/$tfile.mgrt
7648         local f_yaml=$dir/$tfile.yaml
7649         local f_copy=$dir/$tfile.copy
7650         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7651         local layout_copy="-c 2 -S 2M -i 1"
7652         local yamlfile=$dir/yamlfile
7653         local layout_before;
7654         local layout_after;
7655
7656         test_mkdir "$dir" || error "cannot create dir $dir"
7657         $LFS setstripe $layout_yaml $f_yaml ||
7658                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7659         $LFS getstripe --yaml $f_yaml > $yamlfile
7660         $LFS setstripe $layout_copy $f_copy ||
7661                 error "cannot setstripe $f_copy with layout $layout_copy"
7662         touch $f_mgrt
7663         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7664
7665         # 1. test option --yaml
7666         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7667                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7668         layout_before=$(get_layout_param $f_yaml)
7669         layout_after=$(get_layout_param $f_mgrt)
7670         [ "$layout_after" == "$layout_before" ] ||
7671                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7672
7673         # 2. test option --copy
7674         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7675                 error "cannot migrate $f_mgrt with --copy $f_copy"
7676         layout_before=$(get_layout_param $f_copy)
7677         layout_after=$(get_layout_param $f_mgrt)
7678         [ "$layout_after" == "$layout_before" ] ||
7679                 error "lfs_migrate --copy: $layout_after != $layout_before"
7680 }
7681 run_test 56xd "check lfs_migrate --yaml and --copy support"
7682
7683 test_56xe() {
7684         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7685
7686         local dir=$DIR/$tdir
7687         local f_comp=$dir/$tfile
7688         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7689         local layout_before=""
7690         local layout_after=""
7691
7692         test_mkdir "$dir" || error "cannot create dir $dir"
7693         $LFS setstripe $layout $f_comp ||
7694                 error "cannot setstripe $f_comp with layout $layout"
7695         layout_before=$(get_layout_param $f_comp)
7696         dd if=/dev/zero of=$f_comp bs=1M count=4
7697
7698         # 1. migrate a comp layout file by lfs_migrate
7699         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7700         layout_after=$(get_layout_param $f_comp)
7701         [ "$layout_before" == "$layout_after" ] ||
7702                 error "lfs_migrate: $layout_before != $layout_after"
7703
7704         # 2. migrate a comp layout file by lfs migrate
7705         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7706         layout_after=$(get_layout_param $f_comp)
7707         [ "$layout_before" == "$layout_after" ] ||
7708                 error "lfs migrate: $layout_before != $layout_after"
7709 }
7710 run_test 56xe "migrate a composite layout file"
7711
7712 test_56xf() {
7713         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7714
7715         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7716                 skip "Need server version at least 2.13.53"
7717
7718         local dir=$DIR/$tdir
7719         local f_comp=$dir/$tfile
7720         local layout="-E 1M -c1 -E -1 -c2"
7721         local fid_before=""
7722         local fid_after=""
7723
7724         test_mkdir "$dir" || error "cannot create dir $dir"
7725         $LFS setstripe $layout $f_comp ||
7726                 error "cannot setstripe $f_comp with layout $layout"
7727         fid_before=$($LFS getstripe --fid $f_comp)
7728         dd if=/dev/zero of=$f_comp bs=1M count=4
7729
7730         # 1. migrate a comp layout file to a comp layout
7731         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7732         fid_after=$($LFS getstripe --fid $f_comp)
7733         [ "$fid_before" == "$fid_after" ] ||
7734                 error "comp-to-comp migrate: $fid_before != $fid_after"
7735
7736         # 2. migrate a comp layout file to a plain layout
7737         $LFS migrate -c2 $f_comp ||
7738                 error "cannot migrate $f_comp by lfs migrate"
7739         fid_after=$($LFS getstripe --fid $f_comp)
7740         [ "$fid_before" == "$fid_after" ] ||
7741                 error "comp-to-plain migrate: $fid_before != $fid_after"
7742
7743         # 3. migrate a plain layout file to a comp layout
7744         $LFS migrate $layout $f_comp ||
7745                 error "cannot migrate $f_comp by lfs migrate"
7746         fid_after=$($LFS getstripe --fid $f_comp)
7747         [ "$fid_before" == "$fid_after" ] ||
7748                 error "plain-to-comp migrate: $fid_before != $fid_after"
7749 }
7750 run_test 56xf "FID is not lost during migration of a composite layout file"
7751
7752 check_file_ost_range() {
7753         local file="$1"
7754         shift
7755         local range="$*"
7756         local -a file_range
7757         local idx
7758
7759         file_range=($($LFS getstripe -y "$file" |
7760                 awk '/l_ost_idx:/ { print $NF }'))
7761
7762         if [[ "${#file_range[@]}" = 0 ]]; then
7763                 echo "No osts found for $file"
7764                 return 1
7765         fi
7766
7767         for idx in "${file_range[@]}"; do
7768                 [[ " $range " =~ " $idx " ]] ||
7769                         return 1
7770         done
7771
7772         return 0
7773 }
7774
7775 sub_test_56xg() {
7776         local stripe_opt="$1"
7777         local pool="$2"
7778         shift 2
7779         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7780
7781         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7782                 error "Fail to migrate $tfile on $pool"
7783         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7784                 error "$tfile is not in pool $pool"
7785         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7786                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7787 }
7788
7789 test_56xg() {
7790         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7791         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7792         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7793                 skip "Need MDS version newer than 2.14.52"
7794
7795         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7796         local -a pool_ranges=("0 0" "1 1" "0 1")
7797
7798         # init pools
7799         for i in "${!pool_names[@]}"; do
7800                 pool_add ${pool_names[$i]} ||
7801                         error "pool_add failed (pool: ${pool_names[$i]})"
7802                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7803                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7804         done
7805
7806         # init the file to migrate
7807         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7808                 error "Unable to create $tfile on OST1"
7809         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7810                 error "Unable to write on $tfile"
7811
7812         echo "1. migrate $tfile on pool ${pool_names[0]}"
7813         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7814
7815         echo "2. migrate $tfile on pool ${pool_names[2]}"
7816         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7817
7818         echo "3. migrate $tfile on pool ${pool_names[1]}"
7819         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7820
7821         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7822         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7823         echo
7824
7825         # Clean pools
7826         destroy_test_pools ||
7827                 error "pool_destroy failed"
7828 }
7829 run_test 56xg "lfs migrate pool support"
7830
7831 test_56y() {
7832         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7833                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7834
7835         local res=""
7836         local dir=$DIR/$tdir
7837         local f1=$dir/file1
7838         local f2=$dir/file2
7839
7840         test_mkdir -p $dir || error "creating dir $dir"
7841         touch $f1 || error "creating std file $f1"
7842         $MULTIOP $f2 H2c || error "creating released file $f2"
7843
7844         # a directory can be raid0, so ask only for files
7845         res=$($LFS find $dir -L raid0 -type f | wc -l)
7846         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7847
7848         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7849         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7850
7851         # only files can be released, so no need to force file search
7852         res=$($LFS find $dir -L released)
7853         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7854
7855         res=$($LFS find $dir -type f \! -L released)
7856         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7857 }
7858 run_test 56y "lfs find -L raid0|released"
7859
7860 test_56z() { # LU-4824
7861         # This checks to make sure 'lfs find' continues after errors
7862         # There are two classes of errors that should be caught:
7863         # - If multiple paths are provided, all should be searched even if one
7864         #   errors out
7865         # - If errors are encountered during the search, it should not terminate
7866         #   early
7867         local dir=$DIR/$tdir
7868         local i
7869
7870         test_mkdir $dir
7871         for i in d{0..9}; do
7872                 test_mkdir $dir/$i
7873                 touch $dir/$i/$tfile
7874         done
7875         $LFS find $DIR/non_existent_dir $dir &&
7876                 error "$LFS find did not return an error"
7877         # Make a directory unsearchable. This should NOT be the last entry in
7878         # directory order.  Arbitrarily pick the 6th entry
7879         chmod 700 $($LFS find $dir -type d | sed '6!d')
7880
7881         $RUNAS $LFS find $DIR/non_existent $dir
7882         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7883
7884         # The user should be able to see 10 directories and 9 files
7885         (( count == 19 )) ||
7886                 error "$LFS find found $count != 19 entries after error"
7887 }
7888 run_test 56z "lfs find should continue after an error"
7889
7890 test_56aa() { # LU-5937
7891         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7892
7893         local dir=$DIR/$tdir
7894
7895         mkdir $dir
7896         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7897
7898         createmany -o $dir/striped_dir/${tfile}- 1024
7899         local dirs=$($LFS find --size +8k $dir/)
7900
7901         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7902 }
7903 run_test 56aa "lfs find --size under striped dir"
7904
7905 test_56ab() { # LU-10705
7906         test_mkdir $DIR/$tdir
7907         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7908         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7909         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7910         # Flush writes to ensure valid blocks.  Need to be more thorough for
7911         # ZFS, since blocks are not allocated/returned to client immediately.
7912         sync_all_data
7913         wait_zfs_commit ost1 2
7914         cancel_lru_locks osc
7915         ls -ls $DIR/$tdir
7916
7917         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7918
7919         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7920
7921         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7922         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7923
7924         rm -f $DIR/$tdir/$tfile.[123]
7925 }
7926 run_test 56ab "lfs find --blocks"
7927
7928 # LU-11188
7929 test_56aca() {
7930         local dir="$DIR/$tdir"
7931         local perms=(001 002 003 004 005 006 007
7932                      010 020 030 040 050 060 070
7933                      100 200 300 400 500 600 700
7934                      111 222 333 444 555 666 777)
7935         local perm_minus=(8 8 4 8 4 4 2
7936                           8 8 4 8 4 4 2
7937                           8 8 4 8 4 4 2
7938                           4 4 2 4 2 2 1)
7939         local perm_slash=(8  8 12  8 12 12 14
7940                           8  8 12  8 12 12 14
7941                           8  8 12  8 12 12 14
7942                          16 16 24 16 24 24 28)
7943
7944         test_mkdir "$dir"
7945         for perm in ${perms[*]}; do
7946                 touch "$dir/$tfile.$perm"
7947                 chmod $perm "$dir/$tfile.$perm"
7948         done
7949
7950         for ((i = 0; i < ${#perms[*]}; i++)); do
7951                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7952                 (( $num == 1 )) ||
7953                         error "lfs find -perm ${perms[i]}:"\
7954                               "$num != 1"
7955
7956                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7957                 (( $num == ${perm_minus[i]} )) ||
7958                         error "lfs find -perm -${perms[i]}:"\
7959                               "$num != ${perm_minus[i]}"
7960
7961                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7962                 (( $num == ${perm_slash[i]} )) ||
7963                         error "lfs find -perm /${perms[i]}:"\
7964                               "$num != ${perm_slash[i]}"
7965         done
7966 }
7967 run_test 56aca "check lfs find -perm with octal representation"
7968
7969 test_56acb() {
7970         local dir=$DIR/$tdir
7971         # p is the permission of write and execute for user, group and other
7972         # without the umask. It is used to test +wx.
7973         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7974         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7975         local symbolic=(+t  a+t u+t g+t o+t
7976                         g+s u+s o+s +s o+sr
7977                         o=r,ug+o,u+w
7978                         u+ g+ o+ a+ ugo+
7979                         u- g- o- a- ugo-
7980                         u= g= o= a= ugo=
7981                         o=r,ug+o,u+w u=r,a+u,u+w
7982                         g=r,ugo=g,u+w u+x,+X +X
7983                         u+x,u+X u+X u+x,g+X o+r,+X
7984                         u+x,go+X +wx +rwx)
7985
7986         test_mkdir $dir
7987         for perm in ${perms[*]}; do
7988                 touch "$dir/$tfile.$perm"
7989                 chmod $perm "$dir/$tfile.$perm"
7990         done
7991
7992         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
7993                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
7994
7995                 (( $num == 1 )) ||
7996                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
7997         done
7998 }
7999 run_test 56acb "check lfs find -perm with symbolic representation"
8000
8001 test_56acc() {
8002         local dir=$DIR/$tdir
8003         local tests="17777 787 789 abcd
8004                 ug=uu ug=a ug=gu uo=ou urw
8005                 u+xg+x a=r,u+x,"
8006
8007         test_mkdir $dir
8008         for err in $tests; do
8009                 if $LFS find $dir -perm $err 2>/dev/null; then
8010                         error "lfs find -perm $err: parsing should have failed"
8011                 fi
8012         done
8013 }
8014 run_test 56acc "check parsing error for lfs find -perm"
8015
8016 test_56ba() {
8017         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8018                 skip "Need MDS version at least 2.10.50"
8019
8020         # Create composite files with one component
8021         local dir=$DIR/$tdir
8022
8023         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8024         # Create composite files with three components
8025         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8026         # Create non-composite files
8027         createmany -o $dir/${tfile}- 10
8028
8029         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8030
8031         [[ $nfiles == 10 ]] ||
8032                 error "lfs find -E 1M found $nfiles != 10 files"
8033
8034         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8035         [[ $nfiles == 25 ]] ||
8036                 error "lfs find ! -E 1M found $nfiles != 25 files"
8037
8038         # All files have a component that starts at 0
8039         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8040         [[ $nfiles == 35 ]] ||
8041                 error "lfs find --component-start 0 - $nfiles != 35 files"
8042
8043         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8044         [[ $nfiles == 15 ]] ||
8045                 error "lfs find --component-start 2M - $nfiles != 15 files"
8046
8047         # All files created here have a componenet that does not starts at 2M
8048         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8049         [[ $nfiles == 35 ]] ||
8050                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8051
8052         # Find files with a specified number of components
8053         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8054         [[ $nfiles == 15 ]] ||
8055                 error "lfs find --component-count 3 - $nfiles != 15 files"
8056
8057         # Remember non-composite files have a component count of zero
8058         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8059         [[ $nfiles == 10 ]] ||
8060                 error "lfs find --component-count 0 - $nfiles != 10 files"
8061
8062         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8063         [[ $nfiles == 20 ]] ||
8064                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8065
8066         # All files have a flag called "init"
8067         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8068         [[ $nfiles == 35 ]] ||
8069                 error "lfs find --component-flags init - $nfiles != 35 files"
8070
8071         # Multi-component files will have a component not initialized
8072         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8073         [[ $nfiles == 15 ]] ||
8074                 error "lfs find !--component-flags init - $nfiles != 15 files"
8075
8076         rm -rf $dir
8077
8078 }
8079 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8080
8081 test_56ca() {
8082         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8083                 skip "Need MDS version at least 2.10.57"
8084
8085         local td=$DIR/$tdir
8086         local tf=$td/$tfile
8087         local dir
8088         local nfiles
8089         local cmd
8090         local i
8091         local j
8092
8093         # create mirrored directories and mirrored files
8094         mkdir $td || error "mkdir $td failed"
8095         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8096         createmany -o $tf- 10 || error "create $tf- failed"
8097
8098         for i in $(seq 2); do
8099                 dir=$td/dir$i
8100                 mkdir $dir || error "mkdir $dir failed"
8101                 $LFS mirror create -N$((3 + i)) $dir ||
8102                         error "create mirrored dir $dir failed"
8103                 createmany -o $dir/$tfile- 10 ||
8104                         error "create $dir/$tfile- failed"
8105         done
8106
8107         # change the states of some mirrored files
8108         echo foo > $tf-6
8109         for i in $(seq 2); do
8110                 dir=$td/dir$i
8111                 for j in $(seq 4 9); do
8112                         echo foo > $dir/$tfile-$j
8113                 done
8114         done
8115
8116         # find mirrored files with specific mirror count
8117         cmd="$LFS find --mirror-count 3 --type f $td"
8118         nfiles=$($cmd | wc -l)
8119         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8120
8121         cmd="$LFS find ! --mirror-count 3 --type f $td"
8122         nfiles=$($cmd | wc -l)
8123         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8124
8125         cmd="$LFS find --mirror-count +2 --type f $td"
8126         nfiles=$($cmd | wc -l)
8127         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8128
8129         cmd="$LFS find --mirror-count -6 --type f $td"
8130         nfiles=$($cmd | wc -l)
8131         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8132
8133         # find mirrored files with specific file state
8134         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8135         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8136
8137         cmd="$LFS find --mirror-state=ro --type f $td"
8138         nfiles=$($cmd | wc -l)
8139         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8140
8141         cmd="$LFS find ! --mirror-state=ro --type f $td"
8142         nfiles=$($cmd | wc -l)
8143         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8144
8145         cmd="$LFS find --mirror-state=wp --type f $td"
8146         nfiles=$($cmd | wc -l)
8147         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8148
8149         cmd="$LFS find ! --mirror-state=sp --type f $td"
8150         nfiles=$($cmd | wc -l)
8151         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8152 }
8153 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8154
8155 test_56da() { # LU-14179
8156         local path=$DIR/$tdir
8157
8158         test_mkdir $path
8159         cd $path
8160
8161         local longdir=$(str_repeat 'a' 255)
8162
8163         for i in {1..15}; do
8164                 path=$path/$longdir
8165                 test_mkdir $longdir
8166                 cd $longdir
8167         done
8168
8169         local len=${#path}
8170         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8171
8172         test_mkdir $lastdir
8173         cd $lastdir
8174         # PATH_MAX-1
8175         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8176
8177         # NAME_MAX
8178         touch $(str_repeat 'f' 255)
8179
8180         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8181                 error "lfs find reported an error"
8182
8183         rm -rf $DIR/$tdir
8184 }
8185 run_test 56da "test lfs find with long paths"
8186
8187 test_56ea() { #LU-10378
8188         local path=$DIR/$tdir
8189         local pool=$TESTNAME
8190
8191         # Create ost pool
8192         pool_add $pool || error "pool_add $pool failed"
8193         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8194                 error "adding targets to $pool failed"
8195
8196         # Set default pool on directory before creating file
8197         mkdir $path || error "mkdir $path failed"
8198         $LFS setstripe -p $pool $path ||
8199                 error "set OST pool on $pool failed"
8200         touch $path/$tfile || error "touch $path/$tfile failed"
8201
8202         # Compare basic file attributes from -printf and stat
8203         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8204         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8205
8206         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8207                 error "Attrs from lfs find and stat don't match"
8208
8209         # Compare Lustre attributes from lfs find and lfs getstripe
8210         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8211         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8212         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8213         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8214         local fpool=$($LFS getstripe --pool $path/$tfile)
8215         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8216
8217         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8218                 error "Attrs from lfs find and lfs getstripe don't match"
8219
8220         # Verify behavior for unknown escape/format sequences
8221         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8222
8223         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8224                 error "Escape/format codes don't match"
8225 }
8226 run_test 56ea "test lfs find -printf option"
8227
8228 test_57a() {
8229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8230         # note test will not do anything if MDS is not local
8231         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8232                 skip_env "ldiskfs only test"
8233         fi
8234         remote_mds_nodsh && skip "remote MDS with nodsh"
8235
8236         local MNTDEV="osd*.*MDT*.mntdev"
8237         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8238         [ -z "$DEV" ] && error "can't access $MNTDEV"
8239         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8240                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8241                         error "can't access $DEV"
8242                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8243                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8244                 rm $TMP/t57a.dump
8245         done
8246 }
8247 run_test 57a "verify MDS filesystem created with large inodes =="
8248
8249 test_57b() {
8250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8251         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8252                 skip_env "ldiskfs only test"
8253         fi
8254         remote_mds_nodsh && skip "remote MDS with nodsh"
8255
8256         local dir=$DIR/$tdir
8257         local filecount=100
8258         local file1=$dir/f1
8259         local fileN=$dir/f$filecount
8260
8261         rm -rf $dir || error "removing $dir"
8262         test_mkdir -c1 $dir
8263         local mdtidx=$($LFS getstripe -m $dir)
8264         local mdtname=MDT$(printf %04x $mdtidx)
8265         local facet=mds$((mdtidx + 1))
8266
8267         echo "mcreating $filecount files"
8268         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8269
8270         # verify that files do not have EAs yet
8271         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8272                 error "$file1 has an EA"
8273         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8274                 error "$fileN has an EA"
8275
8276         sync
8277         sleep 1
8278         df $dir  #make sure we get new statfs data
8279         local mdsfree=$(do_facet $facet \
8280                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8281         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8282         local file
8283
8284         echo "opening files to create objects/EAs"
8285         for file in $(seq -f $dir/f%g 1 $filecount); do
8286                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8287                         error "opening $file"
8288         done
8289
8290         # verify that files have EAs now
8291         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8292         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8293
8294         sleep 1  #make sure we get new statfs data
8295         df $dir
8296         local mdsfree2=$(do_facet $facet \
8297                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8298         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8299
8300         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8301                 if [ "$mdsfree" != "$mdsfree2" ]; then
8302                         error "MDC before $mdcfree != after $mdcfree2"
8303                 else
8304                         echo "MDC before $mdcfree != after $mdcfree2"
8305                         echo "unable to confirm if MDS has large inodes"
8306                 fi
8307         fi
8308         rm -rf $dir
8309 }
8310 run_test 57b "default LOV EAs are stored inside large inodes ==="
8311
8312 test_58() {
8313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8314         [ -z "$(which wiretest 2>/dev/null)" ] &&
8315                         skip_env "could not find wiretest"
8316
8317         wiretest
8318 }
8319 run_test 58 "verify cross-platform wire constants =============="
8320
8321 test_59() {
8322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8323
8324         echo "touch 130 files"
8325         createmany -o $DIR/f59- 130
8326         echo "rm 130 files"
8327         unlinkmany $DIR/f59- 130
8328         sync
8329         # wait for commitment of removal
8330         wait_delete_completed
8331 }
8332 run_test 59 "verify cancellation of llog records async ========="
8333
8334 TEST60_HEAD="test_60 run $RANDOM"
8335 test_60a() {
8336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8337         remote_mgs_nodsh && skip "remote MGS with nodsh"
8338         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8339                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8340                         skip_env "missing subtest run-llog.sh"
8341
8342         log "$TEST60_HEAD - from kernel mode"
8343         do_facet mgs "$LCTL dk > /dev/null"
8344         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8345         do_facet mgs $LCTL dk > $TMP/$tfile
8346
8347         # LU-6388: test llog_reader
8348         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8349         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8350         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8351                         skip_env "missing llog_reader"
8352         local fstype=$(facet_fstype mgs)
8353         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8354                 skip_env "Only for ldiskfs or zfs type mgs"
8355
8356         local mntpt=$(facet_mntpt mgs)
8357         local mgsdev=$(mgsdevname 1)
8358         local fid_list
8359         local fid
8360         local rec_list
8361         local rec
8362         local rec_type
8363         local obj_file
8364         local path
8365         local seq
8366         local oid
8367         local pass=true
8368
8369         #get fid and record list
8370         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8371                 tail -n 4))
8372         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8373                 tail -n 4))
8374         #remount mgs as ldiskfs or zfs type
8375         stop mgs || error "stop mgs failed"
8376         mount_fstype mgs || error "remount mgs failed"
8377         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8378                 fid=${fid_list[i]}
8379                 rec=${rec_list[i]}
8380                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8381                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8382                 oid=$((16#$oid))
8383
8384                 case $fstype in
8385                         ldiskfs )
8386                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8387                         zfs )
8388                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8389                 esac
8390                 echo "obj_file is $obj_file"
8391                 do_facet mgs $llog_reader $obj_file
8392
8393                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8394                         awk '{ print $3 }' | sed -e "s/^type=//g")
8395                 if [ $rec_type != $rec ]; then
8396                         echo "FAILED test_60a wrong record type $rec_type," \
8397                               "should be $rec"
8398                         pass=false
8399                         break
8400                 fi
8401
8402                 #check obj path if record type is LLOG_LOGID_MAGIC
8403                 if [ "$rec" == "1064553b" ]; then
8404                         path=$(do_facet mgs $llog_reader $obj_file |
8405                                 grep "path=" | awk '{ print $NF }' |
8406                                 sed -e "s/^path=//g")
8407                         if [ $obj_file != $mntpt/$path ]; then
8408                                 echo "FAILED test_60a wrong obj path" \
8409                                       "$montpt/$path, should be $obj_file"
8410                                 pass=false
8411                                 break
8412                         fi
8413                 fi
8414         done
8415         rm -f $TMP/$tfile
8416         #restart mgs before "error", otherwise it will block the next test
8417         stop mgs || error "stop mgs failed"
8418         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8419         $pass || error "test failed, see FAILED test_60a messages for specifics"
8420 }
8421 run_test 60a "llog_test run from kernel module and test llog_reader"
8422
8423 test_60b() { # bug 6411
8424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8425
8426         dmesg > $DIR/$tfile
8427         LLOG_COUNT=$(do_facet mgs dmesg |
8428                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8429                           /llog_[a-z]*.c:[0-9]/ {
8430                                 if (marker)
8431                                         from_marker++
8432                                 from_begin++
8433                           }
8434                           END {
8435                                 if (marker)
8436                                         print from_marker
8437                                 else
8438                                         print from_begin
8439                           }")
8440
8441         [[ $LLOG_COUNT -gt 120 ]] &&
8442                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8443 }
8444 run_test 60b "limit repeated messages from CERROR/CWARN"
8445
8446 test_60c() {
8447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8448
8449         echo "create 5000 files"
8450         createmany -o $DIR/f60c- 5000
8451 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8452         lctl set_param fail_loc=0x80000137
8453         unlinkmany $DIR/f60c- 5000
8454         lctl set_param fail_loc=0
8455 }
8456 run_test 60c "unlink file when mds full"
8457
8458 test_60d() {
8459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8460
8461         SAVEPRINTK=$(lctl get_param -n printk)
8462         # verify "lctl mark" is even working"
8463         MESSAGE="test message ID $RANDOM $$"
8464         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8465         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8466
8467         lctl set_param printk=0 || error "set lnet.printk failed"
8468         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8469         MESSAGE="new test message ID $RANDOM $$"
8470         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8471         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8472         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8473
8474         lctl set_param -n printk="$SAVEPRINTK"
8475 }
8476 run_test 60d "test printk console message masking"
8477
8478 test_60e() {
8479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8480         remote_mds_nodsh && skip "remote MDS with nodsh"
8481
8482         touch $DIR/$tfile
8483 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8484         do_facet mds1 lctl set_param fail_loc=0x15b
8485         rm $DIR/$tfile
8486 }
8487 run_test 60e "no space while new llog is being created"
8488
8489 test_60f() {
8490         local old_path=$($LCTL get_param -n debug_path)
8491
8492         stack_trap "$LCTL set_param debug_path=$old_path"
8493         stack_trap "rm -f $TMP/$tfile*"
8494         rm -f $TMP/$tfile* 2> /dev/null
8495         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8496         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8497         test_mkdir $DIR/$tdir
8498         # retry in case the open is cached and not released
8499         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8500                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8501                 sleep 0.1
8502         done
8503         ls $TMP/$tfile*
8504         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8505 }
8506 run_test 60f "change debug_path works"
8507
8508 test_60g() {
8509         local pid
8510         local i
8511
8512         test_mkdir -c $MDSCOUNT $DIR/$tdir
8513
8514         (
8515                 local index=0
8516                 while true; do
8517                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8518                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8519                                 2>/dev/null
8520                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8521                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8522                         index=$((index + 1))
8523                 done
8524         ) &
8525
8526         pid=$!
8527
8528         for i in {0..100}; do
8529                 # define OBD_FAIL_OSD_TXN_START    0x19a
8530                 local index=$((i % MDSCOUNT + 1))
8531
8532                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8533                         > /dev/null
8534                 sleep 0.01
8535         done
8536
8537         kill -9 $pid
8538
8539         for i in $(seq $MDSCOUNT); do
8540                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8541         done
8542
8543         mkdir $DIR/$tdir/new || error "mkdir failed"
8544         rmdir $DIR/$tdir/new || error "rmdir failed"
8545
8546         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8547                 -t namespace
8548         for i in $(seq $MDSCOUNT); do
8549                 wait_update_facet mds$i "$LCTL get_param -n \
8550                         mdd.$(facet_svc mds$i).lfsck_namespace |
8551                         awk '/^status/ { print \\\$2 }'" "completed"
8552         done
8553
8554         ls -R $DIR/$tdir
8555         rm -rf $DIR/$tdir || error "rmdir failed"
8556 }
8557 run_test 60g "transaction abort won't cause MDT hung"
8558
8559 test_60h() {
8560         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8561                 skip "Need MDS version at least 2.12.52"
8562         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8563
8564         local f
8565
8566         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8567         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8568         for fail_loc in 0x80000188 0x80000189; do
8569                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8570                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8571                         error "mkdir $dir-$fail_loc failed"
8572                 for i in {0..10}; do
8573                         # create may fail on missing stripe
8574                         echo $i > $DIR/$tdir-$fail_loc/$i
8575                 done
8576                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8577                         error "getdirstripe $tdir-$fail_loc failed"
8578                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8579                         error "migrate $tdir-$fail_loc failed"
8580                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8581                         error "getdirstripe $tdir-$fail_loc failed"
8582                 pushd $DIR/$tdir-$fail_loc
8583                 for f in *; do
8584                         echo $f | cmp $f - || error "$f data mismatch"
8585                 done
8586                 popd
8587                 rm -rf $DIR/$tdir-$fail_loc
8588         done
8589 }
8590 run_test 60h "striped directory with missing stripes can be accessed"
8591
8592 function t60i_load() {
8593         mkdir $DIR/$tdir
8594         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8595         $LCTL set_param fail_loc=0x131c fail_val=1
8596         for ((i=0; i<5000; i++)); do
8597                 touch $DIR/$tdir/f$i
8598         done
8599 }
8600
8601 test_60i() {
8602         changelog_register || error "changelog_register failed"
8603         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8604         changelog_users $SINGLEMDS | grep -q $cl_user ||
8605                 error "User $cl_user not found in changelog_users"
8606         changelog_chmask "ALL"
8607         t60i_load &
8608         local PID=$!
8609         for((i=0; i<100; i++)); do
8610                 changelog_dump >/dev/null ||
8611                         error "can't read changelog"
8612         done
8613         kill $PID
8614         wait $PID
8615         changelog_deregister || error "changelog_deregister failed"
8616         $LCTL set_param fail_loc=0
8617 }
8618 run_test 60i "llog: new record vs reader race"
8619
8620 test_61a() {
8621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8622
8623         f="$DIR/f61"
8624         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8625         cancel_lru_locks osc
8626         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8627         sync
8628 }
8629 run_test 61a "mmap() writes don't make sync hang ================"
8630
8631 test_61b() {
8632         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8633 }
8634 run_test 61b "mmap() of unstriped file is successful"
8635
8636 # bug 2330 - insufficient obd_match error checking causes LBUG
8637 test_62() {
8638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8639
8640         f="$DIR/f62"
8641         echo foo > $f
8642         cancel_lru_locks osc
8643         lctl set_param fail_loc=0x405
8644         cat $f && error "cat succeeded, expect -EIO"
8645         lctl set_param fail_loc=0
8646 }
8647 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8648 # match every page all of the time.
8649 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8650
8651 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8652 # Though this test is irrelevant anymore, it helped to reveal some
8653 # other grant bugs (LU-4482), let's keep it.
8654 test_63a() {   # was test_63
8655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8656
8657         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8658
8659         for i in `seq 10` ; do
8660                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8661                 sleep 5
8662                 kill $!
8663                 sleep 1
8664         done
8665
8666         rm -f $DIR/f63 || true
8667 }
8668 run_test 63a "Verify oig_wait interruption does not crash ======="
8669
8670 # bug 2248 - async write errors didn't return to application on sync
8671 # bug 3677 - async write errors left page locked
8672 test_63b() {
8673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8674
8675         debugsave
8676         lctl set_param debug=-1
8677
8678         # ensure we have a grant to do async writes
8679         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8680         rm $DIR/$tfile
8681
8682         sync    # sync lest earlier test intercept the fail_loc
8683
8684         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8685         lctl set_param fail_loc=0x80000406
8686         $MULTIOP $DIR/$tfile Owy && \
8687                 error "sync didn't return ENOMEM"
8688         sync; sleep 2; sync     # do a real sync this time to flush page
8689         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8690                 error "locked page left in cache after async error" || true
8691         debugrestore
8692 }
8693 run_test 63b "async write errors should be returned to fsync ==="
8694
8695 test_64a () {
8696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8697
8698         lfs df $DIR
8699         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8700 }
8701 run_test 64a "verify filter grant calculations (in kernel) ====="
8702
8703 test_64b () {
8704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8705
8706         bash oos.sh $MOUNT || error "oos.sh failed: $?"
8707 }
8708 run_test 64b "check out-of-space detection on client"
8709
8710 test_64c() {
8711         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8712 }
8713 run_test 64c "verify grant shrink"
8714
8715 import_param() {
8716         local tgt=$1
8717         local param=$2
8718
8719         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8720 }
8721
8722 # this does exactly what osc_request.c:osc_announce_cached() does in
8723 # order to calculate max amount of grants to ask from server
8724 want_grant() {
8725         local tgt=$1
8726
8727         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8728         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8729
8730         ((rpc_in_flight++));
8731         nrpages=$((nrpages * rpc_in_flight))
8732
8733         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8734
8735         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8736
8737         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8738         local undirty=$((nrpages * PAGE_SIZE))
8739
8740         local max_extent_pages
8741         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8742         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8743         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8744         local grant_extent_tax
8745         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8746
8747         undirty=$((undirty + nrextents * grant_extent_tax))
8748
8749         echo $undirty
8750 }
8751
8752 # this is size of unit for grant allocation. It should be equal to
8753 # what tgt_grant.c:tgt_grant_chunk() calculates
8754 grant_chunk() {
8755         local tgt=$1
8756         local max_brw_size
8757         local grant_extent_tax
8758
8759         max_brw_size=$(import_param $tgt max_brw_size)
8760
8761         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8762
8763         echo $(((max_brw_size + grant_extent_tax) * 2))
8764 }
8765
8766 test_64d() {
8767         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8768                 skip "OST < 2.10.55 doesn't limit grants enough"
8769
8770         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8771
8772         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8773                 skip "no grant_param connect flag"
8774
8775         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8776
8777         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8778         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8779
8780
8781         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8782         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8783
8784         $LFS setstripe $DIR/$tfile -i 0 -c 1
8785         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8786         ddpid=$!
8787
8788         while kill -0 $ddpid; do
8789                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8790
8791                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8792                         kill $ddpid
8793                         error "cur_grant $cur_grant > $max_cur_granted"
8794                 fi
8795
8796                 sleep 1
8797         done
8798 }
8799 run_test 64d "check grant limit exceed"
8800
8801 check_grants() {
8802         local tgt=$1
8803         local expected=$2
8804         local msg=$3
8805         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8806
8807         ((cur_grants == expected)) ||
8808                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8809 }
8810
8811 round_up_p2() {
8812         echo $((($1 + $2 - 1) & ~($2 - 1)))
8813 }
8814
8815 test_64e() {
8816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8817         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8818                 skip "Need OSS version at least 2.11.56"
8819
8820         # Remount client to reset grant
8821         remount_client $MOUNT || error "failed to remount client"
8822         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8823
8824         local init_grants=$(import_param $osc_tgt initial_grant)
8825
8826         check_grants $osc_tgt $init_grants "init grants"
8827
8828         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8829         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8830         local gbs=$(import_param $osc_tgt grant_block_size)
8831
8832         # write random number of bytes from max_brw_size / 4 to max_brw_size
8833         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8834         # align for direct io
8835         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8836         # round to grant consumption unit
8837         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8838
8839         local grants=$((wb_round_up + extent_tax))
8840
8841         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8842
8843         # define OBD_FAIL_TGT_NO_GRANT 0x725
8844         # make the server not grant more back
8845         do_facet ost1 $LCTL set_param fail_loc=0x725
8846         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8847
8848         do_facet ost1 $LCTL set_param fail_loc=0
8849
8850         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8851
8852         rm -f $DIR/$tfile || error "rm failed"
8853
8854         # Remount client to reset grant
8855         remount_client $MOUNT || error "failed to remount client"
8856         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8857
8858         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8859
8860         # define OBD_FAIL_TGT_NO_GRANT 0x725
8861         # make the server not grant more back
8862         do_facet ost1 $LCTL set_param fail_loc=0x725
8863         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8864         do_facet ost1 $LCTL set_param fail_loc=0
8865
8866         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8867 }
8868 run_test 64e "check grant consumption (no grant allocation)"
8869
8870 test_64f() {
8871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8872
8873         # Remount client to reset grant
8874         remount_client $MOUNT || error "failed to remount client"
8875         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8876
8877         local init_grants=$(import_param $osc_tgt initial_grant)
8878         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8879         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8880         local gbs=$(import_param $osc_tgt grant_block_size)
8881         local chunk=$(grant_chunk $osc_tgt)
8882
8883         # write random number of bytes from max_brw_size / 4 to max_brw_size
8884         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8885         # align for direct io
8886         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8887         # round to grant consumption unit
8888         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8889
8890         local grants=$((wb_round_up + extent_tax))
8891
8892         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8893         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8894                 error "error writing to $DIR/$tfile"
8895
8896         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8897                 "direct io with grant allocation"
8898
8899         rm -f $DIR/$tfile || error "rm failed"
8900
8901         # Remount client to reset grant
8902         remount_client $MOUNT || error "failed to remount client"
8903         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8904
8905         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8906
8907         local cmd="oO_WRONLY:w${write_bytes}_yc"
8908
8909         $MULTIOP $DIR/$tfile $cmd &
8910         MULTIPID=$!
8911         sleep 1
8912
8913         check_grants $osc_tgt $((init_grants - grants)) \
8914                 "buffered io, not write rpc"
8915
8916         kill -USR1 $MULTIPID
8917         wait
8918
8919         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8920                 "buffered io, one RPC"
8921 }
8922 run_test 64f "check grant consumption (with grant allocation)"
8923
8924 test_64g() {
8925         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
8926                 skip "Need MDS version at least 2.14.56"
8927
8928         local mdts=$(comma_list $(mdts_nodes))
8929
8930         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
8931                         tr '\n' ' ')
8932         stack_trap "$LCTL set_param $old"
8933
8934         # generate dirty pages and increase dirty granted on MDT
8935         stack_trap "rm -f $DIR/$tfile-*"
8936         for (( i = 0; i < 10; i++)); do
8937                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
8938                         error "can't set stripe"
8939                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
8940                         error "can't dd"
8941                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
8942                         $LFS getstripe $DIR/$tfile-$i
8943                         error "not DoM file"
8944                 }
8945         done
8946
8947         # flush dirty pages
8948         sync
8949
8950         # wait until grant shrink reset grant dirty on MDTs
8951         for ((i = 0; i < 120; i++)); do
8952                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8953                         awk '{sum=sum+$1} END {print sum}')
8954                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
8955                 echo "$grant_dirty grants, $vm_dirty pages"
8956                 (( grant_dirty + vm_dirty == 0 )) && break
8957                 (( i == 3 )) && sync &&
8958                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
8959                 sleep 1
8960         done
8961
8962         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8963                 awk '{sum=sum+$1} END {print sum}')
8964         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
8965 }
8966 run_test 64g "grant shrink on MDT"
8967
8968 test_64h() {
8969         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
8970                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
8971
8972         local instance=$($LFS getname -i $DIR)
8973         local osc_tgt="$FSNAME-OST0000-osc-$instance"
8974         local num_exps=$(do_facet ost1 \
8975             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
8976         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8977         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
8978         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8979
8980         # 10MiB is for file to be written, max_brw_size * 16 *
8981         # num_exps is space reserve so that tgt_grant_shrink() decided
8982         # to not shrink
8983         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
8984         (( avail * 1024 < expect )) &&
8985                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
8986
8987         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
8988         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
8989         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
8990         $LCTL set_param osc.*OST0000*.grant_shrink=1
8991         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
8992
8993         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8994         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
8995
8996         # drop cache so that coming read would do rpc
8997         cancel_lru_locks osc
8998
8999         # shrink interval is set to 10, pause for 7 seconds so that
9000         # grant thread did not wake up yet but coming read entered
9001         # shrink mode for rpc (osc_should_shrink_grant())
9002         sleep 7
9003
9004         declare -a cur_grant_bytes
9005         declare -a tot_granted
9006         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9007         tot_granted[0]=$(do_facet ost1 \
9008             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9009
9010         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9011
9012         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9013         tot_granted[1]=$(do_facet ost1 \
9014             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9015
9016         # grant change should be equal on both sides
9017         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9018                 tot_granted[0] - tot_granted[1])) ||
9019                 error "grant change mismatch, "                                \
9020                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9021                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9022 }
9023 run_test 64h "grant shrink on read"
9024
9025 test_64i() {
9026         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9027                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9028
9029         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9030         remote_ost_nodsh && skip "remote OSTs with nodsh"
9031
9032         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9033
9034         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9035
9036         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9037         local instance=$($LFS getname -i $DIR)
9038
9039         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9040         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9041
9042         # shrink grants and simulate rpc loss
9043         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9044         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9045         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9046
9047         fail ost1
9048
9049         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9050
9051         local testid=$(echo $TESTNAME | tr '_' ' ')
9052
9053         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9054                 grep "GRANT, real grant" &&
9055                 error "client has more grants then it owns" || true
9056 }
9057 run_test 64i "shrink on reconnect"
9058
9059 # bug 1414 - set/get directories' stripe info
9060 test_65a() {
9061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9062
9063         test_mkdir $DIR/$tdir
9064         touch $DIR/$tdir/f1
9065         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9066 }
9067 run_test 65a "directory with no stripe info"
9068
9069 test_65b() {
9070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9071
9072         test_mkdir $DIR/$tdir
9073         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9074
9075         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9076                                                 error "setstripe"
9077         touch $DIR/$tdir/f2
9078         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9079 }
9080 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9081
9082 test_65c() {
9083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9084         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9085
9086         test_mkdir $DIR/$tdir
9087         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9088
9089         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9090                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9091         touch $DIR/$tdir/f3
9092         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9093 }
9094 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9095
9096 test_65d() {
9097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9098
9099         test_mkdir $DIR/$tdir
9100         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9101         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9102
9103         if [[ $STRIPECOUNT -le 0 ]]; then
9104                 sc=1
9105         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9106                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9107                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9108         else
9109                 sc=$(($STRIPECOUNT - 1))
9110         fi
9111         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9112         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9113         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9114                 error "lverify failed"
9115 }
9116 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9117
9118 test_65e() {
9119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9120
9121         test_mkdir $DIR/$tdir
9122
9123         $LFS setstripe $DIR/$tdir || error "setstripe"
9124         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9125                                         error "no stripe info failed"
9126         touch $DIR/$tdir/f6
9127         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9128 }
9129 run_test 65e "directory setstripe defaults"
9130
9131 test_65f() {
9132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9133
9134         test_mkdir $DIR/${tdir}f
9135         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9136                 error "setstripe succeeded" || true
9137 }
9138 run_test 65f "dir setstripe permission (should return error) ==="
9139
9140 test_65g() {
9141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9142
9143         test_mkdir $DIR/$tdir
9144         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9145
9146         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9147                 error "setstripe -S failed"
9148         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9149         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9150                 error "delete default stripe failed"
9151 }
9152 run_test 65g "directory setstripe -d"
9153
9154 test_65h() {
9155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9156
9157         test_mkdir $DIR/$tdir
9158         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9159
9160         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9161                 error "setstripe -S failed"
9162         test_mkdir $DIR/$tdir/dd1
9163         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9164                 error "stripe info inherit failed"
9165 }
9166 run_test 65h "directory stripe info inherit ===================="
9167
9168 test_65i() {
9169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9170
9171         save_layout_restore_at_exit $MOUNT
9172
9173         # bug6367: set non-default striping on root directory
9174         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9175
9176         # bug12836: getstripe on -1 default directory striping
9177         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9178
9179         # bug12836: getstripe -v on -1 default directory striping
9180         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9181
9182         # bug12836: new find on -1 default directory striping
9183         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9184 }
9185 run_test 65i "various tests to set root directory striping"
9186
9187 test_65j() { # bug6367
9188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9189
9190         sync; sleep 1
9191
9192         # if we aren't already remounting for each test, do so for this test
9193         if [ "$I_MOUNTED" = "yes" ]; then
9194                 cleanup || error "failed to unmount"
9195                 setup
9196         fi
9197
9198         save_layout_restore_at_exit $MOUNT
9199
9200         $LFS setstripe -d $MOUNT || error "setstripe failed"
9201 }
9202 run_test 65j "set default striping on root directory (bug 6367)="
9203
9204 cleanup_65k() {
9205         rm -rf $DIR/$tdir
9206         wait_delete_completed
9207         do_facet $SINGLEMDS "lctl set_param -n \
9208                 osp.$ost*MDT0000.max_create_count=$max_count"
9209         do_facet $SINGLEMDS "lctl set_param -n \
9210                 osp.$ost*MDT0000.create_count=$count"
9211         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9212         echo $INACTIVE_OSC "is Activate"
9213
9214         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9215 }
9216
9217 test_65k() { # bug11679
9218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9219         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9220         remote_mds_nodsh && skip "remote MDS with nodsh"
9221
9222         local disable_precreate=true
9223         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9224                 disable_precreate=false
9225
9226         echo "Check OST status: "
9227         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9228                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9229
9230         for OSC in $MDS_OSCS; do
9231                 echo $OSC "is active"
9232                 do_facet $SINGLEMDS lctl --device %$OSC activate
9233         done
9234
9235         for INACTIVE_OSC in $MDS_OSCS; do
9236                 local ost=$(osc_to_ost $INACTIVE_OSC)
9237                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9238                                lov.*md*.target_obd |
9239                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9240
9241                 mkdir -p $DIR/$tdir
9242                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9243                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9244
9245                 echo "Deactivate: " $INACTIVE_OSC
9246                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9247
9248                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9249                               osp.$ost*MDT0000.create_count")
9250                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9251                                   osp.$ost*MDT0000.max_create_count")
9252                 $disable_precreate &&
9253                         do_facet $SINGLEMDS "lctl set_param -n \
9254                                 osp.$ost*MDT0000.max_create_count=0"
9255
9256                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9257                         [ -f $DIR/$tdir/$idx ] && continue
9258                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9259                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9260                                 { cleanup_65k;
9261                                   error "setstripe $idx should succeed"; }
9262                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9263                 done
9264                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9265                 rmdir $DIR/$tdir
9266
9267                 do_facet $SINGLEMDS "lctl set_param -n \
9268                         osp.$ost*MDT0000.max_create_count=$max_count"
9269                 do_facet $SINGLEMDS "lctl set_param -n \
9270                         osp.$ost*MDT0000.create_count=$count"
9271                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9272                 echo $INACTIVE_OSC "is Activate"
9273
9274                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9275         done
9276 }
9277 run_test 65k "validate manual striping works properly with deactivated OSCs"
9278
9279 test_65l() { # bug 12836
9280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9281
9282         test_mkdir -p $DIR/$tdir/test_dir
9283         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9284         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9285 }
9286 run_test 65l "lfs find on -1 stripe dir ========================"
9287
9288 test_65m() {
9289         local layout=$(save_layout $MOUNT)
9290         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9291                 restore_layout $MOUNT $layout
9292                 error "setstripe should fail by non-root users"
9293         }
9294         true
9295 }
9296 run_test 65m "normal user can't set filesystem default stripe"
9297
9298 test_65n() {
9299         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9300         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9301                 skip "Need MDS version at least 2.12.50"
9302         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9303
9304         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9305         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9306         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9307
9308         save_layout_restore_at_exit $MOUNT
9309
9310         # new subdirectory under root directory should not inherit
9311         # the default layout from root
9312         local dir1=$MOUNT/$tdir-1
9313         mkdir $dir1 || error "mkdir $dir1 failed"
9314         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9315                 error "$dir1 shouldn't have LOV EA"
9316
9317         # delete the default layout on root directory
9318         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9319
9320         local dir2=$MOUNT/$tdir-2
9321         mkdir $dir2 || error "mkdir $dir2 failed"
9322         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9323                 error "$dir2 shouldn't have LOV EA"
9324
9325         # set a new striping pattern on root directory
9326         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9327         local new_def_stripe_size=$((def_stripe_size * 2))
9328         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9329                 error "set stripe size on $MOUNT failed"
9330
9331         # new file created in $dir2 should inherit the new stripe size from
9332         # the filesystem default
9333         local file2=$dir2/$tfile-2
9334         touch $file2 || error "touch $file2 failed"
9335
9336         local file2_stripe_size=$($LFS getstripe -S $file2)
9337         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9338         {
9339                 echo "file2_stripe_size: '$file2_stripe_size'"
9340                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9341                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9342         }
9343
9344         local dir3=$MOUNT/$tdir-3
9345         mkdir $dir3 || error "mkdir $dir3 failed"
9346         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9347         # the root layout, which is the actual default layout that will be used
9348         # when new files are created in $dir3.
9349         local dir3_layout=$(get_layout_param $dir3)
9350         local root_dir_layout=$(get_layout_param $MOUNT)
9351         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9352         {
9353                 echo "dir3_layout: '$dir3_layout'"
9354                 echo "root_dir_layout: '$root_dir_layout'"
9355                 error "$dir3 should show the default layout from $MOUNT"
9356         }
9357
9358         # set OST pool on root directory
9359         local pool=$TESTNAME
9360         pool_add $pool || error "add $pool failed"
9361         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9362                 error "add targets to $pool failed"
9363
9364         $LFS setstripe -p $pool $MOUNT ||
9365                 error "set OST pool on $MOUNT failed"
9366
9367         # new file created in $dir3 should inherit the pool from
9368         # the filesystem default
9369         local file3=$dir3/$tfile-3
9370         touch $file3 || error "touch $file3 failed"
9371
9372         local file3_pool=$($LFS getstripe -p $file3)
9373         [[ "$file3_pool" = "$pool" ]] ||
9374                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9375
9376         local dir4=$MOUNT/$tdir-4
9377         mkdir $dir4 || error "mkdir $dir4 failed"
9378         local dir4_layout=$(get_layout_param $dir4)
9379         root_dir_layout=$(get_layout_param $MOUNT)
9380         echo "$LFS getstripe -d $dir4"
9381         $LFS getstripe -d $dir4
9382         echo "$LFS getstripe -d $MOUNT"
9383         $LFS getstripe -d $MOUNT
9384         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9385         {
9386                 echo "dir4_layout: '$dir4_layout'"
9387                 echo "root_dir_layout: '$root_dir_layout'"
9388                 error "$dir4 should show the default layout from $MOUNT"
9389         }
9390
9391         # new file created in $dir4 should inherit the pool from
9392         # the filesystem default
9393         local file4=$dir4/$tfile-4
9394         touch $file4 || error "touch $file4 failed"
9395
9396         local file4_pool=$($LFS getstripe -p $file4)
9397         [[ "$file4_pool" = "$pool" ]] ||
9398                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9399
9400         # new subdirectory under non-root directory should inherit
9401         # the default layout from its parent directory
9402         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9403                 error "set directory layout on $dir4 failed"
9404
9405         local dir5=$dir4/$tdir-5
9406         mkdir $dir5 || error "mkdir $dir5 failed"
9407
9408         dir4_layout=$(get_layout_param $dir4)
9409         local dir5_layout=$(get_layout_param $dir5)
9410         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9411         {
9412                 echo "dir4_layout: '$dir4_layout'"
9413                 echo "dir5_layout: '$dir5_layout'"
9414                 error "$dir5 should inherit the default layout from $dir4"
9415         }
9416
9417         # though subdir under ROOT doesn't inherit default layout, but
9418         # its sub dir/file should be created with default layout.
9419         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9420         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9421                 skip "Need MDS version at least 2.12.59"
9422
9423         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9424         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9425         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9426
9427         if [ $default_lmv_hash == "none" ]; then
9428                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9429         else
9430                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9431                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9432         fi
9433
9434         $LFS setdirstripe -D -c 2 $MOUNT ||
9435                 error "setdirstripe -D -c 2 failed"
9436         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9437         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9438         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9439
9440         # $dir4 layout includes pool
9441         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9442         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9443                 error "pool lost on setstripe"
9444         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9445         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9446                 error "pool lost on compound layout setstripe"
9447 }
9448 run_test 65n "don't inherit default layout from root for new subdirectories"
9449
9450 # bug 2543 - update blocks count on client
9451 test_66() {
9452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9453
9454         COUNT=${COUNT:-8}
9455         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9456         sync; sync_all_data; sync; sync_all_data
9457         cancel_lru_locks osc
9458         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9459         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9460 }
9461 run_test 66 "update inode blocks count on client ==============="
9462
9463 meminfo() {
9464         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9465 }
9466
9467 swap_used() {
9468         swapon -s | awk '($1 == "'$1'") { print $4 }'
9469 }
9470
9471 # bug5265, obdfilter oa2dentry return -ENOENT
9472 # #define OBD_FAIL_SRV_ENOENT 0x217
9473 test_69() {
9474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9475         remote_ost_nodsh && skip "remote OST with nodsh"
9476
9477         f="$DIR/$tfile"
9478         $LFS setstripe -c 1 -i 0 $f
9479
9480         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9481
9482         do_facet ost1 lctl set_param fail_loc=0x217
9483         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9484         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9485
9486         do_facet ost1 lctl set_param fail_loc=0
9487         $DIRECTIO write $f 0 2 || error "write error"
9488
9489         cancel_lru_locks osc
9490         $DIRECTIO read $f 0 1 || error "read error"
9491
9492         do_facet ost1 lctl set_param fail_loc=0x217
9493         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9494
9495         do_facet ost1 lctl set_param fail_loc=0
9496         rm -f $f
9497 }
9498 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9499
9500 test_71() {
9501         test_mkdir $DIR/$tdir
9502         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9503         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9504 }
9505 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9506
9507 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9509         [ "$RUNAS_ID" = "$UID" ] &&
9510                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9511         # Check that testing environment is properly set up. Skip if not
9512         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9513                 skip_env "User $RUNAS_ID does not exist - skipping"
9514
9515         touch $DIR/$tfile
9516         chmod 777 $DIR/$tfile
9517         chmod ug+s $DIR/$tfile
9518         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9519                 error "$RUNAS dd $DIR/$tfile failed"
9520         # See if we are still setuid/sgid
9521         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9522                 error "S/gid is not dropped on write"
9523         # Now test that MDS is updated too
9524         cancel_lru_locks mdc
9525         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9526                 error "S/gid is not dropped on MDS"
9527         rm -f $DIR/$tfile
9528 }
9529 run_test 72a "Test that remove suid works properly (bug5695) ===="
9530
9531 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9532         local perm
9533
9534         [ "$RUNAS_ID" = "$UID" ] &&
9535                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9536         [ "$RUNAS_ID" -eq 0 ] &&
9537                 skip_env "RUNAS_ID = 0 -- skipping"
9538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9539         # Check that testing environment is properly set up. Skip if not
9540         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9541                 skip_env "User $RUNAS_ID does not exist - skipping"
9542
9543         touch $DIR/${tfile}-f{g,u}
9544         test_mkdir $DIR/${tfile}-dg
9545         test_mkdir $DIR/${tfile}-du
9546         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9547         chmod g+s $DIR/${tfile}-{f,d}g
9548         chmod u+s $DIR/${tfile}-{f,d}u
9549         for perm in 777 2777 4777; do
9550                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9551                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9552                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9553                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9554         done
9555         true
9556 }
9557 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9558
9559 # bug 3462 - multiple simultaneous MDC requests
9560 test_73() {
9561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9562
9563         test_mkdir $DIR/d73-1
9564         test_mkdir $DIR/d73-2
9565         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9566         pid1=$!
9567
9568         lctl set_param fail_loc=0x80000129
9569         $MULTIOP $DIR/d73-1/f73-2 Oc &
9570         sleep 1
9571         lctl set_param fail_loc=0
9572
9573         $MULTIOP $DIR/d73-2/f73-3 Oc &
9574         pid3=$!
9575
9576         kill -USR1 $pid1
9577         wait $pid1 || return 1
9578
9579         sleep 25
9580
9581         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9582         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9583         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9584
9585         rm -rf $DIR/d73-*
9586 }
9587 run_test 73 "multiple MDC requests (should not deadlock)"
9588
9589 test_74a() { # bug 6149, 6184
9590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9591
9592         touch $DIR/f74a
9593         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9594         #
9595         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9596         # will spin in a tight reconnection loop
9597         $LCTL set_param fail_loc=0x8000030e
9598         # get any lock that won't be difficult - lookup works.
9599         ls $DIR/f74a
9600         $LCTL set_param fail_loc=0
9601         rm -f $DIR/f74a
9602         true
9603 }
9604 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9605
9606 test_74b() { # bug 13310
9607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9608
9609         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9610         #
9611         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9612         # will spin in a tight reconnection loop
9613         $LCTL set_param fail_loc=0x8000030e
9614         # get a "difficult" lock
9615         touch $DIR/f74b
9616         $LCTL set_param fail_loc=0
9617         rm -f $DIR/f74b
9618         true
9619 }
9620 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9621
9622 test_74c() {
9623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9624
9625         #define OBD_FAIL_LDLM_NEW_LOCK
9626         $LCTL set_param fail_loc=0x319
9627         touch $DIR/$tfile && error "touch successful"
9628         $LCTL set_param fail_loc=0
9629         true
9630 }
9631 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9632
9633 slab_lic=/sys/kernel/slab/lustre_inode_cache
9634 num_objects() {
9635         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9636         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9637                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9638 }
9639
9640 test_76a() { # Now for b=20433, added originally in b=1443
9641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9642
9643         cancel_lru_locks osc
9644         # there may be some slab objects cached per core
9645         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9646         local before=$(num_objects)
9647         local count=$((512 * cpus))
9648         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9649         local margin=$((count / 10))
9650         if [[ -f $slab_lic/aliases ]]; then
9651                 local aliases=$(cat $slab_lic/aliases)
9652                 (( aliases > 0 )) && margin=$((margin * aliases))
9653         fi
9654
9655         echo "before slab objects: $before"
9656         for i in $(seq $count); do
9657                 touch $DIR/$tfile
9658                 rm -f $DIR/$tfile
9659         done
9660         cancel_lru_locks osc
9661         local after=$(num_objects)
9662         echo "created: $count, after slab objects: $after"
9663         # shared slab counts are not very accurate, allow significant margin
9664         # the main goal is that the cache growth is not permanently > $count
9665         while (( after > before + margin )); do
9666                 sleep 1
9667                 after=$(num_objects)
9668                 wait=$((wait + 1))
9669                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9670                 if (( wait > 60 )); then
9671                         error "inode slab grew from $before+$margin to $after"
9672                 fi
9673         done
9674 }
9675 run_test 76a "confirm clients recycle inodes properly ===="
9676
9677 test_76b() {
9678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9679         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9680
9681         local count=512
9682         local before=$(num_objects)
9683
9684         for i in $(seq $count); do
9685                 mkdir $DIR/$tdir
9686                 rmdir $DIR/$tdir
9687         done
9688
9689         local after=$(num_objects)
9690         local wait=0
9691
9692         while (( after > before )); do
9693                 sleep 1
9694                 after=$(num_objects)
9695                 wait=$((wait + 1))
9696                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9697                 if (( wait > 60 )); then
9698                         error "inode slab grew from $before to $after"
9699                 fi
9700         done
9701
9702         echo "slab objects before: $before, after: $after"
9703 }
9704 run_test 76b "confirm clients recycle directory inodes properly ===="
9705
9706 export ORIG_CSUM=""
9707 set_checksums()
9708 {
9709         # Note: in sptlrpc modes which enable its own bulk checksum, the
9710         # original crc32_le bulk checksum will be automatically disabled,
9711         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9712         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9713         # In this case set_checksums() will not be no-op, because sptlrpc
9714         # bulk checksum will be enabled all through the test.
9715
9716         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9717         lctl set_param -n osc.*.checksums $1
9718         return 0
9719 }
9720
9721 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9722                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9723 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9724                              tr -d [] | head -n1)}
9725 set_checksum_type()
9726 {
9727         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9728         rc=$?
9729         log "set checksum type to $1, rc = $rc"
9730         return $rc
9731 }
9732
9733 get_osc_checksum_type()
9734 {
9735         # arugment 1: OST name, like OST0000
9736         ost=$1
9737         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9738                         sed 's/.*\[\(.*\)\].*/\1/g')
9739         rc=$?
9740         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9741         echo $checksum_type
9742 }
9743
9744 F77_TMP=$TMP/f77-temp
9745 F77SZ=8
9746 setup_f77() {
9747         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9748                 error "error writing to $F77_TMP"
9749 }
9750
9751 test_77a() { # bug 10889
9752         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9753         $GSS && skip_env "could not run with gss"
9754
9755         [ ! -f $F77_TMP ] && setup_f77
9756         set_checksums 1
9757         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9758         set_checksums 0
9759         rm -f $DIR/$tfile
9760 }
9761 run_test 77a "normal checksum read/write operation"
9762
9763 test_77b() { # bug 10889
9764         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9765         $GSS && skip_env "could not run with gss"
9766
9767         [ ! -f $F77_TMP ] && setup_f77
9768         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9769         $LCTL set_param fail_loc=0x80000409
9770         set_checksums 1
9771
9772         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9773                 error "dd error: $?"
9774         $LCTL set_param fail_loc=0
9775
9776         for algo in $CKSUM_TYPES; do
9777                 cancel_lru_locks osc
9778                 set_checksum_type $algo
9779                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9780                 $LCTL set_param fail_loc=0x80000408
9781                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9782                 $LCTL set_param fail_loc=0
9783         done
9784         set_checksums 0
9785         set_checksum_type $ORIG_CSUM_TYPE
9786         rm -f $DIR/$tfile
9787 }
9788 run_test 77b "checksum error on client write, read"
9789
9790 cleanup_77c() {
9791         trap 0
9792         set_checksums 0
9793         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9794         $check_ost &&
9795                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9796         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9797         $check_ost && [ -n "$ost_file_prefix" ] &&
9798                 do_facet ost1 rm -f ${ost_file_prefix}\*
9799 }
9800
9801 test_77c() {
9802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9803         $GSS && skip_env "could not run with gss"
9804         remote_ost_nodsh && skip "remote OST with nodsh"
9805
9806         local bad1
9807         local osc_file_prefix
9808         local osc_file
9809         local check_ost=false
9810         local ost_file_prefix
9811         local ost_file
9812         local orig_cksum
9813         local dump_cksum
9814         local fid
9815
9816         # ensure corruption will occur on first OSS/OST
9817         $LFS setstripe -i 0 $DIR/$tfile
9818
9819         [ ! -f $F77_TMP ] && setup_f77
9820         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9821                 error "dd write error: $?"
9822         fid=$($LFS path2fid $DIR/$tfile)
9823
9824         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9825         then
9826                 check_ost=true
9827                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9828                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9829         else
9830                 echo "OSS do not support bulk pages dump upon error"
9831         fi
9832
9833         osc_file_prefix=$($LCTL get_param -n debug_path)
9834         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9835
9836         trap cleanup_77c EXIT
9837
9838         set_checksums 1
9839         # enable bulk pages dump upon error on Client
9840         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9841         # enable bulk pages dump upon error on OSS
9842         $check_ost &&
9843                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9844
9845         # flush Client cache to allow next read to reach OSS
9846         cancel_lru_locks osc
9847
9848         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9849         $LCTL set_param fail_loc=0x80000408
9850         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9851         $LCTL set_param fail_loc=0
9852
9853         rm -f $DIR/$tfile
9854
9855         # check cksum dump on Client
9856         osc_file=$(ls ${osc_file_prefix}*)
9857         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9858         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9859         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9860         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9861         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9862                      cksum)
9863         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9864         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9865                 error "dump content does not match on Client"
9866
9867         $check_ost || skip "No need to check cksum dump on OSS"
9868
9869         # check cksum dump on OSS
9870         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9871         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9872         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9873         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9874         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9875                 error "dump content does not match on OSS"
9876
9877         cleanup_77c
9878 }
9879 run_test 77c "checksum error on client read with debug"
9880
9881 test_77d() { # bug 10889
9882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9883         $GSS && skip_env "could not run with gss"
9884
9885         stack_trap "rm -f $DIR/$tfile"
9886         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9887         $LCTL set_param fail_loc=0x80000409
9888         set_checksums 1
9889         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9890                 error "direct write: rc=$?"
9891         $LCTL set_param fail_loc=0
9892         set_checksums 0
9893
9894         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9895         $LCTL set_param fail_loc=0x80000408
9896         set_checksums 1
9897         cancel_lru_locks osc
9898         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9899                 error "direct read: rc=$?"
9900         $LCTL set_param fail_loc=0
9901         set_checksums 0
9902 }
9903 run_test 77d "checksum error on OST direct write, read"
9904
9905 test_77f() { # bug 10889
9906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9907         $GSS && skip_env "could not run with gss"
9908
9909         set_checksums 1
9910         stack_trap "rm -f $DIR/$tfile"
9911         for algo in $CKSUM_TYPES; do
9912                 cancel_lru_locks osc
9913                 set_checksum_type $algo
9914                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9915                 $LCTL set_param fail_loc=0x409
9916                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9917                         error "direct write succeeded"
9918                 $LCTL set_param fail_loc=0
9919         done
9920         set_checksum_type $ORIG_CSUM_TYPE
9921         set_checksums 0
9922 }
9923 run_test 77f "repeat checksum error on write (expect error)"
9924
9925 test_77g() { # bug 10889
9926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9927         $GSS && skip_env "could not run with gss"
9928         remote_ost_nodsh && skip "remote OST with nodsh"
9929
9930         [ ! -f $F77_TMP ] && setup_f77
9931
9932         local file=$DIR/$tfile
9933         stack_trap "rm -f $file" EXIT
9934
9935         $LFS setstripe -c 1 -i 0 $file
9936         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9937         do_facet ost1 lctl set_param fail_loc=0x8000021a
9938         set_checksums 1
9939         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9940                 error "write error: rc=$?"
9941         do_facet ost1 lctl set_param fail_loc=0
9942         set_checksums 0
9943
9944         cancel_lru_locks osc
9945         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9946         do_facet ost1 lctl set_param fail_loc=0x8000021b
9947         set_checksums 1
9948         cmp $F77_TMP $file || error "file compare failed"
9949         do_facet ost1 lctl set_param fail_loc=0
9950         set_checksums 0
9951 }
9952 run_test 77g "checksum error on OST write, read"
9953
9954 test_77k() { # LU-10906
9955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9956         $GSS && skip_env "could not run with gss"
9957
9958         local cksum_param="osc.$FSNAME*.checksums"
9959         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9960         local checksum
9961         local i
9962
9963         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9964         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9965         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9966
9967         for i in 0 1; do
9968                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9969                         error "failed to set checksum=$i on MGS"
9970                 wait_update $HOSTNAME "$get_checksum" $i
9971                 #remount
9972                 echo "remount client, checksum should be $i"
9973                 remount_client $MOUNT || error "failed to remount client"
9974                 checksum=$(eval $get_checksum)
9975                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9976         done
9977         # remove persistent param to avoid races with checksum mountopt below
9978         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9979                 error "failed to delete checksum on MGS"
9980
9981         for opt in "checksum" "nochecksum"; do
9982                 #remount with mount option
9983                 echo "remount client with option $opt, checksum should be $i"
9984                 umount_client $MOUNT || error "failed to umount client"
9985                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9986                         error "failed to mount client with option '$opt'"
9987                 checksum=$(eval $get_checksum)
9988                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9989                 i=$((i - 1))
9990         done
9991
9992         remount_client $MOUNT || error "failed to remount client"
9993 }
9994 run_test 77k "enable/disable checksum correctly"
9995
9996 test_77l() {
9997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9998         $GSS && skip_env "could not run with gss"
9999
10000         set_checksums 1
10001         stack_trap "set_checksums $ORIG_CSUM" EXIT
10002         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10003
10004         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10005
10006         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10007         for algo in $CKSUM_TYPES; do
10008                 set_checksum_type $algo || error "fail to set checksum type $algo"
10009                 osc_algo=$(get_osc_checksum_type OST0000)
10010                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10011
10012                 # no locks, no reqs to let the connection idle
10013                 cancel_lru_locks osc
10014                 lru_resize_disable osc
10015                 wait_osc_import_state client ost1 IDLE
10016
10017                 # ensure ost1 is connected
10018                 stat $DIR/$tfile >/dev/null || error "can't stat"
10019                 wait_osc_import_state client ost1 FULL
10020
10021                 osc_algo=$(get_osc_checksum_type OST0000)
10022                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10023         done
10024         return 0
10025 }
10026 run_test 77l "preferred checksum type is remembered after reconnected"
10027
10028 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10029 rm -f $F77_TMP
10030 unset F77_TMP
10031
10032 test_77m() {
10033         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10034                 skip "Need at least version 2.14.52"
10035         local param=checksum_speed
10036
10037         $LCTL get_param $param || error "reading $param failed"
10038
10039         csum_speeds=$($LCTL get_param -n $param)
10040
10041         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10042                 error "known checksum types are missing"
10043 }
10044 run_test 77m "Verify checksum_speed is correctly read"
10045
10046 check_filefrag_77n() {
10047         local nr_ext=0
10048         local starts=()
10049         local ends=()
10050
10051         while read extidx a b start end rest; do
10052                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10053                         nr_ext=$(( $nr_ext + 1 ))
10054                         starts+=( ${start%..} )
10055                         ends+=( ${end%:} )
10056                 fi
10057         done < <( filefrag -sv $1 )
10058
10059         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10060         return 1
10061 }
10062
10063 test_77n() {
10064         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10065
10066         touch $DIR/$tfile
10067         $TRUNCATE $DIR/$tfile 0
10068         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10069         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10070         check_filefrag_77n $DIR/$tfile ||
10071                 skip "$tfile blocks not contiguous around hole"
10072
10073         set_checksums 1
10074         stack_trap "set_checksums $ORIG_CSUM" EXIT
10075         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10076         stack_trap "rm -f $DIR/$tfile"
10077
10078         for algo in $CKSUM_TYPES; do
10079                 if [[ "$algo" =~ ^t10 ]]; then
10080                         set_checksum_type $algo ||
10081                                 error "fail to set checksum type $algo"
10082                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10083                                 error "fail to read $tfile with $algo"
10084                 fi
10085         done
10086         rm -f $DIR/$tfile
10087         return 0
10088 }
10089 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10090
10091 test_77o() {
10092         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10093                 skip "Need MDS version at least 2.14.55"
10094         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10095                 skip "Need OST version at least 2.14.55"
10096         local ofd=obdfilter
10097         local mdt=mdt
10098
10099         # print OST checksum_type
10100         echo "$ofd.$FSNAME-*.checksum_type:"
10101         do_nodes $(comma_list $(osts_nodes)) \
10102                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10103
10104         # print MDT checksum_type
10105         echo "$mdt.$FSNAME-*.checksum_type:"
10106         do_nodes $(comma_list $(mdts_nodes)) \
10107                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10108
10109         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10110                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10111
10112         (( $o_count == $OSTCOUNT )) ||
10113                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10114
10115         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10116                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10117
10118         (( $m_count == $MDSCOUNT )) ||
10119                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10120 }
10121 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10122
10123 cleanup_test_78() {
10124         trap 0
10125         rm -f $DIR/$tfile
10126 }
10127
10128 test_78() { # bug 10901
10129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10130         remote_ost || skip_env "local OST"
10131
10132         NSEQ=5
10133         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10134         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10135         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10136         echo "MemTotal: $MEMTOTAL"
10137
10138         # reserve 256MB of memory for the kernel and other running processes,
10139         # and then take 1/2 of the remaining memory for the read/write buffers.
10140         if [ $MEMTOTAL -gt 512 ] ;then
10141                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10142         else
10143                 # for those poor memory-starved high-end clusters...
10144                 MEMTOTAL=$((MEMTOTAL / 2))
10145         fi
10146         echo "Mem to use for directio: $MEMTOTAL"
10147
10148         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10149         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10150         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10151         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10152                 head -n1)
10153         echo "Smallest OST: $SMALLESTOST"
10154         [[ $SMALLESTOST -lt 10240 ]] &&
10155                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10156
10157         trap cleanup_test_78 EXIT
10158
10159         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10160                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10161
10162         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10163         echo "File size: $F78SIZE"
10164         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10165         for i in $(seq 1 $NSEQ); do
10166                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10167                 echo directIO rdwr round $i of $NSEQ
10168                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10169         done
10170
10171         cleanup_test_78
10172 }
10173 run_test 78 "handle large O_DIRECT writes correctly ============"
10174
10175 test_79() { # bug 12743
10176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10177
10178         wait_delete_completed
10179
10180         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10181         BKFREE=$(calc_osc_kbytes kbytesfree)
10182         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10183
10184         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10185         DFTOTAL=`echo $STRING | cut -d, -f1`
10186         DFUSED=`echo $STRING  | cut -d, -f2`
10187         DFAVAIL=`echo $STRING | cut -d, -f3`
10188         DFFREE=$(($DFTOTAL - $DFUSED))
10189
10190         ALLOWANCE=$((64 * $OSTCOUNT))
10191
10192         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10193            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10194                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10195         fi
10196         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10197            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10198                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10199         fi
10200         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10201            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10202                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10203         fi
10204 }
10205 run_test 79 "df report consistency check ======================="
10206
10207 test_80() { # bug 10718
10208         remote_ost_nodsh && skip "remote OST with nodsh"
10209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10210
10211         # relax strong synchronous semantics for slow backends like ZFS
10212         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10213                 local soc="obdfilter.*.sync_lock_cancel"
10214                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10215
10216                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10217                 if [ -z "$save" ]; then
10218                         soc="obdfilter.*.sync_on_lock_cancel"
10219                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10220                 fi
10221
10222                 if [ "$save" != "never" ]; then
10223                         local hosts=$(comma_list $(osts_nodes))
10224
10225                         do_nodes $hosts $LCTL set_param $soc=never
10226                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10227                 fi
10228         fi
10229
10230         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10231         sync; sleep 1; sync
10232         local before=$(date +%s)
10233         cancel_lru_locks osc
10234         local after=$(date +%s)
10235         local diff=$((after - before))
10236         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10237
10238         rm -f $DIR/$tfile
10239 }
10240 run_test 80 "Page eviction is equally fast at high offsets too"
10241
10242 test_81a() { # LU-456
10243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10244         remote_ost_nodsh && skip "remote OST with nodsh"
10245
10246         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10247         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10248         do_facet ost1 lctl set_param fail_loc=0x80000228
10249
10250         # write should trigger a retry and success
10251         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10252         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10253         RC=$?
10254         if [ $RC -ne 0 ] ; then
10255                 error "write should success, but failed for $RC"
10256         fi
10257 }
10258 run_test 81a "OST should retry write when get -ENOSPC ==============="
10259
10260 test_81b() { # LU-456
10261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10262         remote_ost_nodsh && skip "remote OST with nodsh"
10263
10264         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10265         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10266         do_facet ost1 lctl set_param fail_loc=0x228
10267
10268         # write should retry several times and return -ENOSPC finally
10269         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10270         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10271         RC=$?
10272         ENOSPC=28
10273         if [ $RC -ne $ENOSPC ] ; then
10274                 error "dd should fail for -ENOSPC, but succeed."
10275         fi
10276 }
10277 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10278
10279 test_99() {
10280         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10281
10282         test_mkdir $DIR/$tdir.cvsroot
10283         chown $RUNAS_ID $DIR/$tdir.cvsroot
10284
10285         cd $TMP
10286         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10287
10288         cd /etc/init.d
10289         # some versions of cvs import exit(1) when asked to import links or
10290         # files they can't read.  ignore those files.
10291         local toignore=$(find . -type l -printf '-I %f\n' -o \
10292                          ! -perm /4 -printf '-I %f\n')
10293         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10294                 $tdir.reposname vtag rtag
10295
10296         cd $DIR
10297         test_mkdir $DIR/$tdir.reposname
10298         chown $RUNAS_ID $DIR/$tdir.reposname
10299         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10300
10301         cd $DIR/$tdir.reposname
10302         $RUNAS touch foo99
10303         $RUNAS cvs add -m 'addmsg' foo99
10304         $RUNAS cvs update
10305         $RUNAS cvs commit -m 'nomsg' foo99
10306         rm -fr $DIR/$tdir.cvsroot
10307 }
10308 run_test 99 "cvs strange file/directory operations"
10309
10310 test_100() {
10311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10312         [[ "$NETTYPE" =~ tcp ]] ||
10313                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10314         remote_ost_nodsh && skip "remote OST with nodsh"
10315         remote_mds_nodsh && skip "remote MDS with nodsh"
10316         remote_servers ||
10317                 skip "useless for local single node setup"
10318
10319         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10320                 [ "$PROT" != "tcp" ] && continue
10321                 RPORT=$(echo $REMOTE | cut -d: -f2)
10322                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10323
10324                 rc=0
10325                 LPORT=`echo $LOCAL | cut -d: -f2`
10326                 if [ $LPORT -ge 1024 ]; then
10327                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10328                         netstat -tna
10329                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10330                 fi
10331         done
10332         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10333 }
10334 run_test 100 "check local port using privileged port ==========="
10335
10336 function get_named_value()
10337 {
10338     local tag=$1
10339
10340     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10341 }
10342
10343 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10344                    awk '/^max_cached_mb/ { print $2 }')
10345
10346 cleanup_101a() {
10347         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10348         trap 0
10349 }
10350
10351 test_101a() {
10352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10353
10354         local s
10355         local discard
10356         local nreads=10000
10357         local cache_limit=32
10358
10359         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10360         trap cleanup_101a EXIT
10361         $LCTL set_param -n llite.*.read_ahead_stats=0
10362         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10363
10364         #
10365         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10366         #
10367         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10368         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10369
10370         discard=0
10371         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10372                    get_named_value 'read.but.discarded'); do
10373                         discard=$(($discard + $s))
10374         done
10375         cleanup_101a
10376
10377         $LCTL get_param osc.*-osc*.rpc_stats
10378         $LCTL get_param llite.*.read_ahead_stats
10379
10380         # Discard is generally zero, but sometimes a few random reads line up
10381         # and trigger larger readahead, which is wasted & leads to discards.
10382         if [[ $(($discard)) -gt $nreads ]]; then
10383                 error "too many ($discard) discarded pages"
10384         fi
10385         rm -f $DIR/$tfile || true
10386 }
10387 run_test 101a "check read-ahead for random reads"
10388
10389 setup_test101bc() {
10390         test_mkdir $DIR/$tdir
10391         local ssize=$1
10392         local FILE_LENGTH=$2
10393         STRIPE_OFFSET=0
10394
10395         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10396
10397         local list=$(comma_list $(osts_nodes))
10398         set_osd_param $list '' read_cache_enable 0
10399         set_osd_param $list '' writethrough_cache_enable 0
10400
10401         trap cleanup_test101bc EXIT
10402         # prepare the read-ahead file
10403         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10404
10405         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10406                                 count=$FILE_SIZE_MB 2> /dev/null
10407
10408 }
10409
10410 cleanup_test101bc() {
10411         trap 0
10412         rm -rf $DIR/$tdir
10413         rm -f $DIR/$tfile
10414
10415         local list=$(comma_list $(osts_nodes))
10416         set_osd_param $list '' read_cache_enable 1
10417         set_osd_param $list '' writethrough_cache_enable 1
10418 }
10419
10420 calc_total() {
10421         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10422 }
10423
10424 ra_check_101() {
10425         local read_size=$1
10426         local stripe_size=$2
10427         local stride_length=$((stripe_size / read_size))
10428         local stride_width=$((stride_length * OSTCOUNT))
10429         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
10430                                 (stride_width - stride_length) ))
10431         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
10432                   get_named_value 'read.but.discarded' | calc_total)
10433
10434         if [[ $discard -gt $discard_limit ]]; then
10435                 $LCTL get_param llite.*.read_ahead_stats
10436                 error "($discard) discarded pages with size (${read_size})"
10437         else
10438                 echo "Read-ahead success for size ${read_size}"
10439         fi
10440 }
10441
10442 test_101b() {
10443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10444         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10445
10446         local STRIPE_SIZE=1048576
10447         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10448
10449         if [ $SLOW == "yes" ]; then
10450                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10451         else
10452                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10453         fi
10454
10455         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10456
10457         # prepare the read-ahead file
10458         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10459         cancel_lru_locks osc
10460         for BIDX in 2 4 8 16 32 64 128 256
10461         do
10462                 local BSIZE=$((BIDX*4096))
10463                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10464                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10465                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10466                 $LCTL set_param -n llite.*.read_ahead_stats=0
10467                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10468                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10469                 cancel_lru_locks osc
10470                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10471         done
10472         cleanup_test101bc
10473         true
10474 }
10475 run_test 101b "check stride-io mode read-ahead ================="
10476
10477 test_101c() {
10478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10479
10480         local STRIPE_SIZE=1048576
10481         local FILE_LENGTH=$((STRIPE_SIZE*100))
10482         local nreads=10000
10483         local rsize=65536
10484         local osc_rpc_stats
10485
10486         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10487
10488         cancel_lru_locks osc
10489         $LCTL set_param osc.*.rpc_stats=0
10490         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10491         $LCTL get_param osc.*.rpc_stats
10492         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10493                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10494                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10495                 local size
10496
10497                 if [ $lines -le 20 ]; then
10498                         echo "continue debug"
10499                         continue
10500                 fi
10501                 for size in 1 2 4 8; do
10502                         local rpc=$(echo "$stats" |
10503                                     awk '($1 == "'$size':") {print $2; exit; }')
10504                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10505                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10506                 done
10507                 echo "$osc_rpc_stats check passed!"
10508         done
10509         cleanup_test101bc
10510         true
10511 }
10512 run_test 101c "check stripe_size aligned read-ahead"
10513
10514 test_101d() {
10515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10516
10517         local file=$DIR/$tfile
10518         local sz_MB=${FILESIZE_101d:-80}
10519         local ra_MB=${READAHEAD_MB:-40}
10520
10521         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10522         [ $free_MB -lt $sz_MB ] &&
10523                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10524
10525         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10526         $LFS setstripe -c -1 $file || error "setstripe failed"
10527
10528         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10529         echo Cancel LRU locks on lustre client to flush the client cache
10530         cancel_lru_locks osc
10531
10532         echo Disable read-ahead
10533         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10534         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10535         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10536         $LCTL get_param -n llite.*.max_read_ahead_mb
10537
10538         echo "Reading the test file $file with read-ahead disabled"
10539         local sz_KB=$((sz_MB * 1024 / 4))
10540         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10541         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10542         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10543                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10544
10545         echo "Cancel LRU locks on lustre client to flush the client cache"
10546         cancel_lru_locks osc
10547         echo Enable read-ahead with ${ra_MB}MB
10548         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10549
10550         echo "Reading the test file $file with read-ahead enabled"
10551         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10552                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10553
10554         echo "read-ahead disabled time read $raOFF"
10555         echo "read-ahead enabled time read $raON"
10556
10557         rm -f $file
10558         wait_delete_completed
10559
10560         # use awk for this check instead of bash because it handles decimals
10561         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10562                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10563 }
10564 run_test 101d "file read with and without read-ahead enabled"
10565
10566 test_101e() {
10567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10568
10569         local file=$DIR/$tfile
10570         local size_KB=500  #KB
10571         local count=100
10572         local bsize=1024
10573
10574         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10575         local need_KB=$((count * size_KB))
10576         [[ $free_KB -le $need_KB ]] &&
10577                 skip_env "Need free space $need_KB, have $free_KB"
10578
10579         echo "Creating $count ${size_KB}K test files"
10580         for ((i = 0; i < $count; i++)); do
10581                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10582         done
10583
10584         echo "Cancel LRU locks on lustre client to flush the client cache"
10585         cancel_lru_locks $OSC
10586
10587         echo "Reset readahead stats"
10588         $LCTL set_param -n llite.*.read_ahead_stats=0
10589
10590         for ((i = 0; i < $count; i++)); do
10591                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10592         done
10593
10594         $LCTL get_param llite.*.max_cached_mb
10595         $LCTL get_param llite.*.read_ahead_stats
10596         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10597                      get_named_value 'misses' | calc_total)
10598
10599         for ((i = 0; i < $count; i++)); do
10600                 rm -rf $file.$i 2>/dev/null
10601         done
10602
10603         #10000 means 20% reads are missing in readahead
10604         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10605 }
10606 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10607
10608 test_101f() {
10609         which iozone || skip_env "no iozone installed"
10610
10611         local old_debug=$($LCTL get_param debug)
10612         old_debug=${old_debug#*=}
10613         $LCTL set_param debug="reada mmap"
10614
10615         # create a test file
10616         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10617
10618         echo Cancel LRU locks on lustre client to flush the client cache
10619         cancel_lru_locks osc
10620
10621         echo Reset readahead stats
10622         $LCTL set_param -n llite.*.read_ahead_stats=0
10623
10624         echo mmap read the file with small block size
10625         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10626                 > /dev/null 2>&1
10627
10628         echo checking missing pages
10629         $LCTL get_param llite.*.read_ahead_stats
10630         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10631                         get_named_value 'misses' | calc_total)
10632
10633         $LCTL set_param debug="$old_debug"
10634         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10635         rm -f $DIR/$tfile
10636 }
10637 run_test 101f "check mmap read performance"
10638
10639 test_101g_brw_size_test() {
10640         local mb=$1
10641         local pages=$((mb * 1048576 / PAGE_SIZE))
10642         local file=$DIR/$tfile
10643
10644         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10645                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10646         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10647                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10648                         return 2
10649         done
10650
10651         stack_trap "rm -f $file" EXIT
10652         $LCTL set_param -n osc.*.rpc_stats=0
10653
10654         # 10 RPCs should be enough for the test
10655         local count=10
10656         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10657                 { error "dd write ${mb} MB blocks failed"; return 3; }
10658         cancel_lru_locks osc
10659         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10660                 { error "dd write ${mb} MB blocks failed"; return 4; }
10661
10662         # calculate number of full-sized read and write RPCs
10663         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10664                 sed -n '/pages per rpc/,/^$/p' |
10665                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10666                 END { print reads,writes }'))
10667         # allow one extra full-sized read RPC for async readahead
10668         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10669                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10670         [[ ${rpcs[1]} == $count ]] ||
10671                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10672 }
10673
10674 test_101g() {
10675         remote_ost_nodsh && skip "remote OST with nodsh"
10676
10677         local rpcs
10678         local osts=$(get_facets OST)
10679         local list=$(comma_list $(osts_nodes))
10680         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10681         local brw_size="obdfilter.*.brw_size"
10682
10683         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10684
10685         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10686
10687         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10688                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10689                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10690            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10691                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10692                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10693
10694                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10695                         suffix="M"
10696
10697                 if [[ $orig_mb -lt 16 ]]; then
10698                         save_lustre_params $osts "$brw_size" > $p
10699                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10700                                 error "set 16MB RPC size failed"
10701
10702                         echo "remount client to enable new RPC size"
10703                         remount_client $MOUNT || error "remount_client failed"
10704                 fi
10705
10706                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10707                 # should be able to set brw_size=12, but no rpc_stats for that
10708                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10709         fi
10710
10711         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10712
10713         if [[ $orig_mb -lt 16 ]]; then
10714                 restore_lustre_params < $p
10715                 remount_client $MOUNT || error "remount_client restore failed"
10716         fi
10717
10718         rm -f $p $DIR/$tfile
10719 }
10720 run_test 101g "Big bulk(4/16 MiB) readahead"
10721
10722 test_101h() {
10723         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10724
10725         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10726                 error "dd 70M file failed"
10727         echo Cancel LRU locks on lustre client to flush the client cache
10728         cancel_lru_locks osc
10729
10730         echo "Reset readahead stats"
10731         $LCTL set_param -n llite.*.read_ahead_stats 0
10732
10733         echo "Read 10M of data but cross 64M bundary"
10734         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10735         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10736                      get_named_value 'misses' | calc_total)
10737         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10738         rm -f $p $DIR/$tfile
10739 }
10740 run_test 101h "Readahead should cover current read window"
10741
10742 test_101i() {
10743         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10744                 error "dd 10M file failed"
10745
10746         local max_per_file_mb=$($LCTL get_param -n \
10747                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10748         cancel_lru_locks osc
10749         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10750         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10751                 error "set max_read_ahead_per_file_mb to 1 failed"
10752
10753         echo "Reset readahead stats"
10754         $LCTL set_param llite.*.read_ahead_stats=0
10755
10756         dd if=$DIR/$tfile of=/dev/null bs=2M
10757
10758         $LCTL get_param llite.*.read_ahead_stats
10759         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10760                      awk '/misses/ { print $2 }')
10761         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10762         rm -f $DIR/$tfile
10763 }
10764 run_test 101i "allow current readahead to exceed reservation"
10765
10766 test_101j() {
10767         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10768                 error "setstripe $DIR/$tfile failed"
10769         local file_size=$((1048576 * 16))
10770         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10771         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10772
10773         echo Disable read-ahead
10774         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10775
10776         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10777         for blk in $PAGE_SIZE 1048576 $file_size; do
10778                 cancel_lru_locks osc
10779                 echo "Reset readahead stats"
10780                 $LCTL set_param -n llite.*.read_ahead_stats=0
10781                 local count=$(($file_size / $blk))
10782                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10783                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10784                              get_named_value 'failed.to.fast.read' | calc_total)
10785                 $LCTL get_param -n llite.*.read_ahead_stats
10786                 [ $miss -eq $count ] || error "expected $count got $miss"
10787         done
10788
10789         rm -f $p $DIR/$tfile
10790 }
10791 run_test 101j "A complete read block should be submitted when no RA"
10792
10793 setup_test102() {
10794         test_mkdir $DIR/$tdir
10795         chown $RUNAS_ID $DIR/$tdir
10796         STRIPE_SIZE=65536
10797         STRIPE_OFFSET=1
10798         STRIPE_COUNT=$OSTCOUNT
10799         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10800
10801         trap cleanup_test102 EXIT
10802         cd $DIR
10803         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10804         cd $DIR/$tdir
10805         for num in 1 2 3 4; do
10806                 for count in $(seq 1 $STRIPE_COUNT); do
10807                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10808                                 local size=`expr $STRIPE_SIZE \* $num`
10809                                 local file=file"$num-$idx-$count"
10810                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10811                         done
10812                 done
10813         done
10814
10815         cd $DIR
10816         $1 tar cf $TMP/f102.tar $tdir --xattrs
10817 }
10818
10819 cleanup_test102() {
10820         trap 0
10821         rm -f $TMP/f102.tar
10822         rm -rf $DIR/d0.sanity/d102
10823 }
10824
10825 test_102a() {
10826         [ "$UID" != 0 ] && skip "must run as root"
10827         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10828                 skip_env "must have user_xattr"
10829
10830         [ -z "$(which setfattr 2>/dev/null)" ] &&
10831                 skip_env "could not find setfattr"
10832
10833         local testfile=$DIR/$tfile
10834
10835         touch $testfile
10836         echo "set/get xattr..."
10837         setfattr -n trusted.name1 -v value1 $testfile ||
10838                 error "setfattr -n trusted.name1=value1 $testfile failed"
10839         getfattr -n trusted.name1 $testfile 2> /dev/null |
10840           grep "trusted.name1=.value1" ||
10841                 error "$testfile missing trusted.name1=value1"
10842
10843         setfattr -n user.author1 -v author1 $testfile ||
10844                 error "setfattr -n user.author1=author1 $testfile failed"
10845         getfattr -n user.author1 $testfile 2> /dev/null |
10846           grep "user.author1=.author1" ||
10847                 error "$testfile missing trusted.author1=author1"
10848
10849         echo "listxattr..."
10850         setfattr -n trusted.name2 -v value2 $testfile ||
10851                 error "$testfile unable to set trusted.name2"
10852         setfattr -n trusted.name3 -v value3 $testfile ||
10853                 error "$testfile unable to set trusted.name3"
10854         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10855             grep "trusted.name" | wc -l) -eq 3 ] ||
10856                 error "$testfile missing 3 trusted.name xattrs"
10857
10858         setfattr -n user.author2 -v author2 $testfile ||
10859                 error "$testfile unable to set user.author2"
10860         setfattr -n user.author3 -v author3 $testfile ||
10861                 error "$testfile unable to set user.author3"
10862         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10863             grep "user.author" | wc -l) -eq 3 ] ||
10864                 error "$testfile missing 3 user.author xattrs"
10865
10866         echo "remove xattr..."
10867         setfattr -x trusted.name1 $testfile ||
10868                 error "$testfile error deleting trusted.name1"
10869         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10870                 error "$testfile did not delete trusted.name1 xattr"
10871
10872         setfattr -x user.author1 $testfile ||
10873                 error "$testfile error deleting user.author1"
10874         echo "set lustre special xattr ..."
10875         $LFS setstripe -c1 $testfile
10876         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10877                 awk -F "=" '/trusted.lov/ { print $2 }' )
10878         setfattr -n "trusted.lov" -v $lovea $testfile ||
10879                 error "$testfile doesn't ignore setting trusted.lov again"
10880         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10881                 error "$testfile allow setting invalid trusted.lov"
10882         rm -f $testfile
10883 }
10884 run_test 102a "user xattr test =================================="
10885
10886 check_102b_layout() {
10887         local layout="$*"
10888         local testfile=$DIR/$tfile
10889
10890         echo "test layout '$layout'"
10891         $LFS setstripe $layout $testfile || error "setstripe failed"
10892         $LFS getstripe -y $testfile
10893
10894         echo "get/set/list trusted.lov xattr ..." # b=10930
10895         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10896         [[ "$value" =~ "trusted.lov" ]] ||
10897                 error "can't get trusted.lov from $testfile"
10898         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10899                 error "getstripe failed"
10900
10901         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10902
10903         value=$(cut -d= -f2 <<<$value)
10904         # LU-13168: truncated xattr should fail if short lov_user_md header
10905         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10906                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10907         for len in $lens; do
10908                 echo "setfattr $len $testfile.2"
10909                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10910                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10911         done
10912         local stripe_size=$($LFS getstripe -S $testfile.2)
10913         local stripe_count=$($LFS getstripe -c $testfile.2)
10914         [[ $stripe_size -eq 65536 ]] ||
10915                 error "stripe size $stripe_size != 65536"
10916         [[ $stripe_count -eq $stripe_count_orig ]] ||
10917                 error "stripe count $stripe_count != $stripe_count_orig"
10918         rm $testfile $testfile.2
10919 }
10920
10921 test_102b() {
10922         [ -z "$(which setfattr 2>/dev/null)" ] &&
10923                 skip_env "could not find setfattr"
10924         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10925
10926         # check plain layout
10927         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10928
10929         # and also check composite layout
10930         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10931
10932 }
10933 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10934
10935 test_102c() {
10936         [ -z "$(which setfattr 2>/dev/null)" ] &&
10937                 skip_env "could not find setfattr"
10938         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10939
10940         # b10930: get/set/list lustre.lov xattr
10941         echo "get/set/list lustre.lov xattr ..."
10942         test_mkdir $DIR/$tdir
10943         chown $RUNAS_ID $DIR/$tdir
10944         local testfile=$DIR/$tdir/$tfile
10945         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10946                 error "setstripe failed"
10947         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10948                 error "getstripe failed"
10949         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10950         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10951
10952         local testfile2=${testfile}2
10953         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10954                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10955
10956         $RUNAS $MCREATE $testfile2
10957         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10958         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10959         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10960         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10961         [ $stripe_count -eq $STRIPECOUNT ] ||
10962                 error "stripe count $stripe_count != $STRIPECOUNT"
10963 }
10964 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10965
10966 compare_stripe_info1() {
10967         local stripe_index_all_zero=true
10968
10969         for num in 1 2 3 4; do
10970                 for count in $(seq 1 $STRIPE_COUNT); do
10971                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10972                                 local size=$((STRIPE_SIZE * num))
10973                                 local file=file"$num-$offset-$count"
10974                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10975                                 [[ $stripe_size -ne $size ]] &&
10976                                     error "$file: size $stripe_size != $size"
10977                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10978                                 # allow fewer stripes to be created, ORI-601
10979                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10980                                     error "$file: count $stripe_count != $count"
10981                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10982                                 [[ $stripe_index -ne 0 ]] &&
10983                                         stripe_index_all_zero=false
10984                         done
10985                 done
10986         done
10987         $stripe_index_all_zero &&
10988                 error "all files are being extracted starting from OST index 0"
10989         return 0
10990 }
10991
10992 have_xattrs_include() {
10993         tar --help | grep -q xattrs-include &&
10994                 echo --xattrs-include="lustre.*"
10995 }
10996
10997 test_102d() {
10998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10999         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11000
11001         XINC=$(have_xattrs_include)
11002         setup_test102
11003         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11004         cd $DIR/$tdir/$tdir
11005         compare_stripe_info1
11006 }
11007 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11008
11009 test_102f() {
11010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11011         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11012
11013         XINC=$(have_xattrs_include)
11014         setup_test102
11015         test_mkdir $DIR/$tdir.restore
11016         cd $DIR
11017         tar cf - --xattrs $tdir | tar xf - \
11018                 -C $DIR/$tdir.restore --xattrs $XINC
11019         cd $DIR/$tdir.restore/$tdir
11020         compare_stripe_info1
11021 }
11022 run_test 102f "tar copy files, not keep osts"
11023
11024 grow_xattr() {
11025         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11026                 skip "must have user_xattr"
11027         [ -z "$(which setfattr 2>/dev/null)" ] &&
11028                 skip_env "could not find setfattr"
11029         [ -z "$(which getfattr 2>/dev/null)" ] &&
11030                 skip_env "could not find getfattr"
11031
11032         local xsize=${1:-1024}  # in bytes
11033         local file=$DIR/$tfile
11034         local value="$(generate_string $xsize)"
11035         local xbig=trusted.big
11036         local toobig=$2
11037
11038         touch $file
11039         log "save $xbig on $file"
11040         if [ -z "$toobig" ]
11041         then
11042                 setfattr -n $xbig -v $value $file ||
11043                         error "saving $xbig on $file failed"
11044         else
11045                 setfattr -n $xbig -v $value $file &&
11046                         error "saving $xbig on $file succeeded"
11047                 return 0
11048         fi
11049
11050         local orig=$(get_xattr_value $xbig $file)
11051         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11052
11053         local xsml=trusted.sml
11054         log "save $xsml on $file"
11055         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11056
11057         local new=$(get_xattr_value $xbig $file)
11058         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11059
11060         log "grow $xsml on $file"
11061         setfattr -n $xsml -v "$value" $file ||
11062                 error "growing $xsml on $file failed"
11063
11064         new=$(get_xattr_value $xbig $file)
11065         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11066         log "$xbig still valid after growing $xsml"
11067
11068         rm -f $file
11069 }
11070
11071 test_102h() { # bug 15777
11072         grow_xattr 1024
11073 }
11074 run_test 102h "grow xattr from inside inode to external block"
11075
11076 test_102ha() {
11077         large_xattr_enabled || skip_env "ea_inode feature disabled"
11078
11079         echo "setting xattr of max xattr size: $(max_xattr_size)"
11080         grow_xattr $(max_xattr_size)
11081
11082         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11083         echo "This should fail:"
11084         grow_xattr $(($(max_xattr_size) + 10)) 1
11085 }
11086 run_test 102ha "grow xattr from inside inode to external inode"
11087
11088 test_102i() { # bug 17038
11089         [ -z "$(which getfattr 2>/dev/null)" ] &&
11090                 skip "could not find getfattr"
11091
11092         touch $DIR/$tfile
11093         ln -s $DIR/$tfile $DIR/${tfile}link
11094         getfattr -n trusted.lov $DIR/$tfile ||
11095                 error "lgetxattr on $DIR/$tfile failed"
11096         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11097                 grep -i "no such attr" ||
11098                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11099         rm -f $DIR/$tfile $DIR/${tfile}link
11100 }
11101 run_test 102i "lgetxattr test on symbolic link ============"
11102
11103 test_102j() {
11104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11105         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11106
11107         XINC=$(have_xattrs_include)
11108         setup_test102 "$RUNAS"
11109         chown $RUNAS_ID $DIR/$tdir
11110         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11111         cd $DIR/$tdir/$tdir
11112         compare_stripe_info1 "$RUNAS"
11113 }
11114 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11115
11116 test_102k() {
11117         [ -z "$(which setfattr 2>/dev/null)" ] &&
11118                 skip "could not find setfattr"
11119
11120         touch $DIR/$tfile
11121         # b22187 just check that does not crash for regular file.
11122         setfattr -n trusted.lov $DIR/$tfile
11123         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11124         local test_kdir=$DIR/$tdir
11125         test_mkdir $test_kdir
11126         local default_size=$($LFS getstripe -S $test_kdir)
11127         local default_count=$($LFS getstripe -c $test_kdir)
11128         local default_offset=$($LFS getstripe -i $test_kdir)
11129         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11130                 error 'dir setstripe failed'
11131         setfattr -n trusted.lov $test_kdir
11132         local stripe_size=$($LFS getstripe -S $test_kdir)
11133         local stripe_count=$($LFS getstripe -c $test_kdir)
11134         local stripe_offset=$($LFS getstripe -i $test_kdir)
11135         [ $stripe_size -eq $default_size ] ||
11136                 error "stripe size $stripe_size != $default_size"
11137         [ $stripe_count -eq $default_count ] ||
11138                 error "stripe count $stripe_count != $default_count"
11139         [ $stripe_offset -eq $default_offset ] ||
11140                 error "stripe offset $stripe_offset != $default_offset"
11141         rm -rf $DIR/$tfile $test_kdir
11142 }
11143 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11144
11145 test_102l() {
11146         [ -z "$(which getfattr 2>/dev/null)" ] &&
11147                 skip "could not find getfattr"
11148
11149         # LU-532 trusted. xattr is invisible to non-root
11150         local testfile=$DIR/$tfile
11151
11152         touch $testfile
11153
11154         echo "listxattr as user..."
11155         chown $RUNAS_ID $testfile
11156         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11157             grep -q "trusted" &&
11158                 error "$testfile trusted xattrs are user visible"
11159
11160         return 0;
11161 }
11162 run_test 102l "listxattr size test =================================="
11163
11164 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11165         local path=$DIR/$tfile
11166         touch $path
11167
11168         listxattr_size_check $path || error "listattr_size_check $path failed"
11169 }
11170 run_test 102m "Ensure listxattr fails on small bufffer ========"
11171
11172 cleanup_test102
11173
11174 getxattr() { # getxattr path name
11175         # Return the base64 encoding of the value of xattr name on path.
11176         local path=$1
11177         local name=$2
11178
11179         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11180         # file: $path
11181         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11182         #
11183         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11184
11185         getfattr --absolute-names --encoding=base64 --name=$name $path |
11186                 awk -F= -v name=$name '$1 == name {
11187                         print substr($0, index($0, "=") + 1);
11188         }'
11189 }
11190
11191 test_102n() { # LU-4101 mdt: protect internal xattrs
11192         [ -z "$(which setfattr 2>/dev/null)" ] &&
11193                 skip "could not find setfattr"
11194         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11195         then
11196                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11197         fi
11198
11199         local file0=$DIR/$tfile.0
11200         local file1=$DIR/$tfile.1
11201         local xattr0=$TMP/$tfile.0
11202         local xattr1=$TMP/$tfile.1
11203         local namelist="lov lma lmv link fid version som hsm"
11204         local name
11205         local value
11206
11207         rm -rf $file0 $file1 $xattr0 $xattr1
11208         touch $file0 $file1
11209
11210         # Get 'before' xattrs of $file1.
11211         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11212
11213         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11214                 namelist+=" lfsck_namespace"
11215         for name in $namelist; do
11216                 # Try to copy xattr from $file0 to $file1.
11217                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11218
11219                 setfattr --name=trusted.$name --value="$value" $file1 ||
11220                         error "setxattr 'trusted.$name' failed"
11221
11222                 # Try to set a garbage xattr.
11223                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11224
11225                 if [[ x$name == "xlov" ]]; then
11226                         setfattr --name=trusted.lov --value="$value" $file1 &&
11227                         error "setxattr invalid 'trusted.lov' success"
11228                 else
11229                         setfattr --name=trusted.$name --value="$value" $file1 ||
11230                                 error "setxattr invalid 'trusted.$name' failed"
11231                 fi
11232
11233                 # Try to remove the xattr from $file1. We don't care if this
11234                 # appears to succeed or fail, we just don't want there to be
11235                 # any changes or crashes.
11236                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11237         done
11238
11239         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11240         then
11241                 name="lfsck_ns"
11242                 # Try to copy xattr from $file0 to $file1.
11243                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11244
11245                 setfattr --name=trusted.$name --value="$value" $file1 ||
11246                         error "setxattr 'trusted.$name' failed"
11247
11248                 # Try to set a garbage xattr.
11249                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11250
11251                 setfattr --name=trusted.$name --value="$value" $file1 ||
11252                         error "setxattr 'trusted.$name' failed"
11253
11254                 # Try to remove the xattr from $file1. We don't care if this
11255                 # appears to succeed or fail, we just don't want there to be
11256                 # any changes or crashes.
11257                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11258         fi
11259
11260         # Get 'after' xattrs of file1.
11261         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11262
11263         if ! diff $xattr0 $xattr1; then
11264                 error "before and after xattrs of '$file1' differ"
11265         fi
11266
11267         rm -rf $file0 $file1 $xattr0 $xattr1
11268
11269         return 0
11270 }
11271 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11272
11273 test_102p() { # LU-4703 setxattr did not check ownership
11274         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11275                 skip "MDS needs to be at least 2.5.56"
11276
11277         local testfile=$DIR/$tfile
11278
11279         touch $testfile
11280
11281         echo "setfacl as user..."
11282         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11283         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11284
11285         echo "setfattr as user..."
11286         setfacl -m "u:$RUNAS_ID:---" $testfile
11287         $RUNAS setfattr -x system.posix_acl_access $testfile
11288         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11289 }
11290 run_test 102p "check setxattr(2) correctly fails without permission"
11291
11292 test_102q() {
11293         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11294                 skip "MDS needs to be at least 2.6.92"
11295
11296         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11297 }
11298 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11299
11300 test_102r() {
11301         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11302                 skip "MDS needs to be at least 2.6.93"
11303
11304         touch $DIR/$tfile || error "touch"
11305         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11306         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11307         rm $DIR/$tfile || error "rm"
11308
11309         #normal directory
11310         mkdir -p $DIR/$tdir || error "mkdir"
11311         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11312         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11313         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11314                 error "$testfile error deleting user.author1"
11315         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11316                 grep "user.$(basename $tdir)" &&
11317                 error "$tdir did not delete user.$(basename $tdir)"
11318         rmdir $DIR/$tdir || error "rmdir"
11319
11320         #striped directory
11321         test_mkdir $DIR/$tdir
11322         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11323         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11324         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11325                 error "$testfile error deleting user.author1"
11326         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11327                 grep "user.$(basename $tdir)" &&
11328                 error "$tdir did not delete user.$(basename $tdir)"
11329         rmdir $DIR/$tdir || error "rm striped dir"
11330 }
11331 run_test 102r "set EAs with empty values"
11332
11333 test_102s() {
11334         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11335                 skip "MDS needs to be at least 2.11.52"
11336
11337         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11338
11339         save_lustre_params client "llite.*.xattr_cache" > $save
11340
11341         for cache in 0 1; do
11342                 lctl set_param llite.*.xattr_cache=$cache
11343
11344                 rm -f $DIR/$tfile
11345                 touch $DIR/$tfile || error "touch"
11346                 for prefix in lustre security system trusted user; do
11347                         # Note getxattr() may fail with 'Operation not
11348                         # supported' or 'No such attribute' depending
11349                         # on prefix and cache.
11350                         getfattr -n $prefix.n102s $DIR/$tfile &&
11351                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11352                 done
11353         done
11354
11355         restore_lustre_params < $save
11356 }
11357 run_test 102s "getting nonexistent xattrs should fail"
11358
11359 test_102t() {
11360         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11361                 skip "MDS needs to be at least 2.11.52"
11362
11363         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11364
11365         save_lustre_params client "llite.*.xattr_cache" > $save
11366
11367         for cache in 0 1; do
11368                 lctl set_param llite.*.xattr_cache=$cache
11369
11370                 for buf_size in 0 256; do
11371                         rm -f $DIR/$tfile
11372                         touch $DIR/$tfile || error "touch"
11373                         setfattr -n user.multiop $DIR/$tfile
11374                         $MULTIOP $DIR/$tfile oa$buf_size ||
11375                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11376                 done
11377         done
11378
11379         restore_lustre_params < $save
11380 }
11381 run_test 102t "zero length xattr values handled correctly"
11382
11383 run_acl_subtest()
11384 {
11385     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11386     return $?
11387 }
11388
11389 test_103a() {
11390         [ "$UID" != 0 ] && skip "must run as root"
11391         $GSS && skip_env "could not run under gss"
11392         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11393                 skip_env "must have acl enabled"
11394         [ -z "$(which setfacl 2>/dev/null)" ] &&
11395                 skip_env "could not find setfacl"
11396         remote_mds_nodsh && skip "remote MDS with nodsh"
11397
11398         gpasswd -a daemon bin                           # LU-5641
11399         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11400
11401         declare -a identity_old
11402
11403         for num in $(seq $MDSCOUNT); do
11404                 switch_identity $num true || identity_old[$num]=$?
11405         done
11406
11407         SAVE_UMASK=$(umask)
11408         umask 0022
11409         mkdir -p $DIR/$tdir
11410         cd $DIR/$tdir
11411
11412         echo "performing cp ..."
11413         run_acl_subtest cp || error "run_acl_subtest cp failed"
11414         echo "performing getfacl-noacl..."
11415         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11416         echo "performing misc..."
11417         run_acl_subtest misc || error  "misc test failed"
11418         echo "performing permissions..."
11419         run_acl_subtest permissions || error "permissions failed"
11420         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11421         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11422                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11423                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11424         then
11425                 echo "performing permissions xattr..."
11426                 run_acl_subtest permissions_xattr ||
11427                         error "permissions_xattr failed"
11428         fi
11429         echo "performing setfacl..."
11430         run_acl_subtest setfacl || error  "setfacl test failed"
11431
11432         # inheritance test got from HP
11433         echo "performing inheritance..."
11434         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11435         chmod +x make-tree || error "chmod +x failed"
11436         run_acl_subtest inheritance || error "inheritance test failed"
11437         rm -f make-tree
11438
11439         echo "LU-974 ignore umask when acl is enabled..."
11440         run_acl_subtest 974 || error "LU-974 umask test failed"
11441         if [ $MDSCOUNT -ge 2 ]; then
11442                 run_acl_subtest 974_remote ||
11443                         error "LU-974 umask test failed under remote dir"
11444         fi
11445
11446         echo "LU-2561 newly created file is same size as directory..."
11447         if [ "$mds1_FSTYPE" != "zfs" ]; then
11448                 run_acl_subtest 2561 || error "LU-2561 test failed"
11449         else
11450                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11451         fi
11452
11453         run_acl_subtest 4924 || error "LU-4924 test failed"
11454
11455         cd $SAVE_PWD
11456         umask $SAVE_UMASK
11457
11458         for num in $(seq $MDSCOUNT); do
11459                 if [ "${identity_old[$num]}" = 1 ]; then
11460                         switch_identity $num false || identity_old[$num]=$?
11461                 fi
11462         done
11463 }
11464 run_test 103a "acl test"
11465
11466 test_103b() {
11467         declare -a pids
11468         local U
11469
11470         for U in {0..511}; do
11471                 {
11472                 local O=$(printf "%04o" $U)
11473
11474                 umask $(printf "%04o" $((511 ^ $O)))
11475                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11476                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11477
11478                 (( $S == ($O & 0666) )) ||
11479                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11480
11481                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11482                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11483                 (( $S == ($O & 0666) )) ||
11484                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11485
11486                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11487                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11488                 (( $S == ($O & 0666) )) ||
11489                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11490                 rm -f $DIR/$tfile.[smp]$0
11491                 } &
11492                 local pid=$!
11493
11494                 # limit the concurrently running threads to 64. LU-11878
11495                 local idx=$((U % 64))
11496                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11497                 pids[idx]=$pid
11498         done
11499         wait
11500 }
11501 run_test 103b "umask lfs setstripe"
11502
11503 test_103c() {
11504         mkdir -p $DIR/$tdir
11505         cp -rp $DIR/$tdir $DIR/$tdir.bak
11506
11507         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11508                 error "$DIR/$tdir shouldn't contain default ACL"
11509         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11510                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11511         true
11512 }
11513 run_test 103c "'cp -rp' won't set empty acl"
11514
11515 test_103e() {
11516         local numacl
11517         local fileacl
11518         local saved_debug=$($LCTL get_param -n debug)
11519
11520         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
11521                 skip "MDS needs to be at least 2.14.52"
11522
11523         large_xattr_enabled || skip_env "ea_inode feature disabled"
11524
11525         mkdir -p $DIR/$tdir
11526         # add big LOV EA to cause reply buffer overflow earlier
11527         $LFS setstripe -C 1000 $DIR/$tdir
11528         lctl set_param mdc.*-mdc*.stats=clear
11529
11530         $LCTL set_param debug=0
11531         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11532         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11533
11534         # add a large number of default ACLs (expect 8000+ for 2.13+)
11535         for U in {2..7000}; do
11536                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11537                         error "Able to add just $U default ACLs"
11538         done
11539         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11540         echo "$numacl default ACLs created"
11541
11542         stat $DIR/$tdir || error "Cannot stat directory"
11543         # check file creation
11544         touch $DIR/$tdir/$tfile ||
11545                 error "failed to create $tfile with $numacl default ACLs"
11546         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11547         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11548         echo "$fileacl ACLs were inherited"
11549         (( $fileacl == $numacl )) ||
11550                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11551         # check that new ACLs creation adds new ACLs to inherited ACLs
11552         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11553                 error "Cannot set new ACL"
11554         numacl=$((numacl + 1))
11555         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11556         (( $fileacl == $numacl )) ||
11557                 error "failed to add new ACL: $fileacl != $numacl as expected"
11558         # adds more ACLs to a file to reach their maximum at 8000+
11559         numacl=0
11560         for U in {20000..25000}; do
11561                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11562                 numacl=$((numacl + 1))
11563         done
11564         echo "Added $numacl more ACLs to the file"
11565         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11566         echo "Total $fileacl ACLs in file"
11567         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11568         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11569         rmdir $DIR/$tdir || error "Cannot remove directory"
11570 }
11571 run_test 103e "inheritance of big amount of default ACLs"
11572
11573 test_103f() {
11574         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11575                 skip "MDS needs to be at least 2.14.51"
11576
11577         large_xattr_enabled || skip_env "ea_inode feature disabled"
11578
11579         # enable changelog to consume more internal MDD buffers
11580         changelog_register
11581
11582         mkdir -p $DIR/$tdir
11583         # add big LOV EA
11584         $LFS setstripe -C 1000 $DIR/$tdir
11585         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11586         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11587         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11588         rmdir $DIR/$tdir || error "Cannot remove directory"
11589 }
11590 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11591
11592 test_104a() {
11593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11594
11595         touch $DIR/$tfile
11596         lfs df || error "lfs df failed"
11597         lfs df -ih || error "lfs df -ih failed"
11598         lfs df -h $DIR || error "lfs df -h $DIR failed"
11599         lfs df -i $DIR || error "lfs df -i $DIR failed"
11600         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11601         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11602
11603         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11604         lctl --device %$OSC deactivate
11605         lfs df || error "lfs df with deactivated OSC failed"
11606         lctl --device %$OSC activate
11607         # wait the osc back to normal
11608         wait_osc_import_ready client ost
11609
11610         lfs df || error "lfs df with reactivated OSC failed"
11611         rm -f $DIR/$tfile
11612 }
11613 run_test 104a "lfs df [-ih] [path] test ========================="
11614
11615 test_104b() {
11616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11617         [ $RUNAS_ID -eq $UID ] &&
11618                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11619
11620         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11621                         grep "Permission denied" | wc -l)))
11622         if [ $denied_cnt -ne 0 ]; then
11623                 error "lfs check servers test failed"
11624         fi
11625 }
11626 run_test 104b "$RUNAS lfs check servers test ===================="
11627
11628 #
11629 # Verify $1 is within range of $2.
11630 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11631 # $1 is <= 2% of $2. Else Fail.
11632 #
11633 value_in_range() {
11634         # Strip all units (M, G, T)
11635         actual=$(echo $1 | tr -d A-Z)
11636         expect=$(echo $2 | tr -d A-Z)
11637
11638         expect_lo=$(($expect * 98 / 100)) # 2% below
11639         expect_hi=$(($expect * 102 / 100)) # 2% above
11640
11641         # permit 2% drift above and below
11642         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11643 }
11644
11645 test_104c() {
11646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11647         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11648
11649         local ost_param="osd-zfs.$FSNAME-OST0000."
11650         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11651         local ofacets=$(get_facets OST)
11652         local mfacets=$(get_facets MDS)
11653         local saved_ost_blocks=
11654         local saved_mdt_blocks=
11655
11656         echo "Before recordsize change"
11657         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11658         df=($(df -h | grep "$MOUNT"$))
11659
11660         # For checking.
11661         echo "lfs output : ${lfs_df[*]}"
11662         echo "df  output : ${df[*]}"
11663
11664         for facet in ${ofacets//,/ }; do
11665                 if [ -z $saved_ost_blocks ]; then
11666                         saved_ost_blocks=$(do_facet $facet \
11667                                 lctl get_param -n $ost_param.blocksize)
11668                         echo "OST Blocksize: $saved_ost_blocks"
11669                 fi
11670                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11671                 do_facet $facet zfs set recordsize=32768 $ost
11672         done
11673
11674         # BS too small. Sufficient for functional testing.
11675         for facet in ${mfacets//,/ }; do
11676                 if [ -z $saved_mdt_blocks ]; then
11677                         saved_mdt_blocks=$(do_facet $facet \
11678                                 lctl get_param -n $mdt_param.blocksize)
11679                         echo "MDT Blocksize: $saved_mdt_blocks"
11680                 fi
11681                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11682                 do_facet $facet zfs set recordsize=32768 $mdt
11683         done
11684
11685         # Give new values chance to reflect change
11686         sleep 2
11687
11688         echo "After recordsize change"
11689         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11690         df_after=($(df -h | grep "$MOUNT"$))
11691
11692         # For checking.
11693         echo "lfs output : ${lfs_df_after[*]}"
11694         echo "df  output : ${df_after[*]}"
11695
11696         # Verify lfs df
11697         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11698                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11699         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11700                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11701         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11702                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11703
11704         # Verify df
11705         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11706                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11707         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11708                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11709         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11710                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11711
11712         # Restore MDT recordize back to original
11713         for facet in ${mfacets//,/ }; do
11714                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11715                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11716         done
11717
11718         # Restore OST recordize back to original
11719         for facet in ${ofacets//,/ }; do
11720                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11721                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11722         done
11723
11724         return 0
11725 }
11726 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11727
11728 test_105a() {
11729         # doesn't work on 2.4 kernels
11730         touch $DIR/$tfile
11731         if $(flock_is_enabled); then
11732                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11733         else
11734                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11735         fi
11736         rm -f $DIR/$tfile
11737 }
11738 run_test 105a "flock when mounted without -o flock test ========"
11739
11740 test_105b() {
11741         touch $DIR/$tfile
11742         if $(flock_is_enabled); then
11743                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11744         else
11745                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11746         fi
11747         rm -f $DIR/$tfile
11748 }
11749 run_test 105b "fcntl when mounted without -o flock test ========"
11750
11751 test_105c() {
11752         touch $DIR/$tfile
11753         if $(flock_is_enabled); then
11754                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11755         else
11756                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11757         fi
11758         rm -f $DIR/$tfile
11759 }
11760 run_test 105c "lockf when mounted without -o flock test"
11761
11762 test_105d() { # bug 15924
11763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11764
11765         test_mkdir $DIR/$tdir
11766         flock_is_enabled || skip_env "mount w/o flock enabled"
11767         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11768         $LCTL set_param fail_loc=0x80000315
11769         flocks_test 2 $DIR/$tdir
11770 }
11771 run_test 105d "flock race (should not freeze) ========"
11772
11773 test_105e() { # bug 22660 && 22040
11774         flock_is_enabled || skip_env "mount w/o flock enabled"
11775
11776         touch $DIR/$tfile
11777         flocks_test 3 $DIR/$tfile
11778 }
11779 run_test 105e "Two conflicting flocks from same process"
11780
11781 test_106() { #bug 10921
11782         test_mkdir $DIR/$tdir
11783         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11784         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11785 }
11786 run_test 106 "attempt exec of dir followed by chown of that dir"
11787
11788 test_107() {
11789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11790
11791         CDIR=`pwd`
11792         local file=core
11793
11794         cd $DIR
11795         rm -f $file
11796
11797         local save_pattern=$(sysctl -n kernel.core_pattern)
11798         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11799         sysctl -w kernel.core_pattern=$file
11800         sysctl -w kernel.core_uses_pid=0
11801
11802         ulimit -c unlimited
11803         sleep 60 &
11804         SLEEPPID=$!
11805
11806         sleep 1
11807
11808         kill -s 11 $SLEEPPID
11809         wait $SLEEPPID
11810         if [ -e $file ]; then
11811                 size=`stat -c%s $file`
11812                 [ $size -eq 0 ] && error "Fail to create core file $file"
11813         else
11814                 error "Fail to create core file $file"
11815         fi
11816         rm -f $file
11817         sysctl -w kernel.core_pattern=$save_pattern
11818         sysctl -w kernel.core_uses_pid=$save_uses_pid
11819         cd $CDIR
11820 }
11821 run_test 107 "Coredump on SIG"
11822
11823 test_110() {
11824         test_mkdir $DIR/$tdir
11825         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11826         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11827                 error "mkdir with 256 char should fail, but did not"
11828         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11829                 error "create with 255 char failed"
11830         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11831                 error "create with 256 char should fail, but did not"
11832
11833         ls -l $DIR/$tdir
11834         rm -rf $DIR/$tdir
11835 }
11836 run_test 110 "filename length checking"
11837
11838 #
11839 # Purpose: To verify dynamic thread (OSS) creation.
11840 #
11841 test_115() {
11842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11843         remote_ost_nodsh && skip "remote OST with nodsh"
11844
11845         # Lustre does not stop service threads once they are started.
11846         # Reset number of running threads to default.
11847         stopall
11848         setupall
11849
11850         local OSTIO_pre
11851         local save_params="$TMP/sanity-$TESTNAME.parameters"
11852
11853         # Get ll_ost_io count before I/O
11854         OSTIO_pre=$(do_facet ost1 \
11855                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11856         # Exit if lustre is not running (ll_ost_io not running).
11857         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11858
11859         echo "Starting with $OSTIO_pre threads"
11860         local thread_max=$((OSTIO_pre * 2))
11861         local rpc_in_flight=$((thread_max * 2))
11862         # this is limited to OSC_MAX_RIF_MAX (256)
11863         [ $rpc_in_flight -gt 256 ] && rpc_in_flight=256
11864         thread_max=$((rpc_in_flight / 2))
11865         [ $thread_max -le $OSTIO_pre ] && skip "Too many ost_io threads" &&
11866                 return
11867
11868         # Number of I/O Process proposed to be started.
11869         local nfiles
11870         local facets=$(get_facets OST)
11871
11872         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11873         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11874
11875         # Set in_flight to $rpc_in_flight
11876         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11877                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11878         nfiles=${rpc_in_flight}
11879         # Set ost thread_max to $thread_max
11880         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11881
11882         # 5 Minutes should be sufficient for max number of OSS
11883         # threads(thread_max) to be created.
11884         local timeout=300
11885
11886         # Start I/O.
11887         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11888         test_mkdir $DIR/$tdir
11889         for i in $(seq $nfiles); do
11890                 local file=$DIR/$tdir/${tfile}-$i
11891                 $LFS setstripe -c -1 -i 0 $file
11892                 ($WTL $file $timeout)&
11893         done
11894
11895         # I/O Started - Wait for thread_started to reach thread_max or report
11896         # error if thread_started is more than thread_max.
11897         echo "Waiting for thread_started to reach thread_max"
11898         local thread_started=0
11899         local end_time=$((SECONDS + timeout))
11900
11901         while [ $SECONDS -le $end_time ] ; do
11902                 echo -n "."
11903                 # Get ost i/o thread_started count.
11904                 thread_started=$(do_facet ost1 \
11905                         "$LCTL get_param \
11906                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11907                 # Break out if thread_started is equal/greater than thread_max
11908                 if [[ $thread_started -ge $thread_max ]]; then
11909                         echo ll_ost_io thread_started $thread_started, \
11910                                 equal/greater than thread_max $thread_max
11911                         break
11912                 fi
11913                 sleep 1
11914         done
11915
11916         # Cleanup - We have the numbers, Kill i/o jobs if running.
11917         jobcount=($(jobs -p))
11918         for i in $(seq 0 $((${#jobcount[@]}-1)))
11919         do
11920                 kill -9 ${jobcount[$i]}
11921                 if [ $? -ne 0 ] ; then
11922                         echo Warning: \
11923                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11924                 fi
11925         done
11926
11927         # Cleanup files left by WTL binary.
11928         for i in $(seq $nfiles); do
11929                 local file=$DIR/$tdir/${tfile}-$i
11930                 rm -rf $file
11931                 if [ $? -ne 0 ] ; then
11932                         echo "Warning: Failed to delete file $file"
11933                 fi
11934         done
11935
11936         restore_lustre_params <$save_params
11937         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11938
11939         # Error out if no new thread has started or Thread started is greater
11940         # than thread max.
11941         if [[ $thread_started -le $OSTIO_pre ||
11942                         $thread_started -gt $thread_max ]]; then
11943                 error "ll_ost_io: thread_started $thread_started" \
11944                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11945                       "No new thread started or thread started greater " \
11946                       "than thread_max."
11947         fi
11948 }
11949 run_test 115 "verify dynamic thread creation===================="
11950
11951 test_116a() { # was previously test_116()
11952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11953         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11954         remote_mds_nodsh && skip "remote MDS with nodsh"
11955
11956         echo -n "Free space priority "
11957         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11958                 head -n1
11959         declare -a AVAIL
11960         free_min_max
11961
11962         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11963         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11964         stack_trap simple_cleanup_common
11965
11966         # Check if we need to generate uneven OSTs
11967         test_mkdir -p $DIR/$tdir/OST${MINI}
11968         local FILL=$((MINV / 4))
11969         local DIFF=$((MAXV - MINV))
11970         local DIFF2=$((DIFF * 100 / MINV))
11971
11972         local threshold=$(do_facet $SINGLEMDS \
11973                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11974         threshold=${threshold%%%}
11975         echo -n "Check for uneven OSTs: "
11976         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11977
11978         if [[ $DIFF2 -gt $threshold ]]; then
11979                 echo "ok"
11980                 echo "Don't need to fill OST$MINI"
11981         else
11982                 # generate uneven OSTs. Write 2% over the QOS threshold value
11983                 echo "no"
11984                 DIFF=$((threshold - DIFF2 + 2))
11985                 DIFF2=$((MINV * DIFF / 100))
11986                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11987                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11988                         error "setstripe failed"
11989                 DIFF=$((DIFF2 / 2048))
11990                 i=0
11991                 while [ $i -lt $DIFF ]; do
11992                         i=$((i + 1))
11993                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11994                                 bs=2M count=1 2>/dev/null
11995                         echo -n .
11996                 done
11997                 echo .
11998                 sync
11999                 sleep_maxage
12000                 free_min_max
12001         fi
12002
12003         DIFF=$((MAXV - MINV))
12004         DIFF2=$((DIFF * 100 / MINV))
12005         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12006         if [ $DIFF2 -gt $threshold ]; then
12007                 echo "ok"
12008         else
12009                 skip "QOS imbalance criteria not met"
12010         fi
12011
12012         MINI1=$MINI
12013         MINV1=$MINV
12014         MAXI1=$MAXI
12015         MAXV1=$MAXV
12016
12017         # now fill using QOS
12018         $LFS setstripe -c 1 $DIR/$tdir
12019         FILL=$((FILL / 200))
12020         if [ $FILL -gt 600 ]; then
12021                 FILL=600
12022         fi
12023         echo "writing $FILL files to QOS-assigned OSTs"
12024         i=0
12025         while [ $i -lt $FILL ]; do
12026                 i=$((i + 1))
12027                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12028                         count=1 2>/dev/null
12029                 echo -n .
12030         done
12031         echo "wrote $i 200k files"
12032         sync
12033         sleep_maxage
12034
12035         echo "Note: free space may not be updated, so measurements might be off"
12036         free_min_max
12037         DIFF2=$((MAXV - MINV))
12038         echo "free space delta: orig $DIFF final $DIFF2"
12039         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12040         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12041         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12042         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12043         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12044         if [[ $DIFF -gt 0 ]]; then
12045                 FILL=$((DIFF2 * 100 / DIFF - 100))
12046                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12047         fi
12048
12049         # Figure out which files were written where
12050         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12051                awk '/'$MINI1': / {print $2; exit}')
12052         echo $UUID
12053         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12054         echo "$MINC files created on smaller OST $MINI1"
12055         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12056                awk '/'$MAXI1': / {print $2; exit}')
12057         echo $UUID
12058         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12059         echo "$MAXC files created on larger OST $MAXI1"
12060         if [[ $MINC -gt 0 ]]; then
12061                 FILL=$((MAXC * 100 / MINC - 100))
12062                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12063         fi
12064         [[ $MAXC -gt $MINC ]] ||
12065                 error_ignore LU-9 "stripe QOS didn't balance free space"
12066 }
12067 run_test 116a "stripe QOS: free space balance ==================="
12068
12069 test_116b() { # LU-2093
12070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12071         remote_mds_nodsh && skip "remote MDS with nodsh"
12072
12073 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12074         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12075                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12076         [ -z "$old_rr" ] && skip "no QOS"
12077         do_facet $SINGLEMDS lctl set_param \
12078                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12079         mkdir -p $DIR/$tdir
12080         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12081         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12082         do_facet $SINGLEMDS lctl set_param fail_loc=0
12083         rm -rf $DIR/$tdir
12084         do_facet $SINGLEMDS lctl set_param \
12085                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12086 }
12087 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12088
12089 test_117() # bug 10891
12090 {
12091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12092
12093         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12094         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12095         lctl set_param fail_loc=0x21e
12096         > $DIR/$tfile || error "truncate failed"
12097         lctl set_param fail_loc=0
12098         echo "Truncate succeeded."
12099         rm -f $DIR/$tfile
12100 }
12101 run_test 117 "verify osd extend =========="
12102
12103 NO_SLOW_RESENDCOUNT=4
12104 export OLD_RESENDCOUNT=""
12105 set_resend_count () {
12106         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12107         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12108         lctl set_param -n $PROC_RESENDCOUNT $1
12109         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12110 }
12111
12112 # for reduce test_118* time (b=14842)
12113 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12114
12115 # Reset async IO behavior after error case
12116 reset_async() {
12117         FILE=$DIR/reset_async
12118
12119         # Ensure all OSCs are cleared
12120         $LFS setstripe -c -1 $FILE
12121         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12122         sync
12123         rm $FILE
12124 }
12125
12126 test_118a() #bug 11710
12127 {
12128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12129
12130         reset_async
12131
12132         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12133         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12134         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12135
12136         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12137                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12138                 return 1;
12139         fi
12140         rm -f $DIR/$tfile
12141 }
12142 run_test 118a "verify O_SYNC works =========="
12143
12144 test_118b()
12145 {
12146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12147         remote_ost_nodsh && skip "remote OST with nodsh"
12148
12149         reset_async
12150
12151         #define OBD_FAIL_SRV_ENOENT 0x217
12152         set_nodes_failloc "$(osts_nodes)" 0x217
12153         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12154         RC=$?
12155         set_nodes_failloc "$(osts_nodes)" 0
12156         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12157         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12158                     grep -c writeback)
12159
12160         if [[ $RC -eq 0 ]]; then
12161                 error "Must return error due to dropped pages, rc=$RC"
12162                 return 1;
12163         fi
12164
12165         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12166                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12167                 return 1;
12168         fi
12169
12170         echo "Dirty pages not leaked on ENOENT"
12171
12172         # Due to the above error the OSC will issue all RPCs syncronously
12173         # until a subsequent RPC completes successfully without error.
12174         $MULTIOP $DIR/$tfile Ow4096yc
12175         rm -f $DIR/$tfile
12176
12177         return 0
12178 }
12179 run_test 118b "Reclaim dirty pages on fatal error =========="
12180
12181 test_118c()
12182 {
12183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12184
12185         # for 118c, restore the original resend count, LU-1940
12186         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12187                                 set_resend_count $OLD_RESENDCOUNT
12188         remote_ost_nodsh && skip "remote OST with nodsh"
12189
12190         reset_async
12191
12192         #define OBD_FAIL_OST_EROFS               0x216
12193         set_nodes_failloc "$(osts_nodes)" 0x216
12194
12195         # multiop should block due to fsync until pages are written
12196         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12197         MULTIPID=$!
12198         sleep 1
12199
12200         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12201                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12202         fi
12203
12204         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12205                     grep -c writeback)
12206         if [[ $WRITEBACK -eq 0 ]]; then
12207                 error "No page in writeback, writeback=$WRITEBACK"
12208         fi
12209
12210         set_nodes_failloc "$(osts_nodes)" 0
12211         wait $MULTIPID
12212         RC=$?
12213         if [[ $RC -ne 0 ]]; then
12214                 error "Multiop fsync failed, rc=$RC"
12215         fi
12216
12217         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12218         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12219                     grep -c writeback)
12220         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12221                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12222         fi
12223
12224         rm -f $DIR/$tfile
12225         echo "Dirty pages flushed via fsync on EROFS"
12226         return 0
12227 }
12228 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12229
12230 # continue to use small resend count to reduce test_118* time (b=14842)
12231 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12232
12233 test_118d()
12234 {
12235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12236         remote_ost_nodsh && skip "remote OST with nodsh"
12237
12238         reset_async
12239
12240         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12241         set_nodes_failloc "$(osts_nodes)" 0x214
12242         # multiop should block due to fsync until pages are written
12243         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12244         MULTIPID=$!
12245         sleep 1
12246
12247         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12248                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12249         fi
12250
12251         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12252                     grep -c writeback)
12253         if [[ $WRITEBACK -eq 0 ]]; then
12254                 error "No page in writeback, writeback=$WRITEBACK"
12255         fi
12256
12257         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12258         set_nodes_failloc "$(osts_nodes)" 0
12259
12260         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12261         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12262                     grep -c writeback)
12263         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12264                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12265         fi
12266
12267         rm -f $DIR/$tfile
12268         echo "Dirty pages gaurenteed flushed via fsync"
12269         return 0
12270 }
12271 run_test 118d "Fsync validation inject a delay of the bulk =========="
12272
12273 test_118f() {
12274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12275
12276         reset_async
12277
12278         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12279         lctl set_param fail_loc=0x8000040a
12280
12281         # Should simulate EINVAL error which is fatal
12282         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12283         RC=$?
12284         if [[ $RC -eq 0 ]]; then
12285                 error "Must return error due to dropped pages, rc=$RC"
12286         fi
12287
12288         lctl set_param fail_loc=0x0
12289
12290         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12291         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12292         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12293                     grep -c writeback)
12294         if [[ $LOCKED -ne 0 ]]; then
12295                 error "Locked pages remain in cache, locked=$LOCKED"
12296         fi
12297
12298         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12299                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12300         fi
12301
12302         rm -f $DIR/$tfile
12303         echo "No pages locked after fsync"
12304
12305         reset_async
12306         return 0
12307 }
12308 run_test 118f "Simulate unrecoverable OSC side error =========="
12309
12310 test_118g() {
12311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12312
12313         reset_async
12314
12315         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12316         lctl set_param fail_loc=0x406
12317
12318         # simulate local -ENOMEM
12319         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12320         RC=$?
12321
12322         lctl set_param fail_loc=0
12323         if [[ $RC -eq 0 ]]; then
12324                 error "Must return error due to dropped pages, rc=$RC"
12325         fi
12326
12327         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12328         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12329         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12330                         grep -c writeback)
12331         if [[ $LOCKED -ne 0 ]]; then
12332                 error "Locked pages remain in cache, locked=$LOCKED"
12333         fi
12334
12335         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12336                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12337         fi
12338
12339         rm -f $DIR/$tfile
12340         echo "No pages locked after fsync"
12341
12342         reset_async
12343         return 0
12344 }
12345 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12346
12347 test_118h() {
12348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12349         remote_ost_nodsh && skip "remote OST with nodsh"
12350
12351         reset_async
12352
12353         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12354         set_nodes_failloc "$(osts_nodes)" 0x20e
12355         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12356         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12357         RC=$?
12358
12359         set_nodes_failloc "$(osts_nodes)" 0
12360         if [[ $RC -eq 0 ]]; then
12361                 error "Must return error due to dropped pages, rc=$RC"
12362         fi
12363
12364         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12365         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12366         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12367                     grep -c writeback)
12368         if [[ $LOCKED -ne 0 ]]; then
12369                 error "Locked pages remain in cache, locked=$LOCKED"
12370         fi
12371
12372         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12373                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12374         fi
12375
12376         rm -f $DIR/$tfile
12377         echo "No pages locked after fsync"
12378
12379         return 0
12380 }
12381 run_test 118h "Verify timeout in handling recoverables errors  =========="
12382
12383 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12384
12385 test_118i() {
12386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12387         remote_ost_nodsh && skip "remote OST with nodsh"
12388
12389         reset_async
12390
12391         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12392         set_nodes_failloc "$(osts_nodes)" 0x20e
12393
12394         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12395         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12396         PID=$!
12397         sleep 5
12398         set_nodes_failloc "$(osts_nodes)" 0
12399
12400         wait $PID
12401         RC=$?
12402         if [[ $RC -ne 0 ]]; then
12403                 error "got error, but should be not, rc=$RC"
12404         fi
12405
12406         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12407         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12408         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12409         if [[ $LOCKED -ne 0 ]]; then
12410                 error "Locked pages remain in cache, locked=$LOCKED"
12411         fi
12412
12413         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12414                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12415         fi
12416
12417         rm -f $DIR/$tfile
12418         echo "No pages locked after fsync"
12419
12420         return 0
12421 }
12422 run_test 118i "Fix error before timeout in recoverable error  =========="
12423
12424 [ "$SLOW" = "no" ] && set_resend_count 4
12425
12426 test_118j() {
12427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12428         remote_ost_nodsh && skip "remote OST with nodsh"
12429
12430         reset_async
12431
12432         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12433         set_nodes_failloc "$(osts_nodes)" 0x220
12434
12435         # return -EIO from OST
12436         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12437         RC=$?
12438         set_nodes_failloc "$(osts_nodes)" 0x0
12439         if [[ $RC -eq 0 ]]; then
12440                 error "Must return error due to dropped pages, rc=$RC"
12441         fi
12442
12443         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12444         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12445         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12446         if [[ $LOCKED -ne 0 ]]; then
12447                 error "Locked pages remain in cache, locked=$LOCKED"
12448         fi
12449
12450         # in recoverable error on OST we want resend and stay until it finished
12451         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12452                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12453         fi
12454
12455         rm -f $DIR/$tfile
12456         echo "No pages locked after fsync"
12457
12458         return 0
12459 }
12460 run_test 118j "Simulate unrecoverable OST side error =========="
12461
12462 test_118k()
12463 {
12464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12465         remote_ost_nodsh && skip "remote OSTs with nodsh"
12466
12467         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12468         set_nodes_failloc "$(osts_nodes)" 0x20e
12469         test_mkdir $DIR/$tdir
12470
12471         for ((i=0;i<10;i++)); do
12472                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12473                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12474                 SLEEPPID=$!
12475                 sleep 0.500s
12476                 kill $SLEEPPID
12477                 wait $SLEEPPID
12478         done
12479
12480         set_nodes_failloc "$(osts_nodes)" 0
12481         rm -rf $DIR/$tdir
12482 }
12483 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12484
12485 test_118l() # LU-646
12486 {
12487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12488
12489         test_mkdir $DIR/$tdir
12490         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12491         rm -rf $DIR/$tdir
12492 }
12493 run_test 118l "fsync dir"
12494
12495 test_118m() # LU-3066
12496 {
12497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12498
12499         test_mkdir $DIR/$tdir
12500         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12501         rm -rf $DIR/$tdir
12502 }
12503 run_test 118m "fdatasync dir ========="
12504
12505 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12506
12507 test_118n()
12508 {
12509         local begin
12510         local end
12511
12512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12513         remote_ost_nodsh && skip "remote OSTs with nodsh"
12514
12515         # Sleep to avoid a cached response.
12516         #define OBD_STATFS_CACHE_SECONDS 1
12517         sleep 2
12518
12519         # Inject a 10 second delay in the OST_STATFS handler.
12520         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12521         set_nodes_failloc "$(osts_nodes)" 0x242
12522
12523         begin=$SECONDS
12524         stat --file-system $MOUNT > /dev/null
12525         end=$SECONDS
12526
12527         set_nodes_failloc "$(osts_nodes)" 0
12528
12529         if ((end - begin > 20)); then
12530             error "statfs took $((end - begin)) seconds, expected 10"
12531         fi
12532 }
12533 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12534
12535 test_119a() # bug 11737
12536 {
12537         BSIZE=$((512 * 1024))
12538         directio write $DIR/$tfile 0 1 $BSIZE
12539         # We ask to read two blocks, which is more than a file size.
12540         # directio will indicate an error when requested and actual
12541         # sizes aren't equeal (a normal situation in this case) and
12542         # print actual read amount.
12543         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12544         if [ "$NOB" != "$BSIZE" ]; then
12545                 error "read $NOB bytes instead of $BSIZE"
12546         fi
12547         rm -f $DIR/$tfile
12548 }
12549 run_test 119a "Short directIO read must return actual read amount"
12550
12551 test_119b() # bug 11737
12552 {
12553         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12554
12555         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12556         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12557         sync
12558         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12559                 error "direct read failed"
12560         rm -f $DIR/$tfile
12561 }
12562 run_test 119b "Sparse directIO read must return actual read amount"
12563
12564 test_119c() # bug 13099
12565 {
12566         BSIZE=1048576
12567         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12568         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12569         rm -f $DIR/$tfile
12570 }
12571 run_test 119c "Testing for direct read hitting hole"
12572
12573 test_119d() # bug 15950
12574 {
12575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12576
12577         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12578         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12579         BSIZE=1048576
12580         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12581         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12582         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12583         lctl set_param fail_loc=0x40d
12584         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12585         pid_dio=$!
12586         sleep 1
12587         cat $DIR/$tfile > /dev/null &
12588         lctl set_param fail_loc=0
12589         pid_reads=$!
12590         wait $pid_dio
12591         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12592         sleep 2
12593         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12594         error "the read rpcs have not completed in 2s"
12595         rm -f $DIR/$tfile
12596         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12597 }
12598 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12599
12600 test_120a() {
12601         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12602         remote_mds_nodsh && skip "remote MDS with nodsh"
12603         test_mkdir -i0 -c1 $DIR/$tdir
12604         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12605                 skip_env "no early lock cancel on server"
12606
12607         lru_resize_disable mdc
12608         lru_resize_disable osc
12609         cancel_lru_locks mdc
12610         # asynchronous object destroy at MDT could cause bl ast to client
12611         cancel_lru_locks osc
12612
12613         stat $DIR/$tdir > /dev/null
12614         can1=$(do_facet mds1 \
12615                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12616                awk '/ldlm_cancel/ {print $2}')
12617         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12618                awk '/ldlm_bl_callback/ {print $2}')
12619         test_mkdir -i0 -c1 $DIR/$tdir/d1
12620         can2=$(do_facet mds1 \
12621                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12622                awk '/ldlm_cancel/ {print $2}')
12623         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12624                awk '/ldlm_bl_callback/ {print $2}')
12625         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12626         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12627         lru_resize_enable mdc
12628         lru_resize_enable osc
12629 }
12630 run_test 120a "Early Lock Cancel: mkdir test"
12631
12632 test_120b() {
12633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12634         remote_mds_nodsh && skip "remote MDS with nodsh"
12635         test_mkdir $DIR/$tdir
12636         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12637                 skip_env "no early lock cancel on server"
12638
12639         lru_resize_disable mdc
12640         lru_resize_disable osc
12641         cancel_lru_locks mdc
12642         stat $DIR/$tdir > /dev/null
12643         can1=$(do_facet $SINGLEMDS \
12644                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12645                awk '/ldlm_cancel/ {print $2}')
12646         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12647                awk '/ldlm_bl_callback/ {print $2}')
12648         touch $DIR/$tdir/f1
12649         can2=$(do_facet $SINGLEMDS \
12650                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12651                awk '/ldlm_cancel/ {print $2}')
12652         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12653                awk '/ldlm_bl_callback/ {print $2}')
12654         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12655         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12656         lru_resize_enable mdc
12657         lru_resize_enable osc
12658 }
12659 run_test 120b "Early Lock Cancel: create test"
12660
12661 test_120c() {
12662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12663         remote_mds_nodsh && skip "remote MDS with nodsh"
12664         test_mkdir -i0 -c1 $DIR/$tdir
12665         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12666                 skip "no early lock cancel on server"
12667
12668         lru_resize_disable mdc
12669         lru_resize_disable osc
12670         test_mkdir -i0 -c1 $DIR/$tdir/d1
12671         test_mkdir -i0 -c1 $DIR/$tdir/d2
12672         touch $DIR/$tdir/d1/f1
12673         cancel_lru_locks mdc
12674         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12675         can1=$(do_facet mds1 \
12676                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12677                awk '/ldlm_cancel/ {print $2}')
12678         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12679                awk '/ldlm_bl_callback/ {print $2}')
12680         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12681         can2=$(do_facet mds1 \
12682                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12683                awk '/ldlm_cancel/ {print $2}')
12684         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12685                awk '/ldlm_bl_callback/ {print $2}')
12686         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12687         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12688         lru_resize_enable mdc
12689         lru_resize_enable osc
12690 }
12691 run_test 120c "Early Lock Cancel: link test"
12692
12693 test_120d() {
12694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12695         remote_mds_nodsh && skip "remote MDS with nodsh"
12696         test_mkdir -i0 -c1 $DIR/$tdir
12697         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12698                 skip_env "no early lock cancel on server"
12699
12700         lru_resize_disable mdc
12701         lru_resize_disable osc
12702         touch $DIR/$tdir
12703         cancel_lru_locks mdc
12704         stat $DIR/$tdir > /dev/null
12705         can1=$(do_facet mds1 \
12706                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12707                awk '/ldlm_cancel/ {print $2}')
12708         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12709                awk '/ldlm_bl_callback/ {print $2}')
12710         chmod a+x $DIR/$tdir
12711         can2=$(do_facet mds1 \
12712                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12713                awk '/ldlm_cancel/ {print $2}')
12714         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12715                awk '/ldlm_bl_callback/ {print $2}')
12716         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12717         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12718         lru_resize_enable mdc
12719         lru_resize_enable osc
12720 }
12721 run_test 120d "Early Lock Cancel: setattr test"
12722
12723 test_120e() {
12724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12725         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12726                 skip_env "no early lock cancel on server"
12727         remote_mds_nodsh && skip "remote MDS with nodsh"
12728
12729         local dlmtrace_set=false
12730
12731         test_mkdir -i0 -c1 $DIR/$tdir
12732         lru_resize_disable mdc
12733         lru_resize_disable osc
12734         ! $LCTL get_param debug | grep -q dlmtrace &&
12735                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12736         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12737         cancel_lru_locks mdc
12738         cancel_lru_locks osc
12739         dd if=$DIR/$tdir/f1 of=/dev/null
12740         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12741         # XXX client can not do early lock cancel of OST lock
12742         # during unlink (LU-4206), so cancel osc lock now.
12743         sleep 2
12744         cancel_lru_locks osc
12745         can1=$(do_facet mds1 \
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         unlink $DIR/$tdir/f1
12751         sleep 5
12752         can2=$(do_facet mds1 \
12753                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12754                awk '/ldlm_cancel/ {print $2}')
12755         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12756                awk '/ldlm_bl_callback/ {print $2}')
12757         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12758                 $LCTL dk $TMP/cancel.debug.txt
12759         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12760                 $LCTL dk $TMP/blocking.debug.txt
12761         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12762         lru_resize_enable mdc
12763         lru_resize_enable osc
12764 }
12765 run_test 120e "Early Lock Cancel: unlink test"
12766
12767 test_120f() {
12768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12769         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12770                 skip_env "no early lock cancel on server"
12771         remote_mds_nodsh && skip "remote MDS with nodsh"
12772
12773         test_mkdir -i0 -c1 $DIR/$tdir
12774         lru_resize_disable mdc
12775         lru_resize_disable osc
12776         test_mkdir -i0 -c1 $DIR/$tdir/d1
12777         test_mkdir -i0 -c1 $DIR/$tdir/d2
12778         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12779         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12780         cancel_lru_locks mdc
12781         cancel_lru_locks osc
12782         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12783         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12784         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12785         # XXX client can not do early lock cancel of OST lock
12786         # during rename (LU-4206), so cancel osc lock now.
12787         sleep 2
12788         cancel_lru_locks osc
12789         can1=$(do_facet mds1 \
12790                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12791                awk '/ldlm_cancel/ {print $2}')
12792         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12793                awk '/ldlm_bl_callback/ {print $2}')
12794         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12795         sleep 5
12796         can2=$(do_facet mds1 \
12797                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12798                awk '/ldlm_cancel/ {print $2}')
12799         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12800                awk '/ldlm_bl_callback/ {print $2}')
12801         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12802         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12803         lru_resize_enable mdc
12804         lru_resize_enable osc
12805 }
12806 run_test 120f "Early Lock Cancel: rename test"
12807
12808 test_120g() {
12809         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12810         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12811                 skip_env "no early lock cancel on server"
12812         remote_mds_nodsh && skip "remote MDS with nodsh"
12813
12814         lru_resize_disable mdc
12815         lru_resize_disable osc
12816         count=10000
12817         echo create $count files
12818         test_mkdir $DIR/$tdir
12819         cancel_lru_locks mdc
12820         cancel_lru_locks osc
12821         t0=$(date +%s)
12822
12823         can0=$(do_facet $SINGLEMDS \
12824                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12825                awk '/ldlm_cancel/ {print $2}')
12826         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12827                awk '/ldlm_bl_callback/ {print $2}')
12828         createmany -o $DIR/$tdir/f $count
12829         sync
12830         can1=$(do_facet $SINGLEMDS \
12831                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12832                awk '/ldlm_cancel/ {print $2}')
12833         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12834                awk '/ldlm_bl_callback/ {print $2}')
12835         t1=$(date +%s)
12836         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12837         echo rm $count files
12838         rm -r $DIR/$tdir
12839         sync
12840         can2=$(do_facet $SINGLEMDS \
12841                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12842                awk '/ldlm_cancel/ {print $2}')
12843         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12844                awk '/ldlm_bl_callback/ {print $2}')
12845         t2=$(date +%s)
12846         echo total: $count removes in $((t2-t1))
12847         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12848         sleep 2
12849         # wait for commitment of removal
12850         lru_resize_enable mdc
12851         lru_resize_enable osc
12852 }
12853 run_test 120g "Early Lock Cancel: performance test"
12854
12855 test_121() { #bug #10589
12856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12857
12858         rm -rf $DIR/$tfile
12859         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12860 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12861         lctl set_param fail_loc=0x310
12862         cancel_lru_locks osc > /dev/null
12863         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12864         lctl set_param fail_loc=0
12865         [[ $reads -eq $writes ]] ||
12866                 error "read $reads blocks, must be $writes blocks"
12867 }
12868 run_test 121 "read cancel race ========="
12869
12870 test_123a_base() { # was test 123, statahead(bug 11401)
12871         local lsx="$1"
12872
12873         SLOWOK=0
12874         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12875                 log "testing UP system. Performance may be lower than expected."
12876                 SLOWOK=1
12877         fi
12878         running_in_vm && SLOWOK=1
12879
12880         rm -rf $DIR/$tdir
12881         test_mkdir $DIR/$tdir
12882         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12883         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12884         MULT=10
12885         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12886                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12887
12888                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12889                 lctl set_param -n llite.*.statahead_max 0
12890                 lctl get_param llite.*.statahead_max
12891                 cancel_lru_locks mdc
12892                 cancel_lru_locks osc
12893                 stime=$(date +%s)
12894                 time $lsx $DIR/$tdir | wc -l
12895                 etime=$(date +%s)
12896                 delta=$((etime - stime))
12897                 log "$lsx $i files without statahead: $delta sec"
12898                 lctl set_param llite.*.statahead_max=$max
12899
12900                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12901                         grep "statahead wrong:" | awk '{print $3}')
12902                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12903                 cancel_lru_locks mdc
12904                 cancel_lru_locks osc
12905                 stime=$(date +%s)
12906                 time $lsx $DIR/$tdir | wc -l
12907                 etime=$(date +%s)
12908                 delta_sa=$((etime - stime))
12909                 log "$lsx $i files with statahead: $delta_sa sec"
12910                 lctl get_param -n llite.*.statahead_stats
12911                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12912                         grep "statahead wrong:" | awk '{print $3}')
12913
12914                 [[ $swrong -lt $ewrong ]] &&
12915                         log "statahead was stopped, maybe too many locks held!"
12916                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12917
12918                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12919                         max=$(lctl get_param -n llite.*.statahead_max |
12920                                 head -n 1)
12921                         lctl set_param -n llite.*.statahead_max 0
12922                         lctl get_param llite.*.statahead_max
12923                         cancel_lru_locks mdc
12924                         cancel_lru_locks osc
12925                         stime=$(date +%s)
12926                         time $lsx $DIR/$tdir | wc -l
12927                         etime=$(date +%s)
12928                         delta=$((etime - stime))
12929                         log "$lsx $i files again without statahead: $delta sec"
12930                         lctl set_param llite.*.statahead_max=$max
12931                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12932                                 if [  $SLOWOK -eq 0 ]; then
12933                                         error "$lsx $i files is slower with statahead!"
12934                                 else
12935                                         log "$lsx $i files is slower with statahead!"
12936                                 fi
12937                                 break
12938                         fi
12939                 fi
12940
12941                 [ $delta -gt 20 ] && break
12942                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12943                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12944         done
12945         log "$lsx done"
12946
12947         stime=$(date +%s)
12948         rm -r $DIR/$tdir
12949         sync
12950         etime=$(date +%s)
12951         delta=$((etime - stime))
12952         log "rm -r $DIR/$tdir/: $delta seconds"
12953         log "rm done"
12954         lctl get_param -n llite.*.statahead_stats
12955 }
12956
12957 test_123aa() {
12958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12959
12960         test_123a_base "ls -l"
12961 }
12962 run_test 123aa "verify statahead work"
12963
12964 test_123ab() {
12965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12966
12967         statx_supported || skip_env "Test must be statx() syscall supported"
12968
12969         test_123a_base "$STATX -l"
12970 }
12971 run_test 123ab "verify statahead work by using statx"
12972
12973 test_123ac() {
12974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12975
12976         statx_supported || skip_env "Test must be statx() syscall supported"
12977
12978         local rpcs_before
12979         local rpcs_after
12980         local agl_before
12981         local agl_after
12982
12983         cancel_lru_locks $OSC
12984         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12985         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12986                 awk '/agl.total:/ {print $3}')
12987         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12988         test_123a_base "$STATX --cached=always -D"
12989         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12990                 awk '/agl.total:/ {print $3}')
12991         [ $agl_before -eq $agl_after ] ||
12992                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12993         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12994         [ $rpcs_after -eq $rpcs_before ] ||
12995                 error "$STATX should not send glimpse RPCs to $OSC"
12996 }
12997 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12998
12999 test_123b () { # statahead(bug 15027)
13000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13001
13002         test_mkdir $DIR/$tdir
13003         createmany -o $DIR/$tdir/$tfile-%d 1000
13004
13005         cancel_lru_locks mdc
13006         cancel_lru_locks osc
13007
13008 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13009         lctl set_param fail_loc=0x80000803
13010         ls -lR $DIR/$tdir > /dev/null
13011         log "ls done"
13012         lctl set_param fail_loc=0x0
13013         lctl get_param -n llite.*.statahead_stats
13014         rm -r $DIR/$tdir
13015         sync
13016
13017 }
13018 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13019
13020 test_123c() {
13021         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13022
13023         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13024         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13025         touch $DIR/$tdir.1/{1..3}
13026         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13027
13028         remount_client $MOUNT
13029
13030         $MULTIOP $DIR/$tdir.0 Q
13031
13032         # let statahead to complete
13033         ls -l $DIR/$tdir.0 > /dev/null
13034
13035         testid=$(echo $TESTNAME | tr '_' ' ')
13036         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13037                 error "statahead warning" || true
13038 }
13039 run_test 123c "Can not initialize inode warning on DNE statahead"
13040
13041 test_124a() {
13042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13043         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13044                 skip_env "no lru resize on server"
13045
13046         local NR=2000
13047
13048         test_mkdir $DIR/$tdir
13049
13050         log "create $NR files at $DIR/$tdir"
13051         createmany -o $DIR/$tdir/f $NR ||
13052                 error "failed to create $NR files in $DIR/$tdir"
13053
13054         cancel_lru_locks mdc
13055         ls -l $DIR/$tdir > /dev/null
13056
13057         local NSDIR=""
13058         local LRU_SIZE=0
13059         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13060                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13061                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13062                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13063                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13064                         log "NSDIR=$NSDIR"
13065                         log "NS=$(basename $NSDIR)"
13066                         break
13067                 fi
13068         done
13069
13070         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13071                 skip "Not enough cached locks created!"
13072         fi
13073         log "LRU=$LRU_SIZE"
13074
13075         local SLEEP=30
13076
13077         # We know that lru resize allows one client to hold $LIMIT locks
13078         # for 10h. After that locks begin to be killed by client.
13079         local MAX_HRS=10
13080         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13081         log "LIMIT=$LIMIT"
13082         if [ $LIMIT -lt $LRU_SIZE ]; then
13083                 skip "Limit is too small $LIMIT"
13084         fi
13085
13086         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13087         # killing locks. Some time was spent for creating locks. This means
13088         # that up to the moment of sleep finish we must have killed some of
13089         # them (10-100 locks). This depends on how fast ther were created.
13090         # Many of them were touched in almost the same moment and thus will
13091         # be killed in groups.
13092         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13093
13094         # Use $LRU_SIZE_B here to take into account real number of locks
13095         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13096         local LRU_SIZE_B=$LRU_SIZE
13097         log "LVF=$LVF"
13098         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13099         log "OLD_LVF=$OLD_LVF"
13100         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13101
13102         # Let's make sure that we really have some margin. Client checks
13103         # cached locks every 10 sec.
13104         SLEEP=$((SLEEP+20))
13105         log "Sleep ${SLEEP} sec"
13106         local SEC=0
13107         while ((SEC<$SLEEP)); do
13108                 echo -n "..."
13109                 sleep 5
13110                 SEC=$((SEC+5))
13111                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13112                 echo -n "$LRU_SIZE"
13113         done
13114         echo ""
13115         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13116         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13117
13118         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13119                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13120                 unlinkmany $DIR/$tdir/f $NR
13121                 return
13122         }
13123
13124         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13125         log "unlink $NR files at $DIR/$tdir"
13126         unlinkmany $DIR/$tdir/f $NR
13127 }
13128 run_test 124a "lru resize ======================================="
13129
13130 get_max_pool_limit()
13131 {
13132         local limit=$($LCTL get_param \
13133                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13134         local max=0
13135         for l in $limit; do
13136                 if [[ $l -gt $max ]]; then
13137                         max=$l
13138                 fi
13139         done
13140         echo $max
13141 }
13142
13143 test_124b() {
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         LIMIT=$(get_max_pool_limit)
13149
13150         NR=$(($(default_lru_size)*20))
13151         if [[ $NR -gt $LIMIT ]]; then
13152                 log "Limit lock number by $LIMIT locks"
13153                 NR=$LIMIT
13154         fi
13155
13156         IFree=$(mdsrate_inodes_available)
13157         if [ $IFree -lt $NR ]; then
13158                 log "Limit lock number by $IFree inodes"
13159                 NR=$IFree
13160         fi
13161
13162         lru_resize_disable mdc
13163         test_mkdir -p $DIR/$tdir/disable_lru_resize
13164
13165         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13166         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13167         cancel_lru_locks mdc
13168         stime=`date +%s`
13169         PID=""
13170         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13171         PID="$PID $!"
13172         sleep 2
13173         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13174         PID="$PID $!"
13175         sleep 2
13176         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13177         PID="$PID $!"
13178         wait $PID
13179         etime=`date +%s`
13180         nolruresize_delta=$((etime-stime))
13181         log "ls -la time: $nolruresize_delta seconds"
13182         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13183         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13184
13185         lru_resize_enable mdc
13186         test_mkdir -p $DIR/$tdir/enable_lru_resize
13187
13188         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13189         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13190         cancel_lru_locks mdc
13191         stime=`date +%s`
13192         PID=""
13193         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13194         PID="$PID $!"
13195         sleep 2
13196         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13197         PID="$PID $!"
13198         sleep 2
13199         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13200         PID="$PID $!"
13201         wait $PID
13202         etime=`date +%s`
13203         lruresize_delta=$((etime-stime))
13204         log "ls -la time: $lruresize_delta seconds"
13205         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13206
13207         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13208                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13209         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13210                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13211         else
13212                 log "lru resize performs the same with no lru resize"
13213         fi
13214         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13215 }
13216 run_test 124b "lru resize (performance test) ======================="
13217
13218 test_124c() {
13219         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13220         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13221                 skip_env "no lru resize on server"
13222
13223         # cache ununsed locks on client
13224         local nr=100
13225         cancel_lru_locks mdc
13226         test_mkdir $DIR/$tdir
13227         createmany -o $DIR/$tdir/f $nr ||
13228                 error "failed to create $nr files in $DIR/$tdir"
13229         ls -l $DIR/$tdir > /dev/null
13230
13231         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13232         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13233         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13234         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13235         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13236
13237         # set lru_max_age to 1 sec
13238         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13239         echo "sleep $((recalc_p * 2)) seconds..."
13240         sleep $((recalc_p * 2))
13241
13242         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13243         # restore lru_max_age
13244         $LCTL set_param -n $nsdir.lru_max_age $max_age
13245         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13246         unlinkmany $DIR/$tdir/f $nr
13247 }
13248 run_test 124c "LRUR cancel very aged locks"
13249
13250 test_124d() {
13251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13252         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13253                 skip_env "no lru resize on server"
13254
13255         # cache ununsed locks on client
13256         local nr=100
13257
13258         lru_resize_disable mdc
13259         stack_trap "lru_resize_enable mdc" EXIT
13260
13261         cancel_lru_locks mdc
13262
13263         # asynchronous object destroy at MDT could cause bl ast to client
13264         test_mkdir $DIR/$tdir
13265         createmany -o $DIR/$tdir/f $nr ||
13266                 error "failed to create $nr files in $DIR/$tdir"
13267         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13268
13269         ls -l $DIR/$tdir > /dev/null
13270
13271         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13272         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13273         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13274         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13275
13276         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13277
13278         # set lru_max_age to 1 sec
13279         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13280         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13281
13282         echo "sleep $((recalc_p * 2)) seconds..."
13283         sleep $((recalc_p * 2))
13284
13285         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13286
13287         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13288 }
13289 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13290
13291 test_125() { # 13358
13292         $LCTL get_param -n llite.*.client_type | grep -q local ||
13293                 skip "must run as local client"
13294         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13295                 skip_env "must have acl enabled"
13296         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13297
13298         test_mkdir $DIR/$tdir
13299         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13300         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13301         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13302 }
13303 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13304
13305 test_126() { # bug 12829/13455
13306         $GSS && skip_env "must run as gss disabled"
13307         $LCTL get_param -n llite.*.client_type | grep -q local ||
13308                 skip "must run as local client"
13309         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13310
13311         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13312         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13313         rm -f $DIR/$tfile
13314         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13315 }
13316 run_test 126 "check that the fsgid provided by the client is taken into account"
13317
13318 test_127a() { # bug 15521
13319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13320         local name count samp unit min max sum sumsq
13321
13322         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13323         echo "stats before reset"
13324         $LCTL get_param osc.*.stats
13325         $LCTL set_param osc.*.stats=0
13326         local fsize=$((2048 * 1024))
13327
13328         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13329         cancel_lru_locks osc
13330         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13331
13332         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13333         stack_trap "rm -f $TMP/$tfile.tmp"
13334         while read name count samp unit min max sum sumsq; do
13335                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13336                 [ ! $min ] && error "Missing min value for $name proc entry"
13337                 eval $name=$count || error "Wrong proc format"
13338
13339                 case $name in
13340                 read_bytes|write_bytes)
13341                         [[ "$unit" =~ "bytes" ]] ||
13342                                 error "unit is not 'bytes': $unit"
13343                         (( $min >= 4096 )) || error "min is too small: $min"
13344                         (( $min <= $fsize )) || error "min is too big: $min"
13345                         (( $max >= 4096 )) || error "max is too small: $max"
13346                         (( $max <= $fsize )) || error "max is too big: $max"
13347                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13348                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13349                                 error "sumsquare is too small: $sumsq"
13350                         (( $sumsq <= $fsize * $fsize )) ||
13351                                 error "sumsquare is too big: $sumsq"
13352                         ;;
13353                 ost_read|ost_write)
13354                         [[ "$unit" =~ "usec" ]] ||
13355                                 error "unit is not 'usec': $unit"
13356                         ;;
13357                 *)      ;;
13358                 esac
13359         done < $DIR/$tfile.tmp
13360
13361         #check that we actually got some stats
13362         [ "$read_bytes" ] || error "Missing read_bytes stats"
13363         [ "$write_bytes" ] || error "Missing write_bytes stats"
13364         [ "$read_bytes" != 0 ] || error "no read done"
13365         [ "$write_bytes" != 0 ] || error "no write done"
13366 }
13367 run_test 127a "verify the client stats are sane"
13368
13369 test_127b() { # bug LU-333
13370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13371         local name count samp unit min max sum sumsq
13372
13373         echo "stats before reset"
13374         $LCTL get_param llite.*.stats
13375         $LCTL set_param llite.*.stats=0
13376
13377         # perform 2 reads and writes so MAX is different from SUM.
13378         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13379         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13380         cancel_lru_locks osc
13381         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13382         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13383
13384         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13385         stack_trap "rm -f $TMP/$tfile.tmp"
13386         while read name count samp unit min max sum sumsq; do
13387                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13388                 eval $name=$count || error "Wrong proc format"
13389
13390                 case $name in
13391                 read_bytes|write_bytes)
13392                         [[ "$unit" =~ "bytes" ]] ||
13393                                 error "unit is not 'bytes': $unit"
13394                         (( $count == 2 )) || error "count is not 2: $count"
13395                         (( $min == $PAGE_SIZE )) ||
13396                                 error "min is not $PAGE_SIZE: $min"
13397                         (( $max == $PAGE_SIZE )) ||
13398                                 error "max is not $PAGE_SIZE: $max"
13399                         (( $sum == $PAGE_SIZE * 2 )) ||
13400                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13401                         ;;
13402                 read|write)
13403                         [[ "$unit" =~ "usec" ]] ||
13404                                 error "unit is not 'usec': $unit"
13405                         ;;
13406                 *)      ;;
13407                 esac
13408         done < $TMP/$tfile.tmp
13409
13410         #check that we actually got some stats
13411         [ "$read_bytes" ] || error "Missing read_bytes stats"
13412         [ "$write_bytes" ] || error "Missing write_bytes stats"
13413         [ "$read_bytes" != 0 ] || error "no read done"
13414         [ "$write_bytes" != 0 ] || error "no write done"
13415 }
13416 run_test 127b "verify the llite client stats are sane"
13417
13418 test_127c() { # LU-12394
13419         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13420         local size
13421         local bsize
13422         local reads
13423         local writes
13424         local count
13425
13426         $LCTL set_param llite.*.extents_stats=1
13427         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13428
13429         # Use two stripes so there is enough space in default config
13430         $LFS setstripe -c 2 $DIR/$tfile
13431
13432         # Extent stats start at 0-4K and go in power of two buckets
13433         # LL_HIST_START = 12 --> 2^12 = 4K
13434         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13435         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13436         # small configs
13437         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13438                 do
13439                 # Write and read, 2x each, second time at a non-zero offset
13440                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13441                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13442                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13443                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13444                 rm -f $DIR/$tfile
13445         done
13446
13447         $LCTL get_param llite.*.extents_stats
13448
13449         count=2
13450         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13451                 do
13452                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13453                                 grep -m 1 $bsize)
13454                 reads=$(echo $bucket | awk '{print $5}')
13455                 writes=$(echo $bucket | awk '{print $9}')
13456                 [ "$reads" -eq $count ] ||
13457                         error "$reads reads in < $bsize bucket, expect $count"
13458                 [ "$writes" -eq $count ] ||
13459                         error "$writes writes in < $bsize bucket, expect $count"
13460         done
13461
13462         # Test mmap write and read
13463         $LCTL set_param llite.*.extents_stats=c
13464         size=512
13465         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13466         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13467         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13468
13469         $LCTL get_param llite.*.extents_stats
13470
13471         count=$(((size*1024) / PAGE_SIZE))
13472
13473         bsize=$((2 * PAGE_SIZE / 1024))K
13474
13475         bucket=$($LCTL get_param -n llite.*.extents_stats |
13476                         grep -m 1 $bsize)
13477         reads=$(echo $bucket | awk '{print $5}')
13478         writes=$(echo $bucket | awk '{print $9}')
13479         # mmap writes fault in the page first, creating an additonal read
13480         [ "$reads" -eq $((2 * count)) ] ||
13481                 error "$reads reads in < $bsize bucket, expect $count"
13482         [ "$writes" -eq $count ] ||
13483                 error "$writes writes in < $bsize bucket, expect $count"
13484 }
13485 run_test 127c "test llite extent stats with regular & mmap i/o"
13486
13487 test_128() { # bug 15212
13488         touch $DIR/$tfile
13489         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13490                 find $DIR/$tfile
13491                 find $DIR/$tfile
13492         EOF
13493
13494         result=$(grep error $TMP/$tfile.log)
13495         rm -f $DIR/$tfile $TMP/$tfile.log
13496         [ -z "$result" ] ||
13497                 error "consecutive find's under interactive lfs failed"
13498 }
13499 run_test 128 "interactive lfs for 2 consecutive find's"
13500
13501 set_dir_limits () {
13502         local mntdev
13503         local canondev
13504         local node
13505
13506         local ldproc=/proc/fs/ldiskfs
13507         local facets=$(get_facets MDS)
13508
13509         for facet in ${facets//,/ }; do
13510                 canondev=$(ldiskfs_canon \
13511                            *.$(convert_facet2label $facet).mntdev $facet)
13512                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13513                         ldproc=/sys/fs/ldiskfs
13514                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13515                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13516         done
13517 }
13518
13519 check_mds_dmesg() {
13520         local facets=$(get_facets MDS)
13521         for facet in ${facets//,/ }; do
13522                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13523         done
13524         return 1
13525 }
13526
13527 test_129() {
13528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13529         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13530                 skip "Need MDS version with at least 2.5.56"
13531         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13532                 skip_env "ldiskfs only test"
13533         fi
13534         remote_mds_nodsh && skip "remote MDS with nodsh"
13535
13536         local ENOSPC=28
13537         local has_warning=false
13538
13539         rm -rf $DIR/$tdir
13540         mkdir -p $DIR/$tdir
13541
13542         # block size of mds1
13543         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13544         set_dir_limits $maxsize $((maxsize * 6 / 8))
13545         stack_trap "set_dir_limits 0 0"
13546         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13547         local dirsize=$(stat -c%s "$DIR/$tdir")
13548         local nfiles=0
13549         while (( $dirsize <= $maxsize )); do
13550                 $MCREATE $DIR/$tdir/file_base_$nfiles
13551                 rc=$?
13552                 # check two errors:
13553                 # ENOSPC for ext4 max_dir_size, which has been used since
13554                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13555                 if (( rc == ENOSPC )); then
13556                         set_dir_limits 0 0
13557                         echo "rc=$rc returned as expected after $nfiles files"
13558
13559                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13560                                 error "create failed w/o dir size limit"
13561
13562                         # messages may be rate limited if test is run repeatedly
13563                         check_mds_dmesg '"is approaching max"' ||
13564                                 echo "warning message should be output"
13565                         check_mds_dmesg '"has reached max"' ||
13566                                 echo "reached message should be output"
13567
13568                         dirsize=$(stat -c%s "$DIR/$tdir")
13569
13570                         [[ $dirsize -ge $maxsize ]] && return 0
13571                         error "dirsize $dirsize < $maxsize after $nfiles files"
13572                 elif (( rc != 0 )); then
13573                         break
13574                 fi
13575                 nfiles=$((nfiles + 1))
13576                 dirsize=$(stat -c%s "$DIR/$tdir")
13577         done
13578
13579         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13580 }
13581 run_test 129 "test directory size limit ========================"
13582
13583 OLDIFS="$IFS"
13584 cleanup_130() {
13585         trap 0
13586         IFS="$OLDIFS"
13587 }
13588
13589 test_130a() {
13590         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13591         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13592
13593         trap cleanup_130 EXIT RETURN
13594
13595         local fm_file=$DIR/$tfile
13596         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13597         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13598                 error "dd failed for $fm_file"
13599
13600         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13601         filefrag -ves $fm_file
13602         RC=$?
13603         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13604                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13605         [ $RC != 0 ] && error "filefrag $fm_file failed"
13606
13607         filefrag_op=$(filefrag -ve -k $fm_file |
13608                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13609         lun=$($LFS getstripe -i $fm_file)
13610
13611         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13612         IFS=$'\n'
13613         tot_len=0
13614         for line in $filefrag_op
13615         do
13616                 frag_lun=`echo $line | cut -d: -f5`
13617                 ext_len=`echo $line | cut -d: -f4`
13618                 if (( $frag_lun != $lun )); then
13619                         cleanup_130
13620                         error "FIEMAP on 1-stripe file($fm_file) failed"
13621                         return
13622                 fi
13623                 (( tot_len += ext_len ))
13624         done
13625
13626         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13627                 cleanup_130
13628                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13629                 return
13630         fi
13631
13632         cleanup_130
13633
13634         echo "FIEMAP on single striped file succeeded"
13635 }
13636 run_test 130a "FIEMAP (1-stripe file)"
13637
13638 test_130b() {
13639         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13640
13641         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13642         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13643
13644         trap cleanup_130 EXIT RETURN
13645
13646         local fm_file=$DIR/$tfile
13647         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13648                         error "setstripe on $fm_file"
13649         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13650                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13651
13652         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13653                 error "dd failed on $fm_file"
13654
13655         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13656         filefrag_op=$(filefrag -ve -k $fm_file |
13657                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13658
13659         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13660                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13661
13662         IFS=$'\n'
13663         tot_len=0
13664         num_luns=1
13665         for line in $filefrag_op
13666         do
13667                 frag_lun=$(echo $line | cut -d: -f5 |
13668                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13669                 ext_len=$(echo $line | cut -d: -f4)
13670                 if (( $frag_lun != $last_lun )); then
13671                         if (( tot_len != 1024 )); then
13672                                 cleanup_130
13673                                 error "FIEMAP on $fm_file failed; returned " \
13674                                 "len $tot_len for OST $last_lun instead of 1024"
13675                                 return
13676                         else
13677                                 (( num_luns += 1 ))
13678                                 tot_len=0
13679                         fi
13680                 fi
13681                 (( tot_len += ext_len ))
13682                 last_lun=$frag_lun
13683         done
13684         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13685                 cleanup_130
13686                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13687                         "luns or wrong len for OST $last_lun"
13688                 return
13689         fi
13690
13691         cleanup_130
13692
13693         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13694 }
13695 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13696
13697 test_130c() {
13698         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13699
13700         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13701         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13702
13703         trap cleanup_130 EXIT RETURN
13704
13705         local fm_file=$DIR/$tfile
13706         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13707         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13708                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13709
13710         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13711                         error "dd failed on $fm_file"
13712
13713         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13714         filefrag_op=$(filefrag -ve -k $fm_file |
13715                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13716
13717         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13718                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13719
13720         IFS=$'\n'
13721         tot_len=0
13722         num_luns=1
13723         for line in $filefrag_op
13724         do
13725                 frag_lun=$(echo $line | cut -d: -f5 |
13726                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13727                 ext_len=$(echo $line | cut -d: -f4)
13728                 if (( $frag_lun != $last_lun )); then
13729                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13730                         if (( logical != 512 )); then
13731                                 cleanup_130
13732                                 error "FIEMAP on $fm_file failed; returned " \
13733                                 "logical start for lun $logical instead of 512"
13734                                 return
13735                         fi
13736                         if (( tot_len != 512 )); then
13737                                 cleanup_130
13738                                 error "FIEMAP on $fm_file failed; returned " \
13739                                 "len $tot_len for OST $last_lun instead of 1024"
13740                                 return
13741                         else
13742                                 (( num_luns += 1 ))
13743                                 tot_len=0
13744                         fi
13745                 fi
13746                 (( tot_len += ext_len ))
13747                 last_lun=$frag_lun
13748         done
13749         if (( num_luns != 2 || tot_len != 512 )); then
13750                 cleanup_130
13751                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13752                         "luns or wrong len for OST $last_lun"
13753                 return
13754         fi
13755
13756         cleanup_130
13757
13758         echo "FIEMAP on 2-stripe file with hole succeeded"
13759 }
13760 run_test 130c "FIEMAP (2-stripe file with hole)"
13761
13762 test_130d() {
13763         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13764
13765         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13766         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13767
13768         trap cleanup_130 EXIT RETURN
13769
13770         local fm_file=$DIR/$tfile
13771         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13772                         error "setstripe on $fm_file"
13773         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13774                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13775
13776         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13777         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13778                 error "dd failed on $fm_file"
13779
13780         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13781         filefrag_op=$(filefrag -ve -k $fm_file |
13782                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13783
13784         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13785                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13786
13787         IFS=$'\n'
13788         tot_len=0
13789         num_luns=1
13790         for line in $filefrag_op
13791         do
13792                 frag_lun=$(echo $line | cut -d: -f5 |
13793                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13794                 ext_len=$(echo $line | cut -d: -f4)
13795                 if (( $frag_lun != $last_lun )); then
13796                         if (( tot_len != 1024 )); then
13797                                 cleanup_130
13798                                 error "FIEMAP on $fm_file failed; returned " \
13799                                 "len $tot_len for OST $last_lun instead of 1024"
13800                                 return
13801                         else
13802                                 (( num_luns += 1 ))
13803                                 tot_len=0
13804                         fi
13805                 fi
13806                 (( tot_len += ext_len ))
13807                 last_lun=$frag_lun
13808         done
13809         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13810                 cleanup_130
13811                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13812                         "luns or wrong len for OST $last_lun"
13813                 return
13814         fi
13815
13816         cleanup_130
13817
13818         echo "FIEMAP on N-stripe file succeeded"
13819 }
13820 run_test 130d "FIEMAP (N-stripe file)"
13821
13822 test_130e() {
13823         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13824
13825         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13826         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13827
13828         trap cleanup_130 EXIT RETURN
13829
13830         local fm_file=$DIR/$tfile
13831         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13832
13833         NUM_BLKS=512
13834         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13835         for ((i = 0; i < $NUM_BLKS; i++)); do
13836                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13837                         conv=notrunc > /dev/null 2>&1
13838         done
13839
13840         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13841         filefrag_op=$(filefrag -ve -k $fm_file |
13842                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13843
13844         last_lun=$(echo $filefrag_op | cut -d: -f5)
13845
13846         IFS=$'\n'
13847         tot_len=0
13848         num_luns=1
13849         for line in $filefrag_op; do
13850                 frag_lun=$(echo $line | cut -d: -f5)
13851                 ext_len=$(echo $line | cut -d: -f4)
13852                 if [[ "$frag_lun" != "$last_lun" ]]; then
13853                         if (( tot_len != $EXPECTED_LEN )); then
13854                                 cleanup_130
13855                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13856                         else
13857                                 (( num_luns += 1 ))
13858                                 tot_len=0
13859                         fi
13860                 fi
13861                 (( tot_len += ext_len ))
13862                 last_lun=$frag_lun
13863         done
13864         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13865                 cleanup_130
13866                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13867         fi
13868
13869         echo "FIEMAP with continuation calls succeeded"
13870 }
13871 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13872
13873 test_130f() {
13874         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13875         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13876
13877         local fm_file=$DIR/$tfile
13878         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13879                 error "multiop create with lov_delay_create on $fm_file"
13880
13881         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13882         filefrag_extents=$(filefrag -vek $fm_file |
13883                            awk '/extents? found/ { print $2 }')
13884         if [[ "$filefrag_extents" != "0" ]]; then
13885                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13886         fi
13887
13888         rm -f $fm_file
13889 }
13890 run_test 130f "FIEMAP (unstriped file)"
13891
13892 test_130g() {
13893         local file=$DIR/$tfile
13894         local nr=$((OSTCOUNT * 100))
13895
13896         $LFS setstripe -C $nr $file ||
13897                 error "failed to setstripe -C $nr $file"
13898
13899         dd if=/dev/zero of=$file count=$nr bs=1M
13900         sync
13901         nr=$($LFS getstripe -c $file)
13902
13903         local extents=$(filefrag -v $file |
13904                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13905
13906         echo "filefrag list $extents extents in file with stripecount $nr"
13907         if (( extents < nr )); then
13908                 $LFS getstripe $file
13909                 filefrag -v $file
13910                 error "filefrag printed $extents < $nr extents"
13911         fi
13912
13913         rm -f $file
13914 }
13915 run_test 130g "FIEMAP (overstripe file)"
13916
13917 # Test for writev/readv
13918 test_131a() {
13919         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13920                 error "writev test failed"
13921         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13922                 error "readv failed"
13923         rm -f $DIR/$tfile
13924 }
13925 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13926
13927 test_131b() {
13928         local fsize=$((524288 + 1048576 + 1572864))
13929         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13930                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13931                         error "append writev test failed"
13932
13933         ((fsize += 1572864 + 1048576))
13934         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13935                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13936                         error "append writev test failed"
13937         rm -f $DIR/$tfile
13938 }
13939 run_test 131b "test append writev"
13940
13941 test_131c() {
13942         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13943         error "NOT PASS"
13944 }
13945 run_test 131c "test read/write on file w/o objects"
13946
13947 test_131d() {
13948         rwv -f $DIR/$tfile -w -n 1 1572864
13949         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13950         if [ "$NOB" != 1572864 ]; then
13951                 error "Short read filed: read $NOB bytes instead of 1572864"
13952         fi
13953         rm -f $DIR/$tfile
13954 }
13955 run_test 131d "test short read"
13956
13957 test_131e() {
13958         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13959         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13960         error "read hitting hole failed"
13961         rm -f $DIR/$tfile
13962 }
13963 run_test 131e "test read hitting hole"
13964
13965 check_stats() {
13966         local facet=$1
13967         local op=$2
13968         local want=${3:-0}
13969         local res
13970
13971         case $facet in
13972         mds*) res=$(do_facet $facet \
13973                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13974                  ;;
13975         ost*) res=$(do_facet $facet \
13976                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13977                  ;;
13978         *) error "Wrong facet '$facet'" ;;
13979         esac
13980         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13981         # if the argument $3 is zero, it means any stat increment is ok.
13982         if [[ $want -gt 0 ]]; then
13983                 local count=$(echo $res | awk '{ print $2 }')
13984                 [[ $count -ne $want ]] &&
13985                         error "The $op counter on $facet is $count, not $want"
13986         fi
13987 }
13988
13989 test_133a() {
13990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13991         remote_ost_nodsh && skip "remote OST with nodsh"
13992         remote_mds_nodsh && skip "remote MDS with nodsh"
13993         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13994                 skip_env "MDS doesn't support rename stats"
13995
13996         local testdir=$DIR/${tdir}/stats_testdir
13997
13998         mkdir -p $DIR/${tdir}
13999
14000         # clear stats.
14001         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14002         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14003
14004         # verify mdt stats first.
14005         mkdir ${testdir} || error "mkdir failed"
14006         check_stats $SINGLEMDS "mkdir" 1
14007         touch ${testdir}/${tfile} || error "touch failed"
14008         check_stats $SINGLEMDS "open" 1
14009         check_stats $SINGLEMDS "close" 1
14010         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14011                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14012                 check_stats $SINGLEMDS "mknod" 2
14013         }
14014         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14015         check_stats $SINGLEMDS "unlink" 1
14016         rm -f ${testdir}/${tfile} || error "file remove failed"
14017         check_stats $SINGLEMDS "unlink" 2
14018
14019         # remove working dir and check mdt stats again.
14020         rmdir ${testdir} || error "rmdir failed"
14021         check_stats $SINGLEMDS "rmdir" 1
14022
14023         local testdir1=$DIR/${tdir}/stats_testdir1
14024         mkdir -p ${testdir}
14025         mkdir -p ${testdir1}
14026         touch ${testdir1}/test1
14027         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14028         check_stats $SINGLEMDS "crossdir_rename" 1
14029
14030         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14031         check_stats $SINGLEMDS "samedir_rename" 1
14032
14033         rm -rf $DIR/${tdir}
14034 }
14035 run_test 133a "Verifying MDT stats ========================================"
14036
14037 test_133b() {
14038         local res
14039
14040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14041         remote_ost_nodsh && skip "remote OST with nodsh"
14042         remote_mds_nodsh && skip "remote MDS with nodsh"
14043
14044         local testdir=$DIR/${tdir}/stats_testdir
14045
14046         mkdir -p ${testdir} || error "mkdir failed"
14047         touch ${testdir}/${tfile} || error "touch failed"
14048         cancel_lru_locks mdc
14049
14050         # clear stats.
14051         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14052         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14053
14054         # extra mdt stats verification.
14055         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14056         check_stats $SINGLEMDS "setattr" 1
14057         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14058         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14059         then            # LU-1740
14060                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14061                 check_stats $SINGLEMDS "getattr" 1
14062         fi
14063         rm -rf $DIR/${tdir}
14064
14065         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14066         # so the check below is not reliable
14067         [ $MDSCOUNT -eq 1 ] || return 0
14068
14069         # Sleep to avoid a cached response.
14070         #define OBD_STATFS_CACHE_SECONDS 1
14071         sleep 2
14072         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14073         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14074         $LFS df || error "lfs failed"
14075         check_stats $SINGLEMDS "statfs" 1
14076
14077         # check aggregated statfs (LU-10018)
14078         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14079                 return 0
14080         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14081                 return 0
14082         sleep 2
14083         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14084         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14085         df $DIR
14086         check_stats $SINGLEMDS "statfs" 1
14087
14088         # We want to check that the client didn't send OST_STATFS to
14089         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14090         # extra care is needed here.
14091         if remote_mds; then
14092                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14093                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14094
14095                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14096                 [ "$res" ] && error "OST got STATFS"
14097         fi
14098
14099         return 0
14100 }
14101 run_test 133b "Verifying extra MDT stats =================================="
14102
14103 test_133c() {
14104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14105         remote_ost_nodsh && skip "remote OST with nodsh"
14106         remote_mds_nodsh && skip "remote MDS with nodsh"
14107
14108         local testdir=$DIR/$tdir/stats_testdir
14109
14110         test_mkdir -p $testdir
14111
14112         # verify obdfilter stats.
14113         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14114         sync
14115         cancel_lru_locks osc
14116         wait_delete_completed
14117
14118         # clear stats.
14119         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14120         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14121
14122         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14123                 error "dd failed"
14124         sync
14125         cancel_lru_locks osc
14126         check_stats ost1 "write" 1
14127
14128         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14129         check_stats ost1 "read" 1
14130
14131         > $testdir/$tfile || error "truncate failed"
14132         check_stats ost1 "punch" 1
14133
14134         rm -f $testdir/$tfile || error "file remove failed"
14135         wait_delete_completed
14136         check_stats ost1 "destroy" 1
14137
14138         rm -rf $DIR/$tdir
14139 }
14140 run_test 133c "Verifying OST stats ========================================"
14141
14142 order_2() {
14143         local value=$1
14144         local orig=$value
14145         local order=1
14146
14147         while [ $value -ge 2 ]; do
14148                 order=$((order*2))
14149                 value=$((value/2))
14150         done
14151
14152         if [ $orig -gt $order ]; then
14153                 order=$((order*2))
14154         fi
14155         echo $order
14156 }
14157
14158 size_in_KMGT() {
14159     local value=$1
14160     local size=('K' 'M' 'G' 'T');
14161     local i=0
14162     local size_string=$value
14163
14164     while [ $value -ge 1024 ]; do
14165         if [ $i -gt 3 ]; then
14166             #T is the biggest unit we get here, if that is bigger,
14167             #just return XXXT
14168             size_string=${value}T
14169             break
14170         fi
14171         value=$((value >> 10))
14172         if [ $value -lt 1024 ]; then
14173             size_string=${value}${size[$i]}
14174             break
14175         fi
14176         i=$((i + 1))
14177     done
14178
14179     echo $size_string
14180 }
14181
14182 get_rename_size() {
14183         local size=$1
14184         local context=${2:-.}
14185         local sample=$(do_facet $SINGLEMDS $LCTL \
14186                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14187                 grep -A1 $context |
14188                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14189         echo $sample
14190 }
14191
14192 test_133d() {
14193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14194         remote_ost_nodsh && skip "remote OST with nodsh"
14195         remote_mds_nodsh && skip "remote MDS with nodsh"
14196         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14197                 skip_env "MDS doesn't support rename stats"
14198
14199         local testdir1=$DIR/${tdir}/stats_testdir1
14200         local testdir2=$DIR/${tdir}/stats_testdir2
14201         mkdir -p $DIR/${tdir}
14202
14203         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14204
14205         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14206         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14207
14208         createmany -o $testdir1/test 512 || error "createmany failed"
14209
14210         # check samedir rename size
14211         mv ${testdir1}/test0 ${testdir1}/test_0
14212
14213         local testdir1_size=$(ls -l $DIR/${tdir} |
14214                 awk '/stats_testdir1/ {print $5}')
14215         local testdir2_size=$(ls -l $DIR/${tdir} |
14216                 awk '/stats_testdir2/ {print $5}')
14217
14218         testdir1_size=$(order_2 $testdir1_size)
14219         testdir2_size=$(order_2 $testdir2_size)
14220
14221         testdir1_size=$(size_in_KMGT $testdir1_size)
14222         testdir2_size=$(size_in_KMGT $testdir2_size)
14223
14224         echo "source rename dir size: ${testdir1_size}"
14225         echo "target rename dir size: ${testdir2_size}"
14226
14227         local cmd="do_facet $SINGLEMDS $LCTL "
14228         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14229
14230         eval $cmd || error "$cmd failed"
14231         local samedir=$($cmd | grep 'same_dir')
14232         local same_sample=$(get_rename_size $testdir1_size)
14233         [ -z "$samedir" ] && error "samedir_rename_size count error"
14234         [[ $same_sample -eq 1 ]] ||
14235                 error "samedir_rename_size error $same_sample"
14236         echo "Check same dir rename stats success"
14237
14238         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14239
14240         # check crossdir rename size
14241         mv ${testdir1}/test_0 ${testdir2}/test_0
14242
14243         testdir1_size=$(ls -l $DIR/${tdir} |
14244                 awk '/stats_testdir1/ {print $5}')
14245         testdir2_size=$(ls -l $DIR/${tdir} |
14246                 awk '/stats_testdir2/ {print $5}')
14247
14248         testdir1_size=$(order_2 $testdir1_size)
14249         testdir2_size=$(order_2 $testdir2_size)
14250
14251         testdir1_size=$(size_in_KMGT $testdir1_size)
14252         testdir2_size=$(size_in_KMGT $testdir2_size)
14253
14254         echo "source rename dir size: ${testdir1_size}"
14255         echo "target rename dir size: ${testdir2_size}"
14256
14257         eval $cmd || error "$cmd failed"
14258         local crossdir=$($cmd | grep 'crossdir')
14259         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14260         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14261         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14262         [[ $src_sample -eq 1 ]] ||
14263                 error "crossdir_rename_size error $src_sample"
14264         [[ $tgt_sample -eq 1 ]] ||
14265                 error "crossdir_rename_size error $tgt_sample"
14266         echo "Check cross dir rename stats success"
14267         rm -rf $DIR/${tdir}
14268 }
14269 run_test 133d "Verifying rename_stats ========================================"
14270
14271 test_133e() {
14272         remote_mds_nodsh && skip "remote MDS with nodsh"
14273         remote_ost_nodsh && skip "remote OST with nodsh"
14274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14275
14276         local testdir=$DIR/${tdir}/stats_testdir
14277         local ctr f0 f1 bs=32768 count=42 sum
14278
14279         mkdir -p ${testdir} || error "mkdir failed"
14280
14281         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14282
14283         for ctr in {write,read}_bytes; do
14284                 sync
14285                 cancel_lru_locks osc
14286
14287                 do_facet ost1 $LCTL set_param -n \
14288                         "obdfilter.*.exports.clear=clear"
14289
14290                 if [ $ctr = write_bytes ]; then
14291                         f0=/dev/zero
14292                         f1=${testdir}/${tfile}
14293                 else
14294                         f0=${testdir}/${tfile}
14295                         f1=/dev/null
14296                 fi
14297
14298                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14299                         error "dd failed"
14300                 sync
14301                 cancel_lru_locks osc
14302
14303                 sum=$(do_facet ost1 $LCTL get_param \
14304                         "obdfilter.*.exports.*.stats" |
14305                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14306                                 $1 == ctr { sum += $7 }
14307                                 END { printf("%0.0f", sum) }')
14308
14309                 if ((sum != bs * count)); then
14310                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14311                 fi
14312         done
14313
14314         rm -rf $DIR/${tdir}
14315 }
14316 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14317
14318 test_133f() {
14319         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14320                 skip "too old lustre for get_param -R ($facet_ver)"
14321
14322         # verifying readability.
14323         $LCTL get_param -R '*' &> /dev/null
14324
14325         # Verifing writability with badarea_io.
14326         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14327         local skipped_params='force_lbug|changelog_mask|daemon_file'
14328         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14329                 egrep -v "$skipped_params" |
14330                 xargs -n 1 find $proc_dirs -name |
14331                 xargs -n 1 badarea_io ||
14332                 error "client badarea_io failed"
14333
14334         # remount the FS in case writes/reads /proc break the FS
14335         cleanup || error "failed to unmount"
14336         setup || error "failed to setup"
14337 }
14338 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14339
14340 test_133g() {
14341         remote_mds_nodsh && skip "remote MDS with nodsh"
14342         remote_ost_nodsh && skip "remote OST with nodsh"
14343
14344         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14345         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14346         local facet
14347         for facet in mds1 ost1; do
14348                 local facet_ver=$(lustre_version_code $facet)
14349                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14350                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14351                 else
14352                         log "$facet: too old lustre for get_param -R"
14353                 fi
14354                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14355                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14356                                 tr -d = | egrep -v $skipped_params |
14357                                 xargs -n 1 find $proc_dirs -name |
14358                                 xargs -n 1 badarea_io" ||
14359                                         error "$facet badarea_io failed"
14360                 else
14361                         skip_noexit "$facet: too old lustre for get_param -R"
14362                 fi
14363         done
14364
14365         # remount the FS in case writes/reads /proc break the FS
14366         cleanup || error "failed to unmount"
14367         setup || error "failed to setup"
14368 }
14369 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14370
14371 test_133h() {
14372         remote_mds_nodsh && skip "remote MDS with nodsh"
14373         remote_ost_nodsh && skip "remote OST with nodsh"
14374         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14375                 skip "Need MDS version at least 2.9.54"
14376
14377         local facet
14378         for facet in client mds1 ost1; do
14379                 # Get the list of files that are missing the terminating newline
14380                 local plist=$(do_facet $facet
14381                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14382                 local ent
14383                 for ent in $plist; do
14384                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14385                                 awk -v FS='\v' -v RS='\v\v' \
14386                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14387                                         print FILENAME}'" 2>/dev/null)
14388                         [ -z $missing ] || {
14389                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14390                                 error "file does not end with newline: $facet-$ent"
14391                         }
14392                 done
14393         done
14394 }
14395 run_test 133h "Proc files should end with newlines"
14396
14397 test_134a() {
14398         remote_mds_nodsh && skip "remote MDS with nodsh"
14399         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14400                 skip "Need MDS version at least 2.7.54"
14401
14402         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14403         cancel_lru_locks mdc
14404
14405         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14406         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14407         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14408
14409         local nr=1000
14410         createmany -o $DIR/$tdir/f $nr ||
14411                 error "failed to create $nr files in $DIR/$tdir"
14412         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14413
14414         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14415         do_facet mds1 $LCTL set_param fail_loc=0x327
14416         do_facet mds1 $LCTL set_param fail_val=500
14417         touch $DIR/$tdir/m
14418
14419         echo "sleep 10 seconds ..."
14420         sleep 10
14421         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14422
14423         do_facet mds1 $LCTL set_param fail_loc=0
14424         do_facet mds1 $LCTL set_param fail_val=0
14425         [ $lck_cnt -lt $unused ] ||
14426                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14427
14428         rm $DIR/$tdir/m
14429         unlinkmany $DIR/$tdir/f $nr
14430 }
14431 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14432
14433 test_134b() {
14434         remote_mds_nodsh && skip "remote MDS with nodsh"
14435         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14436                 skip "Need MDS version at least 2.7.54"
14437
14438         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14439         cancel_lru_locks mdc
14440
14441         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14442                         ldlm.lock_reclaim_threshold_mb)
14443         # disable reclaim temporarily
14444         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14445
14446         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14447         do_facet mds1 $LCTL set_param fail_loc=0x328
14448         do_facet mds1 $LCTL set_param fail_val=500
14449
14450         $LCTL set_param debug=+trace
14451
14452         local nr=600
14453         createmany -o $DIR/$tdir/f $nr &
14454         local create_pid=$!
14455
14456         echo "Sleep $TIMEOUT seconds ..."
14457         sleep $TIMEOUT
14458         if ! ps -p $create_pid  > /dev/null 2>&1; then
14459                 do_facet mds1 $LCTL set_param fail_loc=0
14460                 do_facet mds1 $LCTL set_param fail_val=0
14461                 do_facet mds1 $LCTL set_param \
14462                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14463                 error "createmany finished incorrectly!"
14464         fi
14465         do_facet mds1 $LCTL set_param fail_loc=0
14466         do_facet mds1 $LCTL set_param fail_val=0
14467         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14468         wait $create_pid || return 1
14469
14470         unlinkmany $DIR/$tdir/f $nr
14471 }
14472 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14473
14474 test_135() {
14475         remote_mds_nodsh && skip "remote MDS with nodsh"
14476         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14477                 skip "Need MDS version at least 2.13.50"
14478         local fname
14479
14480         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14481
14482 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14483         #set only one record at plain llog
14484         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14485
14486         #fill already existed plain llog each 64767
14487         #wrapping whole catalog
14488         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14489
14490         createmany -o $DIR/$tdir/$tfile_ 64700
14491         for (( i = 0; i < 64700; i = i + 2 ))
14492         do
14493                 rm $DIR/$tdir/$tfile_$i &
14494                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14495                 local pid=$!
14496                 wait $pid
14497         done
14498
14499         #waiting osp synchronization
14500         wait_delete_completed
14501 }
14502 run_test 135 "Race catalog processing"
14503
14504 test_136() {
14505         remote_mds_nodsh && skip "remote MDS with nodsh"
14506         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14507                 skip "Need MDS version at least 2.13.50"
14508         local fname
14509
14510         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14511         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14512         #set only one record at plain llog
14513 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14514         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14515
14516         #fill already existed 2 plain llogs each 64767
14517         #wrapping whole catalog
14518         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14519         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14520         wait_delete_completed
14521
14522         createmany -o $DIR/$tdir/$tfile_ 10
14523         sleep 25
14524
14525         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14526         for (( i = 0; i < 10; i = i + 3 ))
14527         do
14528                 rm $DIR/$tdir/$tfile_$i &
14529                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14530                 local pid=$!
14531                 wait $pid
14532                 sleep 7
14533                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14534         done
14535
14536         #waiting osp synchronization
14537         wait_delete_completed
14538 }
14539 run_test 136 "Race catalog processing 2"
14540
14541 test_140() { #bug-17379
14542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14543
14544         test_mkdir $DIR/$tdir
14545         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14546         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14547
14548         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14549         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14550         local i=0
14551         while i=$((i + 1)); do
14552                 test_mkdir $i
14553                 cd $i || error "Changing to $i"
14554                 ln -s ../stat stat || error "Creating stat symlink"
14555                 # Read the symlink until ELOOP present,
14556                 # not LBUGing the system is considered success,
14557                 # we didn't overrun the stack.
14558                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14559                 if [ $ret -ne 0 ]; then
14560                         if [ $ret -eq 40 ]; then
14561                                 break  # -ELOOP
14562                         else
14563                                 error "Open stat symlink"
14564                                         return
14565                         fi
14566                 fi
14567         done
14568         i=$((i - 1))
14569         echo "The symlink depth = $i"
14570         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14571                 error "Invalid symlink depth"
14572
14573         # Test recursive symlink
14574         ln -s symlink_self symlink_self
14575         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14576         echo "open symlink_self returns $ret"
14577         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14578 }
14579 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14580
14581 test_150a() {
14582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14583
14584         local TF="$TMP/$tfile"
14585
14586         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14587         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14588         cp $TF $DIR/$tfile
14589         cancel_lru_locks $OSC
14590         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14591         remount_client $MOUNT
14592         df -P $MOUNT
14593         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14594
14595         $TRUNCATE $TF 6000
14596         $TRUNCATE $DIR/$tfile 6000
14597         cancel_lru_locks $OSC
14598         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14599
14600         echo "12345" >>$TF
14601         echo "12345" >>$DIR/$tfile
14602         cancel_lru_locks $OSC
14603         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14604
14605         echo "12345" >>$TF
14606         echo "12345" >>$DIR/$tfile
14607         cancel_lru_locks $OSC
14608         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14609 }
14610 run_test 150a "truncate/append tests"
14611
14612 test_150b() {
14613         check_set_fallocate_or_skip
14614
14615         touch $DIR/$tfile
14616         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14617         check_fallocate $DIR/$tfile || skip_eopnotsupp "fallocate failed"
14618 }
14619 run_test 150b "Verify fallocate (prealloc) functionality"
14620
14621 test_150bb() {
14622         check_set_fallocate_or_skip
14623
14624         touch $DIR/$tfile
14625         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14626         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14627         > $DIR/$tfile
14628         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14629         # precomputed md5sum for 20MB of zeroes
14630         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14631         local sum=($(md5sum $DIR/$tfile))
14632
14633         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14634
14635         check_set_fallocate 1
14636
14637         > $DIR/$tfile
14638         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14639         sum=($(md5sum $DIR/$tfile))
14640
14641         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14642 }
14643 run_test 150bb "Verify fallocate modes both zero space"
14644
14645 test_150c() {
14646         check_set_fallocate_or_skip
14647         local striping="-c2"
14648
14649         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14650         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14651         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14652         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14653         local want=$((OSTCOUNT * 1048576))
14654
14655         # Must allocate all requested space, not more than 5% extra
14656         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14657                 error "bytes $bytes is not $want"
14658
14659         rm -f $DIR/$tfile
14660
14661         echo "verify fallocate on PFL file"
14662
14663         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14664
14665         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14666                 error "Create $DIR/$tfile failed"
14667         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
14668         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14669         want=$((512 * 1048576))
14670
14671         # Must allocate all requested space, not more than 5% extra
14672         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14673                 error "bytes $bytes is not $want"
14674 }
14675 run_test 150c "Verify fallocate Size and Blocks"
14676
14677 test_150d() {
14678         check_set_fallocate_or_skip
14679         local striping="-c2"
14680
14681         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14682
14683         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14684         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14685                 error "setstripe failed"
14686         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14687         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14688         local want=$((OSTCOUNT * 1048576))
14689
14690         # Must allocate all requested space, not more than 5% extra
14691         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14692                 error "bytes $bytes is not $want"
14693 }
14694 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14695
14696 test_150e() {
14697         check_set_fallocate_or_skip
14698
14699         echo "df before:"
14700         $LFS df
14701         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14702         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14703                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14704
14705         # Find OST with Minimum Size
14706         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14707                        sort -un | head -1)
14708
14709         # Get 100MB per OST of the available space to reduce run time
14710         # else 60% of the available space if we are running SLOW tests
14711         if [ $SLOW == "no" ]; then
14712                 local space=$((1024 * 100 * OSTCOUNT))
14713         else
14714                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14715         fi
14716
14717         fallocate -l${space}k $DIR/$tfile ||
14718                 error "fallocate ${space}k $DIR/$tfile failed"
14719         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14720
14721         # get size immediately after fallocate. This should be correctly
14722         # updated
14723         local size=$(stat -c '%s' $DIR/$tfile)
14724         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14725
14726         # Sleep for a while for statfs to get updated. And not pull from cache.
14727         sleep 2
14728
14729         echo "df after fallocate:"
14730         $LFS df
14731
14732         (( size / 1024 == space )) || error "size $size != requested $space"
14733         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14734                 error "used $used < space $space"
14735
14736         rm $DIR/$tfile || error "rm failed"
14737         sync
14738         wait_delete_completed
14739
14740         echo "df after unlink:"
14741         $LFS df
14742 }
14743 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14744
14745 test_150f() {
14746         local size
14747         local blocks
14748         local want_size_before=20480 # in bytes
14749         local want_blocks_before=40 # 512 sized blocks
14750         local want_blocks_after=24  # 512 sized blocks
14751         local length=$(((want_blocks_before - want_blocks_after) * 512))
14752
14753         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14754                 skip "need at least 2.14.0 for fallocate punch"
14755
14756         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14757                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14758         fi
14759
14760         check_set_fallocate_or_skip
14761         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14762
14763         [[ "x$DOM" == "xyes" ]] &&
14764                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14765
14766         echo "Verify fallocate punch: Range within the file range"
14767         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14768                 error "dd failed for bs 4096 and count 5"
14769
14770         # Call fallocate with punch range which is within the file range
14771         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
14772                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
14773         # client must see changes immediately after fallocate
14774         size=$(stat -c '%s' $DIR/$tfile)
14775         blocks=$(stat -c '%b' $DIR/$tfile)
14776
14777         # Verify punch worked.
14778         (( blocks == want_blocks_after )) ||
14779                 error "punch failed: blocks $blocks != $want_blocks_after"
14780
14781         (( size == want_size_before )) ||
14782                 error "punch failed: size $size != $want_size_before"
14783
14784         # Verify there is hole in file
14785         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14786         # precomputed md5sum
14787         local expect="4a9a834a2db02452929c0a348273b4aa"
14788
14789         cksum=($(md5sum $DIR/$tfile))
14790         [[ "${cksum[0]}" == "$expect" ]] ||
14791                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14792
14793         # Start second sub-case for fallocate punch.
14794         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14795         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14796                 error "dd failed for bs 4096 and count 5"
14797
14798         # Punch range less than block size will have no change in block count
14799         want_blocks_after=40  # 512 sized blocks
14800
14801         # Punch overlaps two blocks and less than blocksize
14802         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
14803                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
14804         size=$(stat -c '%s' $DIR/$tfile)
14805         blocks=$(stat -c '%b' $DIR/$tfile)
14806
14807         # Verify punch worked.
14808         (( blocks == want_blocks_after )) ||
14809                 error "punch failed: blocks $blocks != $want_blocks_after"
14810
14811         (( size == want_size_before )) ||
14812                 error "punch failed: size $size != $want_size_before"
14813
14814         # Verify if range is really zero'ed out. We expect Zeros.
14815         # precomputed md5sum
14816         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14817         cksum=($(md5sum $DIR/$tfile))
14818         [[ "${cksum[0]}" == "$expect" ]] ||
14819                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14820 }
14821 run_test 150f "Verify fallocate punch functionality"
14822
14823 test_150g() {
14824         local space
14825         local size
14826         local blocks
14827         local blocks_after
14828         local size_after
14829         local BS=4096 # Block size in bytes
14830
14831         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14832                 skip "need at least 2.14.0 for fallocate punch"
14833
14834         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14835                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14836         fi
14837
14838         check_set_fallocate_or_skip
14839         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14840
14841         if [[ "x$DOM" == "xyes" ]]; then
14842                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
14843                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
14844         else
14845                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14846                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14847         fi
14848
14849         # Get 100MB per OST of the available space to reduce run time
14850         # else 60% of the available space if we are running SLOW tests
14851         if [ $SLOW == "no" ]; then
14852                 space=$((1024 * 100 * OSTCOUNT))
14853         else
14854                 # Find OST with Minimum Size
14855                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14856                         sort -un | head -1)
14857                 echo "min size OST: $space"
14858                 space=$(((space * 60)/100 * OSTCOUNT))
14859         fi
14860         # space in 1k units, round to 4k blocks
14861         local blkcount=$((space * 1024 / $BS))
14862
14863         echo "Verify fallocate punch: Very large Range"
14864         fallocate -l${space}k $DIR/$tfile ||
14865                 error "fallocate ${space}k $DIR/$tfile failed"
14866         # write 1M at the end, start and in the middle
14867         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14868                 error "dd failed: bs $BS count 256"
14869         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14870                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14871         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14872                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14873
14874         # Gather stats.
14875         size=$(stat -c '%s' $DIR/$tfile)
14876
14877         # gather punch length.
14878         local punch_size=$((size - (BS * 2)))
14879
14880         echo "punch_size = $punch_size"
14881         echo "size - punch_size: $((size - punch_size))"
14882         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14883
14884         # Call fallocate to punch all except 2 blocks. We leave the
14885         # first and the last block
14886         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14887         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
14888                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
14889
14890         size_after=$(stat -c '%s' $DIR/$tfile)
14891         blocks_after=$(stat -c '%b' $DIR/$tfile)
14892
14893         # Verify punch worked.
14894         # Size should be kept
14895         (( size == size_after )) ||
14896                 error "punch failed: size $size != $size_after"
14897
14898         # two 4k data blocks to remain plus possible 1 extra extent block
14899         (( blocks_after <= ((BS / 512) * 3) )) ||
14900                 error "too many blocks remains: $blocks_after"
14901
14902         # Verify that file has hole between the first and the last blocks
14903         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14904         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14905
14906         echo "Hole at [$hole_start, $hole_end)"
14907         (( hole_start == BS )) ||
14908                 error "no hole at offset $BS after punch"
14909
14910         (( hole_end == BS + punch_size )) ||
14911                 error "data at offset $hole_end < $((BS + punch_size))"
14912 }
14913 run_test 150g "Verify fallocate punch on large range"
14914
14915 #LU-2902 roc_hit was not able to read all values from lproc
14916 function roc_hit_init() {
14917         local list=$(comma_list $(osts_nodes))
14918         local dir=$DIR/$tdir-check
14919         local file=$dir/$tfile
14920         local BEFORE
14921         local AFTER
14922         local idx
14923
14924         test_mkdir $dir
14925         #use setstripe to do a write to every ost
14926         for i in $(seq 0 $((OSTCOUNT-1))); do
14927                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14928                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14929                 idx=$(printf %04x $i)
14930                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14931                         awk '$1 == "cache_access" {sum += $7}
14932                                 END { printf("%0.0f", sum) }')
14933
14934                 cancel_lru_locks osc
14935                 cat $file >/dev/null
14936
14937                 AFTER=$(get_osd_param $list *OST*$idx stats |
14938                         awk '$1 == "cache_access" {sum += $7}
14939                                 END { printf("%0.0f", sum) }')
14940
14941                 echo BEFORE:$BEFORE AFTER:$AFTER
14942                 if ! let "AFTER - BEFORE == 4"; then
14943                         rm -rf $dir
14944                         error "roc_hit is not safe to use"
14945                 fi
14946                 rm $file
14947         done
14948
14949         rm -rf $dir
14950 }
14951
14952 function roc_hit() {
14953         local list=$(comma_list $(osts_nodes))
14954         echo $(get_osd_param $list '' stats |
14955                 awk '$1 == "cache_hit" {sum += $7}
14956                         END { printf("%0.0f", sum) }')
14957 }
14958
14959 function set_cache() {
14960         local on=1
14961
14962         if [ "$2" == "off" ]; then
14963                 on=0;
14964         fi
14965         local list=$(comma_list $(osts_nodes))
14966         set_osd_param $list '' $1_cache_enable $on
14967
14968         cancel_lru_locks osc
14969 }
14970
14971 test_151() {
14972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14973         remote_ost_nodsh && skip "remote OST with nodsh"
14974
14975         local CPAGES=3
14976         local list=$(comma_list $(osts_nodes))
14977
14978         # check whether obdfilter is cache capable at all
14979         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14980                 skip "not cache-capable obdfilter"
14981         fi
14982
14983         # check cache is enabled on all obdfilters
14984         if get_osd_param $list '' read_cache_enable | grep 0; then
14985                 skip "oss cache is disabled"
14986         fi
14987
14988         set_osd_param $list '' writethrough_cache_enable 1
14989
14990         # check write cache is enabled on all obdfilters
14991         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14992                 skip "oss write cache is NOT enabled"
14993         fi
14994
14995         roc_hit_init
14996
14997         #define OBD_FAIL_OBD_NO_LRU  0x609
14998         do_nodes $list $LCTL set_param fail_loc=0x609
14999
15000         # pages should be in the case right after write
15001         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15002                 error "dd failed"
15003
15004         local BEFORE=$(roc_hit)
15005         cancel_lru_locks osc
15006         cat $DIR/$tfile >/dev/null
15007         local AFTER=$(roc_hit)
15008
15009         do_nodes $list $LCTL set_param fail_loc=0
15010
15011         if ! let "AFTER - BEFORE == CPAGES"; then
15012                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15013         fi
15014
15015         cancel_lru_locks osc
15016         # invalidates OST cache
15017         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15018         set_osd_param $list '' read_cache_enable 0
15019         cat $DIR/$tfile >/dev/null
15020
15021         # now data shouldn't be found in the cache
15022         BEFORE=$(roc_hit)
15023         cancel_lru_locks osc
15024         cat $DIR/$tfile >/dev/null
15025         AFTER=$(roc_hit)
15026         if let "AFTER - BEFORE != 0"; then
15027                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15028         fi
15029
15030         set_osd_param $list '' read_cache_enable 1
15031         rm -f $DIR/$tfile
15032 }
15033 run_test 151 "test cache on oss and controls ==============================="
15034
15035 test_152() {
15036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15037
15038         local TF="$TMP/$tfile"
15039
15040         # simulate ENOMEM during write
15041 #define OBD_FAIL_OST_NOMEM      0x226
15042         lctl set_param fail_loc=0x80000226
15043         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15044         cp $TF $DIR/$tfile
15045         sync || error "sync failed"
15046         lctl set_param fail_loc=0
15047
15048         # discard client's cache
15049         cancel_lru_locks osc
15050
15051         # simulate ENOMEM during read
15052         lctl set_param fail_loc=0x80000226
15053         cmp $TF $DIR/$tfile || error "cmp failed"
15054         lctl set_param fail_loc=0
15055
15056         rm -f $TF
15057 }
15058 run_test 152 "test read/write with enomem ============================"
15059
15060 test_153() {
15061         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15062 }
15063 run_test 153 "test if fdatasync does not crash ======================="
15064
15065 dot_lustre_fid_permission_check() {
15066         local fid=$1
15067         local ffid=$MOUNT/.lustre/fid/$fid
15068         local test_dir=$2
15069
15070         echo "stat fid $fid"
15071         stat $ffid > /dev/null || error "stat $ffid failed."
15072         echo "touch fid $fid"
15073         touch $ffid || error "touch $ffid failed."
15074         echo "write to fid $fid"
15075         cat /etc/hosts > $ffid || error "write $ffid failed."
15076         echo "read fid $fid"
15077         diff /etc/hosts $ffid || error "read $ffid failed."
15078         echo "append write to fid $fid"
15079         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15080         echo "rename fid $fid"
15081         mv $ffid $test_dir/$tfile.1 &&
15082                 error "rename $ffid to $tfile.1 should fail."
15083         touch $test_dir/$tfile.1
15084         mv $test_dir/$tfile.1 $ffid &&
15085                 error "rename $tfile.1 to $ffid should fail."
15086         rm -f $test_dir/$tfile.1
15087         echo "truncate fid $fid"
15088         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15089         echo "link fid $fid"
15090         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15091         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15092                 echo "setfacl fid $fid"
15093                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
15094                 echo "getfacl fid $fid"
15095                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
15096         fi
15097         echo "unlink fid $fid"
15098         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15099         echo "mknod fid $fid"
15100         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15101
15102         fid=[0xf00000400:0x1:0x0]
15103         ffid=$MOUNT/.lustre/fid/$fid
15104
15105         echo "stat non-exist fid $fid"
15106         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15107         echo "write to non-exist fid $fid"
15108         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15109         echo "link new fid $fid"
15110         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15111
15112         mkdir -p $test_dir/$tdir
15113         touch $test_dir/$tdir/$tfile
15114         fid=$($LFS path2fid $test_dir/$tdir)
15115         rc=$?
15116         [ $rc -ne 0 ] &&
15117                 error "error: could not get fid for $test_dir/$dir/$tfile."
15118
15119         ffid=$MOUNT/.lustre/fid/$fid
15120
15121         echo "ls $fid"
15122         ls $ffid > /dev/null || error "ls $ffid failed."
15123         echo "touch $fid/$tfile.1"
15124         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15125
15126         echo "touch $MOUNT/.lustre/fid/$tfile"
15127         touch $MOUNT/.lustre/fid/$tfile && \
15128                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15129
15130         echo "setxattr to $MOUNT/.lustre/fid"
15131         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15132
15133         echo "listxattr for $MOUNT/.lustre/fid"
15134         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15135
15136         echo "delxattr from $MOUNT/.lustre/fid"
15137         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15138
15139         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15140         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15141                 error "touch invalid fid should fail."
15142
15143         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15144         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15145                 error "touch non-normal fid should fail."
15146
15147         echo "rename $tdir to $MOUNT/.lustre/fid"
15148         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15149                 error "rename to $MOUNT/.lustre/fid should fail."
15150
15151         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15152         then            # LU-3547
15153                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15154                 local new_obf_mode=777
15155
15156                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15157                 chmod $new_obf_mode $DIR/.lustre/fid ||
15158                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15159
15160                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15161                 [ $obf_mode -eq $new_obf_mode ] ||
15162                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15163
15164                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15165                 chmod $old_obf_mode $DIR/.lustre/fid ||
15166                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15167         fi
15168
15169         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15170         fid=$($LFS path2fid $test_dir/$tfile-2)
15171
15172         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15173         then # LU-5424
15174                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15175                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15176                         error "create lov data thru .lustre failed"
15177         fi
15178         echo "cp /etc/passwd $test_dir/$tfile-2"
15179         cp /etc/passwd $test_dir/$tfile-2 ||
15180                 error "copy to $test_dir/$tfile-2 failed."
15181         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15182         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15183                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15184
15185         rm -rf $test_dir/tfile.lnk
15186         rm -rf $test_dir/$tfile-2
15187 }
15188
15189 test_154A() {
15190         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15191                 skip "Need MDS version at least 2.4.1"
15192
15193         local tf=$DIR/$tfile
15194         touch $tf
15195
15196         local fid=$($LFS path2fid $tf)
15197         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15198
15199         # check that we get the same pathname back
15200         local rootpath
15201         local found
15202         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15203                 echo "$rootpath $fid"
15204                 found=$($LFS fid2path $rootpath "$fid")
15205                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15206                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15207         done
15208
15209         # check wrong root path format
15210         rootpath=$MOUNT"_wrong"
15211         found=$($LFS fid2path $rootpath "$fid")
15212         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15213 }
15214 run_test 154A "lfs path2fid and fid2path basic checks"
15215
15216 test_154B() {
15217         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15218                 skip "Need MDS version at least 2.4.1"
15219
15220         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15221         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15222         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15223         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15224
15225         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15226         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15227
15228         # check that we get the same pathname
15229         echo "PFID: $PFID, name: $name"
15230         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15231         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15232         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15233                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15234
15235         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15236 }
15237 run_test 154B "verify the ll_decode_linkea tool"
15238
15239 test_154a() {
15240         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15241         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15242         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15243                 skip "Need MDS version at least 2.2.51"
15244         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15245
15246         cp /etc/hosts $DIR/$tfile
15247
15248         fid=$($LFS path2fid $DIR/$tfile)
15249         rc=$?
15250         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15251
15252         dot_lustre_fid_permission_check "$fid" $DIR ||
15253                 error "dot lustre permission check $fid failed"
15254
15255         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15256
15257         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15258
15259         touch $MOUNT/.lustre/file &&
15260                 error "creation is not allowed under .lustre"
15261
15262         mkdir $MOUNT/.lustre/dir &&
15263                 error "mkdir is not allowed under .lustre"
15264
15265         rm -rf $DIR/$tfile
15266 }
15267 run_test 154a "Open-by-FID"
15268
15269 test_154b() {
15270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15271         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15272         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15273         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15274                 skip "Need MDS version at least 2.2.51"
15275
15276         local remote_dir=$DIR/$tdir/remote_dir
15277         local MDTIDX=1
15278         local rc=0
15279
15280         mkdir -p $DIR/$tdir
15281         $LFS mkdir -i $MDTIDX $remote_dir ||
15282                 error "create remote directory failed"
15283
15284         cp /etc/hosts $remote_dir/$tfile
15285
15286         fid=$($LFS path2fid $remote_dir/$tfile)
15287         rc=$?
15288         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15289
15290         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15291                 error "dot lustre permission check $fid failed"
15292         rm -rf $DIR/$tdir
15293 }
15294 run_test 154b "Open-by-FID for remote directory"
15295
15296 test_154c() {
15297         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15298                 skip "Need MDS version at least 2.4.1"
15299
15300         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15301         local FID1=$($LFS path2fid $DIR/$tfile.1)
15302         local FID2=$($LFS path2fid $DIR/$tfile.2)
15303         local FID3=$($LFS path2fid $DIR/$tfile.3)
15304
15305         local N=1
15306         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15307                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15308                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15309                 local want=FID$N
15310                 [ "$FID" = "${!want}" ] ||
15311                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15312                 N=$((N + 1))
15313         done
15314
15315         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15316         do
15317                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15318                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15319                 N=$((N + 1))
15320         done
15321 }
15322 run_test 154c "lfs path2fid and fid2path multiple arguments"
15323
15324 test_154d() {
15325         remote_mds_nodsh && skip "remote MDS with nodsh"
15326         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15327                 skip "Need MDS version at least 2.5.53"
15328
15329         if remote_mds; then
15330                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15331         else
15332                 nid="0@lo"
15333         fi
15334         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15335         local fd
15336         local cmd
15337
15338         rm -f $DIR/$tfile
15339         touch $DIR/$tfile
15340
15341         local fid=$($LFS path2fid $DIR/$tfile)
15342         # Open the file
15343         fd=$(free_fd)
15344         cmd="exec $fd<$DIR/$tfile"
15345         eval $cmd
15346         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15347         echo "$fid_list" | grep "$fid"
15348         rc=$?
15349
15350         cmd="exec $fd>/dev/null"
15351         eval $cmd
15352         if [ $rc -ne 0 ]; then
15353                 error "FID $fid not found in open files list $fid_list"
15354         fi
15355 }
15356 run_test 154d "Verify open file fid"
15357
15358 test_154e()
15359 {
15360         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15361                 skip "Need MDS version at least 2.6.50"
15362
15363         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15364                 error ".lustre returned by readdir"
15365         fi
15366 }
15367 run_test 154e ".lustre is not returned by readdir"
15368
15369 test_154f() {
15370         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15371
15372         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15373         mkdir_on_mdt0 $DIR/$tdir
15374         # test dirs inherit from its stripe
15375         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15376         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15377         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15378         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15379         touch $DIR/f
15380
15381         # get fid of parents
15382         local FID0=$($LFS path2fid $DIR/$tdir)
15383         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15384         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15385         local FID3=$($LFS path2fid $DIR)
15386
15387         # check that path2fid --parents returns expected <parent_fid>/name
15388         # 1) test for a directory (single parent)
15389         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15390         [ "$parent" == "$FID0/foo1" ] ||
15391                 error "expected parent: $FID0/foo1, got: $parent"
15392
15393         # 2) test for a file with nlink > 1 (multiple parents)
15394         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15395         echo "$parent" | grep -F "$FID1/$tfile" ||
15396                 error "$FID1/$tfile not returned in parent list"
15397         echo "$parent" | grep -F "$FID2/link" ||
15398                 error "$FID2/link not returned in parent list"
15399
15400         # 3) get parent by fid
15401         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15402         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15403         echo "$parent" | grep -F "$FID1/$tfile" ||
15404                 error "$FID1/$tfile not returned in parent list (by fid)"
15405         echo "$parent" | grep -F "$FID2/link" ||
15406                 error "$FID2/link not returned in parent list (by fid)"
15407
15408         # 4) test for entry in root directory
15409         parent=$($LFS path2fid --parents $DIR/f)
15410         echo "$parent" | grep -F "$FID3/f" ||
15411                 error "$FID3/f not returned in parent list"
15412
15413         # 5) test it on root directory
15414         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15415                 error "$MOUNT should not have parents"
15416
15417         # enable xattr caching and check that linkea is correctly updated
15418         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15419         save_lustre_params client "llite.*.xattr_cache" > $save
15420         lctl set_param llite.*.xattr_cache 1
15421
15422         # 6.1) linkea update on rename
15423         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15424
15425         # get parents by fid
15426         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15427         # foo1 should no longer be returned in parent list
15428         echo "$parent" | grep -F "$FID1" &&
15429                 error "$FID1 should no longer be in parent list"
15430         # the new path should appear
15431         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15432                 error "$FID2/$tfile.moved is not in parent list"
15433
15434         # 6.2) linkea update on unlink
15435         rm -f $DIR/$tdir/foo2/link
15436         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15437         # foo2/link should no longer be returned in parent list
15438         echo "$parent" | grep -F "$FID2/link" &&
15439                 error "$FID2/link should no longer be in parent list"
15440         true
15441
15442         rm -f $DIR/f
15443         restore_lustre_params < $save
15444         rm -f $save
15445 }
15446 run_test 154f "get parent fids by reading link ea"
15447
15448 test_154g()
15449 {
15450         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15451         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15452            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15453                 skip "Need MDS version at least 2.6.92"
15454
15455         mkdir_on_mdt0 $DIR/$tdir
15456         llapi_fid_test -d $DIR/$tdir
15457 }
15458 run_test 154g "various llapi FID tests"
15459
15460 test_155_small_load() {
15461     local temp=$TMP/$tfile
15462     local file=$DIR/$tfile
15463
15464     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15465         error "dd of=$temp bs=6096 count=1 failed"
15466     cp $temp $file
15467     cancel_lru_locks $OSC
15468     cmp $temp $file || error "$temp $file differ"
15469
15470     $TRUNCATE $temp 6000
15471     $TRUNCATE $file 6000
15472     cmp $temp $file || error "$temp $file differ (truncate1)"
15473
15474     echo "12345" >>$temp
15475     echo "12345" >>$file
15476     cmp $temp $file || error "$temp $file differ (append1)"
15477
15478     echo "12345" >>$temp
15479     echo "12345" >>$file
15480     cmp $temp $file || error "$temp $file differ (append2)"
15481
15482     rm -f $temp $file
15483     true
15484 }
15485
15486 test_155_big_load() {
15487         remote_ost_nodsh && skip "remote OST with nodsh"
15488
15489         local temp=$TMP/$tfile
15490         local file=$DIR/$tfile
15491
15492         free_min_max
15493         local cache_size=$(do_facet ost$((MAXI+1)) \
15494                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15495         local large_file_size=$((cache_size * 2))
15496
15497         echo "OSS cache size: $cache_size KB"
15498         echo "Large file size: $large_file_size KB"
15499
15500         [ $MAXV -le $large_file_size ] &&
15501                 skip_env "max available OST size needs > $large_file_size KB"
15502
15503         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15504
15505         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15506                 error "dd of=$temp bs=$large_file_size count=1k failed"
15507         cp $temp $file
15508         ls -lh $temp $file
15509         cancel_lru_locks osc
15510         cmp $temp $file || error "$temp $file differ"
15511
15512         rm -f $temp $file
15513         true
15514 }
15515
15516 save_writethrough() {
15517         local facets=$(get_facets OST)
15518
15519         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15520 }
15521
15522 test_155a() {
15523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15524
15525         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15526
15527         save_writethrough $p
15528
15529         set_cache read on
15530         set_cache writethrough on
15531         test_155_small_load
15532         restore_lustre_params < $p
15533         rm -f $p
15534 }
15535 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15536
15537 test_155b() {
15538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15539
15540         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15541
15542         save_writethrough $p
15543
15544         set_cache read on
15545         set_cache writethrough off
15546         test_155_small_load
15547         restore_lustre_params < $p
15548         rm -f $p
15549 }
15550 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15551
15552 test_155c() {
15553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15554
15555         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15556
15557         save_writethrough $p
15558
15559         set_cache read off
15560         set_cache writethrough on
15561         test_155_small_load
15562         restore_lustre_params < $p
15563         rm -f $p
15564 }
15565 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15566
15567 test_155d() {
15568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15569
15570         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15571
15572         save_writethrough $p
15573
15574         set_cache read off
15575         set_cache writethrough off
15576         test_155_small_load
15577         restore_lustre_params < $p
15578         rm -f $p
15579 }
15580 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15581
15582 test_155e() {
15583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15584
15585         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15586
15587         save_writethrough $p
15588
15589         set_cache read on
15590         set_cache writethrough on
15591         test_155_big_load
15592         restore_lustre_params < $p
15593         rm -f $p
15594 }
15595 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15596
15597 test_155f() {
15598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15599
15600         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15601
15602         save_writethrough $p
15603
15604         set_cache read on
15605         set_cache writethrough off
15606         test_155_big_load
15607         restore_lustre_params < $p
15608         rm -f $p
15609 }
15610 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15611
15612 test_155g() {
15613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15614
15615         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15616
15617         save_writethrough $p
15618
15619         set_cache read off
15620         set_cache writethrough on
15621         test_155_big_load
15622         restore_lustre_params < $p
15623         rm -f $p
15624 }
15625 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15626
15627 test_155h() {
15628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15629
15630         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15631
15632         save_writethrough $p
15633
15634         set_cache read off
15635         set_cache writethrough off
15636         test_155_big_load
15637         restore_lustre_params < $p
15638         rm -f $p
15639 }
15640 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15641
15642 test_156() {
15643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15644         remote_ost_nodsh && skip "remote OST with nodsh"
15645         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15646                 skip "stats not implemented on old servers"
15647         [ "$ost1_FSTYPE" = "zfs" ] &&
15648                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15649
15650         local CPAGES=3
15651         local BEFORE
15652         local AFTER
15653         local file="$DIR/$tfile"
15654         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15655
15656         save_writethrough $p
15657         roc_hit_init
15658
15659         log "Turn on read and write cache"
15660         set_cache read on
15661         set_cache writethrough on
15662
15663         log "Write data and read it back."
15664         log "Read should be satisfied from the cache."
15665         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15666         BEFORE=$(roc_hit)
15667         cancel_lru_locks osc
15668         cat $file >/dev/null
15669         AFTER=$(roc_hit)
15670         if ! let "AFTER - BEFORE == CPAGES"; then
15671                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15672         else
15673                 log "cache hits: before: $BEFORE, after: $AFTER"
15674         fi
15675
15676         log "Read again; it should be satisfied from the cache."
15677         BEFORE=$AFTER
15678         cancel_lru_locks osc
15679         cat $file >/dev/null
15680         AFTER=$(roc_hit)
15681         if ! let "AFTER - BEFORE == CPAGES"; then
15682                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15683         else
15684                 log "cache hits:: before: $BEFORE, after: $AFTER"
15685         fi
15686
15687         log "Turn off the read cache and turn on the write cache"
15688         set_cache read off
15689         set_cache writethrough on
15690
15691         log "Read again; it should be satisfied from the cache."
15692         BEFORE=$(roc_hit)
15693         cancel_lru_locks osc
15694         cat $file >/dev/null
15695         AFTER=$(roc_hit)
15696         if ! let "AFTER - BEFORE == CPAGES"; then
15697                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15698         else
15699                 log "cache hits:: before: $BEFORE, after: $AFTER"
15700         fi
15701
15702         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15703                 # > 2.12.56 uses pagecache if cached
15704                 log "Read again; it should not be satisfied from the cache."
15705                 BEFORE=$AFTER
15706                 cancel_lru_locks osc
15707                 cat $file >/dev/null
15708                 AFTER=$(roc_hit)
15709                 if ! let "AFTER - BEFORE == 0"; then
15710                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15711                 else
15712                         log "cache hits:: before: $BEFORE, after: $AFTER"
15713                 fi
15714         fi
15715
15716         log "Write data and read it back."
15717         log "Read should be satisfied from the cache."
15718         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15719         BEFORE=$(roc_hit)
15720         cancel_lru_locks osc
15721         cat $file >/dev/null
15722         AFTER=$(roc_hit)
15723         if ! let "AFTER - BEFORE == CPAGES"; then
15724                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15725         else
15726                 log "cache hits:: before: $BEFORE, after: $AFTER"
15727         fi
15728
15729         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15730                 # > 2.12.56 uses pagecache if cached
15731                 log "Read again; it should not be satisfied from the cache."
15732                 BEFORE=$AFTER
15733                 cancel_lru_locks osc
15734                 cat $file >/dev/null
15735                 AFTER=$(roc_hit)
15736                 if ! let "AFTER - BEFORE == 0"; then
15737                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15738                 else
15739                         log "cache hits:: before: $BEFORE, after: $AFTER"
15740                 fi
15741         fi
15742
15743         log "Turn off read and write cache"
15744         set_cache read off
15745         set_cache writethrough off
15746
15747         log "Write data and read it back"
15748         log "It should not be satisfied from the cache."
15749         rm -f $file
15750         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15751         cancel_lru_locks osc
15752         BEFORE=$(roc_hit)
15753         cat $file >/dev/null
15754         AFTER=$(roc_hit)
15755         if ! let "AFTER - BEFORE == 0"; then
15756                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15757         else
15758                 log "cache hits:: before: $BEFORE, after: $AFTER"
15759         fi
15760
15761         log "Turn on the read cache and turn off the write cache"
15762         set_cache read on
15763         set_cache writethrough off
15764
15765         log "Write data and read it back"
15766         log "It should not be satisfied from the cache."
15767         rm -f $file
15768         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15769         BEFORE=$(roc_hit)
15770         cancel_lru_locks osc
15771         cat $file >/dev/null
15772         AFTER=$(roc_hit)
15773         if ! let "AFTER - BEFORE == 0"; then
15774                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15775         else
15776                 log "cache hits:: before: $BEFORE, after: $AFTER"
15777         fi
15778
15779         log "Read again; it should be satisfied from the cache."
15780         BEFORE=$(roc_hit)
15781         cancel_lru_locks osc
15782         cat $file >/dev/null
15783         AFTER=$(roc_hit)
15784         if ! let "AFTER - BEFORE == CPAGES"; then
15785                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15786         else
15787                 log "cache hits:: before: $BEFORE, after: $AFTER"
15788         fi
15789
15790         restore_lustre_params < $p
15791         rm -f $p $file
15792 }
15793 run_test 156 "Verification of tunables"
15794
15795 test_160a() {
15796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15797         remote_mds_nodsh && skip "remote MDS with nodsh"
15798         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15799                 skip "Need MDS version at least 2.2.0"
15800
15801         changelog_register || error "changelog_register failed"
15802         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15803         changelog_users $SINGLEMDS | grep -q $cl_user ||
15804                 error "User $cl_user not found in changelog_users"
15805
15806         mkdir_on_mdt0 $DIR/$tdir
15807
15808         # change something
15809         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15810         changelog_clear 0 || error "changelog_clear failed"
15811         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15812         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15813         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15814         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15815         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15816         rm $DIR/$tdir/pics/desktop.jpg
15817
15818         echo "verifying changelog mask"
15819         changelog_chmask "-MKDIR"
15820         changelog_chmask "-CLOSE"
15821
15822         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15823         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15824
15825         changelog_chmask "+MKDIR"
15826         changelog_chmask "+CLOSE"
15827
15828         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15829         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15830
15831         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15832         CLOSES=$(changelog_dump | grep -c "CLOSE")
15833         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15834         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15835
15836         # verify contents
15837         echo "verifying target fid"
15838         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15839         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15840         [ "$fidc" == "$fidf" ] ||
15841                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15842         echo "verifying parent fid"
15843         # The FID returned from the Changelog may be the directory shard on
15844         # a different MDT, and not the FID returned by path2fid on the parent.
15845         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15846         # since this is what will matter when recreating this file in the tree.
15847         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15848         local pathp=$($LFS fid2path $MOUNT "$fidp")
15849         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15850                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15851
15852         echo "getting records for $cl_user"
15853         changelog_users $SINGLEMDS
15854         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15855         local nclr=3
15856         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15857                 error "changelog_clear failed"
15858         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15859         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15860         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15861                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15862
15863         local min0_rec=$(changelog_users $SINGLEMDS |
15864                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15865         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15866                           awk '{ print $1; exit; }')
15867
15868         changelog_dump | tail -n 5
15869         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15870         [ $first_rec == $((min0_rec + 1)) ] ||
15871                 error "first index should be $min0_rec + 1 not $first_rec"
15872
15873         # LU-3446 changelog index reset on MDT restart
15874         local cur_rec1=$(changelog_users $SINGLEMDS |
15875                          awk '/^current.index:/ { print $NF }')
15876         changelog_clear 0 ||
15877                 error "clear all changelog records for $cl_user failed"
15878         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15879         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15880                 error "Fail to start $SINGLEMDS"
15881         local cur_rec2=$(changelog_users $SINGLEMDS |
15882                          awk '/^current.index:/ { print $NF }')
15883         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15884         [ $cur_rec1 == $cur_rec2 ] ||
15885                 error "current index should be $cur_rec1 not $cur_rec2"
15886
15887         echo "verifying users from this test are deregistered"
15888         changelog_deregister || error "changelog_deregister failed"
15889         changelog_users $SINGLEMDS | grep -q $cl_user &&
15890                 error "User '$cl_user' still in changelog_users"
15891
15892         # lctl get_param -n mdd.*.changelog_users
15893         # current_index: 144
15894         # ID    index (idle seconds)
15895         # cl3   144   (2) mask=<list>
15896         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15897                 # this is the normal case where all users were deregistered
15898                 # make sure no new records are added when no users are present
15899                 local last_rec1=$(changelog_users $SINGLEMDS |
15900                                   awk '/^current.index:/ { print $NF }')
15901                 touch $DIR/$tdir/chloe
15902                 local last_rec2=$(changelog_users $SINGLEMDS |
15903                                   awk '/^current.index:/ { print $NF }')
15904                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15905                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15906         else
15907                 # any changelog users must be leftovers from a previous test
15908                 changelog_users $SINGLEMDS
15909                 echo "other changelog users; can't verify off"
15910         fi
15911 }
15912 run_test 160a "changelog sanity"
15913
15914 test_160b() { # LU-3587
15915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15916         remote_mds_nodsh && skip "remote MDS with nodsh"
15917         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15918                 skip "Need MDS version at least 2.2.0"
15919
15920         changelog_register || error "changelog_register failed"
15921         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15922         changelog_users $SINGLEMDS | grep -q $cl_user ||
15923                 error "User '$cl_user' not found in changelog_users"
15924
15925         local longname1=$(str_repeat a 255)
15926         local longname2=$(str_repeat b 255)
15927
15928         cd $DIR
15929         echo "creating very long named file"
15930         touch $longname1 || error "create of '$longname1' failed"
15931         echo "renaming very long named file"
15932         mv $longname1 $longname2
15933
15934         changelog_dump | grep RENME | tail -n 5
15935         rm -f $longname2
15936 }
15937 run_test 160b "Verify that very long rename doesn't crash in changelog"
15938
15939 test_160c() {
15940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15941         remote_mds_nodsh && skip "remote MDS with nodsh"
15942
15943         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15944                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15945                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15946                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15947
15948         local rc=0
15949
15950         # Registration step
15951         changelog_register || error "changelog_register failed"
15952
15953         rm -rf $DIR/$tdir
15954         mkdir -p $DIR/$tdir
15955         $MCREATE $DIR/$tdir/foo_160c
15956         changelog_chmask "-TRUNC"
15957         $TRUNCATE $DIR/$tdir/foo_160c 200
15958         changelog_chmask "+TRUNC"
15959         $TRUNCATE $DIR/$tdir/foo_160c 199
15960         changelog_dump | tail -n 5
15961         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15962         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15963 }
15964 run_test 160c "verify that changelog log catch the truncate event"
15965
15966 test_160d() {
15967         remote_mds_nodsh && skip "remote MDS with nodsh"
15968         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15970         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15971                 skip "Need MDS version at least 2.7.60"
15972
15973         # Registration step
15974         changelog_register || error "changelog_register failed"
15975
15976         mkdir -p $DIR/$tdir/migrate_dir
15977         changelog_clear 0 || error "changelog_clear failed"
15978
15979         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15980         changelog_dump | tail -n 5
15981         local migrates=$(changelog_dump | grep -c "MIGRT")
15982         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15983 }
15984 run_test 160d "verify that changelog log catch the migrate event"
15985
15986 test_160e() {
15987         remote_mds_nodsh && skip "remote MDS with nodsh"
15988
15989         # Create a user
15990         changelog_register || error "changelog_register failed"
15991
15992         local MDT0=$(facet_svc $SINGLEMDS)
15993         local rc
15994
15995         # No user (expect fail)
15996         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
15997         rc=$?
15998         if [ $rc -eq 0 ]; then
15999                 error "Should fail without user"
16000         elif [ $rc -ne 4 ]; then
16001                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16002         fi
16003
16004         # Delete a future user (expect fail)
16005         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16006         rc=$?
16007         if [ $rc -eq 0 ]; then
16008                 error "Deleted non-existant user cl77"
16009         elif [ $rc -ne 2 ]; then
16010                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16011         fi
16012
16013         # Clear to a bad index (1 billion should be safe)
16014         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16015         rc=$?
16016
16017         if [ $rc -eq 0 ]; then
16018                 error "Successfully cleared to invalid CL index"
16019         elif [ $rc -ne 22 ]; then
16020                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16021         fi
16022 }
16023 run_test 160e "changelog negative testing (should return errors)"
16024
16025 test_160f() {
16026         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16027         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16028                 skip "Need MDS version at least 2.10.56"
16029
16030         local mdts=$(comma_list $(mdts_nodes))
16031
16032         # Create a user
16033         changelog_register || error "first changelog_register failed"
16034         changelog_register || error "second changelog_register failed"
16035         local cl_users
16036         declare -A cl_user1
16037         declare -A cl_user2
16038         local user_rec1
16039         local user_rec2
16040         local i
16041
16042         # generate some changelog records to accumulate on each MDT
16043         # use all_char because created files should be evenly distributed
16044         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16045                 error "test_mkdir $tdir failed"
16046         log "$(date +%s): creating first files"
16047         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16048                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16049                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16050         done
16051
16052         # check changelogs have been generated
16053         local start=$SECONDS
16054         local idle_time=$((MDSCOUNT * 5 + 5))
16055         local nbcl=$(changelog_dump | wc -l)
16056         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16057
16058         for param in "changelog_max_idle_time=$idle_time" \
16059                      "changelog_gc=1" \
16060                      "changelog_min_gc_interval=2" \
16061                      "changelog_min_free_cat_entries=3"; do
16062                 local MDT0=$(facet_svc $SINGLEMDS)
16063                 local var="${param%=*}"
16064                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16065
16066                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16067                 do_nodes $mdts $LCTL set_param mdd.*.$param
16068         done
16069
16070         # force cl_user2 to be idle (1st part), but also cancel the
16071         # cl_user1 records so that it is not evicted later in the test.
16072         local sleep1=$((idle_time / 2))
16073         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16074         sleep $sleep1
16075
16076         # simulate changelog catalog almost full
16077         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16078         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16079
16080         for i in $(seq $MDSCOUNT); do
16081                 cl_users=(${CL_USERS[mds$i]})
16082                 cl_user1[mds$i]="${cl_users[0]}"
16083                 cl_user2[mds$i]="${cl_users[1]}"
16084
16085                 [ -n "${cl_user1[mds$i]}" ] ||
16086                         error "mds$i: no user registered"
16087                 [ -n "${cl_user2[mds$i]}" ] ||
16088                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16089
16090                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16091                 [ -n "$user_rec1" ] ||
16092                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16093                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16094                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16095                 [ -n "$user_rec2" ] ||
16096                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16097                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16098                      "$user_rec1 + 2 == $user_rec2"
16099                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16100                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16101                               "$user_rec1 + 2, but is $user_rec2"
16102                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16103                 [ -n "$user_rec2" ] ||
16104                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16105                 [ $user_rec1 == $user_rec2 ] ||
16106                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16107                               "$user_rec1, but is $user_rec2"
16108         done
16109
16110         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16111         local sleep2=$((idle_time - (SECONDS - start) + 1))
16112         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16113         sleep $sleep2
16114
16115         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16116         # cl_user1 should be OK because it recently processed records.
16117         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16118         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16119                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16120                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16121         done
16122
16123         # ensure gc thread is done
16124         for i in $(mdts_nodes); do
16125                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16126                         error "$i: GC-thread not done"
16127         done
16128
16129         local first_rec
16130         for (( i = 1; i <= MDSCOUNT; i++ )); do
16131                 # check cl_user1 still registered
16132                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16133                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16134                 # check cl_user2 unregistered
16135                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16136                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16137
16138                 # check changelogs are present and starting at $user_rec1 + 1
16139                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16140                 [ -n "$user_rec1" ] ||
16141                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16142                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16143                             awk '{ print $1; exit; }')
16144
16145                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16146                 [ $((user_rec1 + 1)) == $first_rec ] ||
16147                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16148         done
16149 }
16150 run_test 160f "changelog garbage collect (timestamped users)"
16151
16152 test_160g() {
16153         remote_mds_nodsh && skip "remote MDS with nodsh"
16154         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16155                 skip "Need MDS version at least 2.14.55"
16156
16157         local mdts=$(comma_list $(mdts_nodes))
16158
16159         # Create a user
16160         changelog_register || error "first changelog_register failed"
16161         changelog_register || error "second changelog_register failed"
16162         local cl_users
16163         declare -A cl_user1
16164         declare -A cl_user2
16165         local user_rec1
16166         local user_rec2
16167         local i
16168
16169         # generate some changelog records to accumulate on each MDT
16170         # use all_char because created files should be evenly distributed
16171         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16172                 error "test_mkdir $tdir failed"
16173         for ((i = 0; i < MDSCOUNT; i++)); do
16174                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16175                         error "create $DIR/$tdir/d$i.1 failed"
16176         done
16177
16178         # check changelogs have been generated
16179         local nbcl=$(changelog_dump | wc -l)
16180         (( $nbcl > 0 )) || error "no changelogs found"
16181
16182         # reduce the max_idle_indexes value to make sure we exceed it
16183         for param in "changelog_max_idle_indexes=2" \
16184                      "changelog_gc=1" \
16185                      "changelog_min_gc_interval=2"; do
16186                 local MDT0=$(facet_svc $SINGLEMDS)
16187                 local var="${param%=*}"
16188                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16189
16190                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16191                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16192                         error "unable to set mdd.*.$param"
16193         done
16194
16195         local start=$SECONDS
16196         for i in $(seq $MDSCOUNT); do
16197                 cl_users=(${CL_USERS[mds$i]})
16198                 cl_user1[mds$i]="${cl_users[0]}"
16199                 cl_user2[mds$i]="${cl_users[1]}"
16200
16201                 [ -n "${cl_user1[mds$i]}" ] ||
16202                         error "mds$i: user1 is not registered"
16203                 [ -n "${cl_user2[mds$i]}" ] ||
16204                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16205
16206                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16207                 [ -n "$user_rec1" ] ||
16208                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16209                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16210                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16211                 [ -n "$user_rec2" ] ||
16212                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16213                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16214                      "$user_rec1 + 2 == $user_rec2"
16215                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16216                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16217                               "expected $user_rec1 + 2, but is $user_rec2"
16218                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16219                 [ -n "$user_rec2" ] ||
16220                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16221                 [ $user_rec1 == $user_rec2 ] ||
16222                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16223                               "expected $user_rec1, but is $user_rec2"
16224         done
16225
16226         # ensure we are past the previous changelog_min_gc_interval set above
16227         local sleep2=$((start + 2 - SECONDS))
16228         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16229         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16230         # cl_user1 should be OK because it recently processed records.
16231         for ((i = 0; i < MDSCOUNT; i++)); do
16232                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16233                         error "create $DIR/$tdir/d$i.3 failed"
16234         done
16235
16236         # ensure gc thread is done
16237         for i in $(mdts_nodes); do
16238                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16239                         error "$i: GC-thread not done"
16240         done
16241
16242         local first_rec
16243         for (( i = 1; i <= MDSCOUNT; i++ )); do
16244                 # check cl_user1 still registered
16245                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16246                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16247                 # check cl_user2 unregistered
16248                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16249                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16250
16251                 # check changelogs are present and starting at $user_rec1 + 1
16252                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16253                 [ -n "$user_rec1" ] ||
16254                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16255                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16256                             awk '{ print $1; exit; }')
16257
16258                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16259                 [ $((user_rec1 + 1)) == $first_rec ] ||
16260                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16261         done
16262 }
16263 run_test 160g "changelog garbage collect on idle records"
16264
16265 test_160h() {
16266         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16267         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16268                 skip "Need MDS version at least 2.10.56"
16269
16270         local mdts=$(comma_list $(mdts_nodes))
16271
16272         # Create a user
16273         changelog_register || error "first changelog_register failed"
16274         changelog_register || error "second changelog_register failed"
16275         local cl_users
16276         declare -A cl_user1
16277         declare -A cl_user2
16278         local user_rec1
16279         local user_rec2
16280         local i
16281
16282         # generate some changelog records to accumulate on each MDT
16283         # use all_char because created files should be evenly distributed
16284         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16285                 error "test_mkdir $tdir failed"
16286         for ((i = 0; i < MDSCOUNT; i++)); do
16287                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16288                         error "create $DIR/$tdir/d$i.1 failed"
16289         done
16290
16291         # check changelogs have been generated
16292         local nbcl=$(changelog_dump | wc -l)
16293         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16294
16295         for param in "changelog_max_idle_time=10" \
16296                      "changelog_gc=1" \
16297                      "changelog_min_gc_interval=2"; do
16298                 local MDT0=$(facet_svc $SINGLEMDS)
16299                 local var="${param%=*}"
16300                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16301
16302                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16303                 do_nodes $mdts $LCTL set_param mdd.*.$param
16304         done
16305
16306         # force cl_user2 to be idle (1st part)
16307         sleep 9
16308
16309         for i in $(seq $MDSCOUNT); do
16310                 cl_users=(${CL_USERS[mds$i]})
16311                 cl_user1[mds$i]="${cl_users[0]}"
16312                 cl_user2[mds$i]="${cl_users[1]}"
16313
16314                 [ -n "${cl_user1[mds$i]}" ] ||
16315                         error "mds$i: no user registered"
16316                 [ -n "${cl_user2[mds$i]}" ] ||
16317                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16318
16319                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16320                 [ -n "$user_rec1" ] ||
16321                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16322                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16323                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16324                 [ -n "$user_rec2" ] ||
16325                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16326                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16327                      "$user_rec1 + 2 == $user_rec2"
16328                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16329                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16330                               "$user_rec1 + 2, but is $user_rec2"
16331                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16332                 [ -n "$user_rec2" ] ||
16333                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16334                 [ $user_rec1 == $user_rec2 ] ||
16335                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16336                               "$user_rec1, but is $user_rec2"
16337         done
16338
16339         # force cl_user2 to be idle (2nd part) and to reach
16340         # changelog_max_idle_time
16341         sleep 2
16342
16343         # force each GC-thread start and block then
16344         # one per MDT/MDD, set fail_val accordingly
16345         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16346         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16347
16348         # generate more changelogs to trigger fail_loc
16349         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16350                 error "create $DIR/$tdir/${tfile}bis failed"
16351
16352         # stop MDT to stop GC-thread, should be done in back-ground as it will
16353         # block waiting for the thread to be released and exit
16354         declare -A stop_pids
16355         for i in $(seq $MDSCOUNT); do
16356                 stop mds$i &
16357                 stop_pids[mds$i]=$!
16358         done
16359
16360         for i in $(mdts_nodes); do
16361                 local facet
16362                 local nb=0
16363                 local facets=$(facets_up_on_host $i)
16364
16365                 for facet in ${facets//,/ }; do
16366                         if [[ $facet == mds* ]]; then
16367                                 nb=$((nb + 1))
16368                         fi
16369                 done
16370                 # ensure each MDS's gc threads are still present and all in "R"
16371                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16372                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16373                         error "$i: expected $nb GC-thread"
16374                 wait_update $i \
16375                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16376                         "R" 20 ||
16377                         error "$i: GC-thread not found in R-state"
16378                 # check umounts of each MDT on MDS have reached kthread_stop()
16379                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16380                         error "$i: expected $nb umount"
16381                 wait_update $i \
16382                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16383                         error "$i: umount not found in D-state"
16384         done
16385
16386         # release all GC-threads
16387         do_nodes $mdts $LCTL set_param fail_loc=0
16388
16389         # wait for MDT stop to complete
16390         for i in $(seq $MDSCOUNT); do
16391                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16392         done
16393
16394         # XXX
16395         # may try to check if any orphan changelog records are present
16396         # via ldiskfs/zfs and llog_reader...
16397
16398         # re-start/mount MDTs
16399         for i in $(seq $MDSCOUNT); do
16400                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16401                         error "Fail to start mds$i"
16402         done
16403
16404         local first_rec
16405         for i in $(seq $MDSCOUNT); do
16406                 # check cl_user1 still registered
16407                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16408                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16409                 # check cl_user2 unregistered
16410                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16411                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16412
16413                 # check changelogs are present and starting at $user_rec1 + 1
16414                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16415                 [ -n "$user_rec1" ] ||
16416                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16417                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16418                             awk '{ print $1; exit; }')
16419
16420                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16421                 [ $((user_rec1 + 1)) == $first_rec ] ||
16422                         error "mds$i: first index should be $user_rec1 + 1, " \
16423                               "but is $first_rec"
16424         done
16425 }
16426 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16427               "during mount"
16428
16429 test_160i() {
16430
16431         local mdts=$(comma_list $(mdts_nodes))
16432
16433         changelog_register || error "first changelog_register failed"
16434
16435         # generate some changelog records to accumulate on each MDT
16436         # use all_char because created files should be evenly distributed
16437         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16438                 error "test_mkdir $tdir failed"
16439         for ((i = 0; i < MDSCOUNT; i++)); do
16440                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16441                         error "create $DIR/$tdir/d$i.1 failed"
16442         done
16443
16444         # check changelogs have been generated
16445         local nbcl=$(changelog_dump | wc -l)
16446         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16447
16448         # simulate race between register and unregister
16449         # XXX as fail_loc is set per-MDS, with DNE configs the race
16450         # simulation will only occur for one MDT per MDS and for the
16451         # others the normal race scenario will take place
16452         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16453         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16454         do_nodes $mdts $LCTL set_param fail_val=1
16455
16456         # unregister 1st user
16457         changelog_deregister &
16458         local pid1=$!
16459         # wait some time for deregister work to reach race rdv
16460         sleep 2
16461         # register 2nd user
16462         changelog_register || error "2nd user register failed"
16463
16464         wait $pid1 || error "1st user deregister failed"
16465
16466         local i
16467         local last_rec
16468         declare -A LAST_REC
16469         for i in $(seq $MDSCOUNT); do
16470                 if changelog_users mds$i | grep "^cl"; then
16471                         # make sure new records are added with one user present
16472                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16473                                           awk '/^current.index:/ { print $NF }')
16474                 else
16475                         error "mds$i has no user registered"
16476                 fi
16477         done
16478
16479         # generate more changelog records to accumulate on each MDT
16480         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16481                 error "create $DIR/$tdir/${tfile}bis failed"
16482
16483         for i in $(seq $MDSCOUNT); do
16484                 last_rec=$(changelog_users $SINGLEMDS |
16485                            awk '/^current.index:/ { print $NF }')
16486                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16487                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16488                         error "changelogs are off on mds$i"
16489         done
16490 }
16491 run_test 160i "changelog user register/unregister race"
16492
16493 test_160j() {
16494         remote_mds_nodsh && skip "remote MDS with nodsh"
16495         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16496                 skip "Need MDS version at least 2.12.56"
16497
16498         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16499         stack_trap "umount $MOUNT2" EXIT
16500
16501         changelog_register || error "first changelog_register failed"
16502         stack_trap "changelog_deregister" EXIT
16503
16504         # generate some changelog
16505         # use all_char because created files should be evenly distributed
16506         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16507                 error "mkdir $tdir failed"
16508         for ((i = 0; i < MDSCOUNT; i++)); do
16509                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16510                         error "create $DIR/$tdir/d$i.1 failed"
16511         done
16512
16513         # open the changelog device
16514         exec 3>/dev/changelog-$FSNAME-MDT0000
16515         stack_trap "exec 3>&-" EXIT
16516         exec 4</dev/changelog-$FSNAME-MDT0000
16517         stack_trap "exec 4<&-" EXIT
16518
16519         # umount the first lustre mount
16520         umount $MOUNT
16521         stack_trap "mount_client $MOUNT" EXIT
16522
16523         # read changelog, which may or may not fail, but should not crash
16524         cat <&4 >/dev/null
16525
16526         # clear changelog
16527         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16528         changelog_users $SINGLEMDS | grep -q $cl_user ||
16529                 error "User $cl_user not found in changelog_users"
16530
16531         printf 'clear:'$cl_user':0' >&3
16532 }
16533 run_test 160j "client can be umounted while its chanangelog is being used"
16534
16535 test_160k() {
16536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16537         remote_mds_nodsh && skip "remote MDS with nodsh"
16538
16539         mkdir -p $DIR/$tdir/1/1
16540
16541         changelog_register || error "changelog_register failed"
16542         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16543
16544         changelog_users $SINGLEMDS | grep -q $cl_user ||
16545                 error "User '$cl_user' not found in changelog_users"
16546 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16547         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16548         rmdir $DIR/$tdir/1/1 & sleep 1
16549         mkdir $DIR/$tdir/2
16550         touch $DIR/$tdir/2/2
16551         rm -rf $DIR/$tdir/2
16552
16553         wait
16554         sleep 4
16555
16556         changelog_dump | grep rmdir || error "rmdir not recorded"
16557 }
16558 run_test 160k "Verify that changelog records are not lost"
16559
16560 # Verifies that a file passed as a parameter has recently had an operation
16561 # performed on it that has generated an MTIME changelog which contains the
16562 # correct parent FID. As files might reside on a different MDT from the
16563 # parent directory in DNE configurations, the FIDs are translated to paths
16564 # before being compared, which should be identical
16565 compare_mtime_changelog() {
16566         local file="${1}"
16567         local mdtidx
16568         local mtime
16569         local cl_fid
16570         local pdir
16571         local dir
16572
16573         mdtidx=$($LFS getstripe --mdt-index $file)
16574         mdtidx=$(printf "%04x" $mdtidx)
16575
16576         # Obtain the parent FID from the MTIME changelog
16577         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16578         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16579
16580         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16581         [ -z "$cl_fid" ] && error "parent FID not present"
16582
16583         # Verify that the path for the parent FID is the same as the path for
16584         # the test directory
16585         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16586
16587         dir=$(dirname $1)
16588
16589         [[ "${pdir%/}" == "$dir" ]] ||
16590                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16591 }
16592
16593 test_160l() {
16594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16595
16596         remote_mds_nodsh && skip "remote MDS with nodsh"
16597         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16598                 skip "Need MDS version at least 2.13.55"
16599
16600         local cl_user
16601
16602         changelog_register || error "changelog_register failed"
16603         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16604
16605         changelog_users $SINGLEMDS | grep -q $cl_user ||
16606                 error "User '$cl_user' not found in changelog_users"
16607
16608         # Clear some types so that MTIME changelogs are generated
16609         changelog_chmask "-CREAT"
16610         changelog_chmask "-CLOSE"
16611
16612         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16613
16614         # Test CL_MTIME during setattr
16615         touch $DIR/$tdir/$tfile
16616         compare_mtime_changelog $DIR/$tdir/$tfile
16617
16618         # Test CL_MTIME during close
16619         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16620         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16621 }
16622 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16623
16624 test_160m() {
16625         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16626         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16627                 skip "Need MDS version at least 2.14.51"
16628         local cl_users
16629         local cl_user1
16630         local cl_user2
16631         local pid1
16632
16633         # Create a user
16634         changelog_register || error "first changelog_register failed"
16635         changelog_register || error "second changelog_register failed"
16636
16637         cl_users=(${CL_USERS[mds1]})
16638         cl_user1="${cl_users[0]}"
16639         cl_user2="${cl_users[1]}"
16640         # generate some changelog records to accumulate on MDT0
16641         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16642         createmany -m $DIR/$tdir/$tfile 50 ||
16643                 error "create $DIR/$tdir/$tfile failed"
16644         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16645         rm -f $DIR/$tdir
16646
16647         # check changelogs have been generated
16648         local nbcl=$(changelog_dump | wc -l)
16649         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16650
16651 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16652         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16653
16654         __changelog_clear mds1 $cl_user1 +10
16655         __changelog_clear mds1 $cl_user2 0 &
16656         pid1=$!
16657         sleep 2
16658         __changelog_clear mds1 $cl_user1 0 ||
16659                 error "fail to cancel record for $cl_user1"
16660         wait $pid1
16661         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16662 }
16663 run_test 160m "Changelog clear race"
16664
16665 test_160n() {
16666         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16667         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16668                 skip "Need MDS version at least 2.14.51"
16669         local cl_users
16670         local cl_user1
16671         local cl_user2
16672         local pid1
16673         local first_rec
16674         local last_rec=0
16675
16676         # Create a user
16677         changelog_register || error "first changelog_register failed"
16678
16679         cl_users=(${CL_USERS[mds1]})
16680         cl_user1="${cl_users[0]}"
16681
16682         # generate some changelog records to accumulate on MDT0
16683         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16684         first_rec=$(changelog_users $SINGLEMDS |
16685                         awk '/^current.index:/ { print $NF }')
16686         while (( last_rec < (( first_rec + 65000)) )); do
16687                 createmany -m $DIR/$tdir/$tfile 10000 ||
16688                         error "create $DIR/$tdir/$tfile failed"
16689
16690                 for i in $(seq 0 10000); do
16691                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16692                                 > /dev/null
16693                 done
16694
16695                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16696                         error "unlinkmany failed unlink"
16697                 last_rec=$(changelog_users $SINGLEMDS |
16698                         awk '/^current.index:/ { print $NF }')
16699                 echo last record $last_rec
16700                 (( last_rec == 0 )) && error "no changelog found"
16701         done
16702
16703 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16704         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16705
16706         __changelog_clear mds1 $cl_user1 0 &
16707         pid1=$!
16708         sleep 2
16709         __changelog_clear mds1 $cl_user1 0 ||
16710                 error "fail to cancel record for $cl_user1"
16711         wait $pid1
16712         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16713 }
16714 run_test 160n "Changelog destroy race"
16715
16716 test_160o() {
16717         local mdt="$(facet_svc $SINGLEMDS)"
16718
16719         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16720         remote_mds_nodsh && skip "remote MDS with nodsh"
16721         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16722                 skip "Need MDS version at least 2.14.52"
16723
16724         changelog_register --user test_160o -m unlnk+close+open ||
16725                 error "changelog_register failed"
16726
16727         do_facet $SINGLEMDS $LCTL --device $mdt \
16728                                 changelog_register -u "Tt3_-#" &&
16729                 error "bad symbols in name should fail"
16730
16731         do_facet $SINGLEMDS $LCTL --device $mdt \
16732                                 changelog_register -u test_160o &&
16733                 error "the same name registration should fail"
16734
16735         do_facet $SINGLEMDS $LCTL --device $mdt \
16736                         changelog_register -u test_160toolongname &&
16737                 error "too long name registration should fail"
16738
16739         changelog_chmask "MARK+HSM"
16740         lctl get_param mdd.*.changelog*mask
16741         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16742         changelog_users $SINGLEMDS | grep -q $cl_user ||
16743                 error "User $cl_user not found in changelog_users"
16744         #verify username
16745         echo $cl_user | grep -q test_160o ||
16746                 error "User $cl_user has no specific name 'test160o'"
16747
16748         # change something
16749         changelog_clear 0 || error "changelog_clear failed"
16750         # generate some changelog records to accumulate on MDT0
16751         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16752         touch $DIR/$tdir/$tfile                 # open 1
16753
16754         OPENS=$(changelog_dump | grep -c "OPEN")
16755         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16756
16757         # must be no MKDIR it wasn't set as user mask
16758         MKDIR=$(changelog_dump | grep -c "MKDIR")
16759         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16760
16761         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16762                                 mdd.$mdt.changelog_current_mask -n)
16763         # register maskless user
16764         changelog_register || error "changelog_register failed"
16765         # effective mask should be not changed because it is not minimal
16766         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16767                                 mdd.$mdt.changelog_current_mask -n)
16768         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16769         # set server mask to minimal value
16770         changelog_chmask "MARK"
16771         # check effective mask again, should be treated as DEFMASK now
16772         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16773                                 mdd.$mdt.changelog_current_mask -n)
16774         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16775
16776         do_facet $SINGLEMDS $LCTL --device $mdt \
16777                                 changelog_deregister -u test_160o ||
16778                 error "cannot deregister by name"
16779 }
16780 run_test 160o "changelog user name and mask"
16781
16782 test_160p() {
16783         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16784         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16785                 skip "Need MDS version at least 2.14.51"
16786         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16787         local cl_users
16788         local cl_user1
16789         local entry_count
16790
16791         # Create a user
16792         changelog_register || error "first changelog_register failed"
16793
16794         cl_users=(${CL_USERS[mds1]})
16795         cl_user1="${cl_users[0]}"
16796
16797         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16798         createmany -m $DIR/$tdir/$tfile 50 ||
16799                 error "create $DIR/$tdir/$tfile failed"
16800         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16801         rm -rf $DIR/$tdir
16802
16803         # check changelogs have been generated
16804         entry_count=$(changelog_dump | wc -l)
16805         ((entry_count != 0)) || error "no changelog entries found"
16806
16807         # remove changelog_users and check that orphan entries are removed
16808         stop mds1
16809         local dev=$(mdsdevname 1)
16810         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
16811         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
16812         entry_count=$(changelog_dump | wc -l)
16813         ((entry_count == 0)) ||
16814                 error "found $entry_count changelog entries, expected none"
16815 }
16816 run_test 160p "Changelog orphan cleanup with no users"
16817
16818 test_160q() {
16819         local mdt="$(facet_svc $SINGLEMDS)"
16820         local clu
16821
16822         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16823         remote_mds_nodsh && skip "remote MDS with nodsh"
16824         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16825                 skip "Need MDS version at least 2.14.54"
16826
16827         # set server mask to minimal value like server init does
16828         changelog_chmask "MARK"
16829         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16830                 error "changelog_register failed"
16831         # check effective mask again, should be treated as DEFMASK now
16832         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16833                                 mdd.$mdt.changelog_current_mask -n)
16834         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
16835                 error "changelog_deregister failed"
16836         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16837 }
16838 run_test 160q "changelog effective mask is DEFMASK if not set"
16839
16840 test_160s() {
16841         remote_mds_nodsh && skip "remote MDS with nodsh"
16842         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
16843                 skip "Need MDS version at least 2.14.55"
16844
16845         local mdts=$(comma_list $(mdts_nodes))
16846
16847         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
16848         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
16849                                        fail_val=$((24 * 3600 * 10))
16850
16851         # Create a user which is 10 days old
16852         changelog_register || error "first changelog_register failed"
16853         local cl_users
16854         declare -A cl_user1
16855         local i
16856
16857         # generate some changelog records to accumulate on each MDT
16858         # use all_char because created files should be evenly distributed
16859         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16860                 error "test_mkdir $tdir failed"
16861         for ((i = 0; i < MDSCOUNT; i++)); do
16862                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16863                         error "create $DIR/$tdir/d$i.1 failed"
16864         done
16865
16866         # check changelogs have been generated
16867         local nbcl=$(changelog_dump | wc -l)
16868         (( nbcl > 0 )) || error "no changelogs found"
16869
16870         # reduce the max_idle_indexes value to make sure we exceed it
16871         for param in "changelog_max_idle_indexes=2097446912" \
16872                      "changelog_max_idle_time=2592000" \
16873                      "changelog_gc=1" \
16874                      "changelog_min_gc_interval=2"; do
16875                 local MDT0=$(facet_svc $SINGLEMDS)
16876                 local var="${param%=*}"
16877                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16878
16879                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16880                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16881                         error "unable to set mdd.*.$param"
16882         done
16883
16884         local start=$SECONDS
16885         for i in $(seq $MDSCOUNT); do
16886                 cl_users=(${CL_USERS[mds$i]})
16887                 cl_user1[mds$i]="${cl_users[0]}"
16888
16889                 [[ -n "${cl_user1[mds$i]}" ]] ||
16890                         error "mds$i: no user registered"
16891         done
16892
16893         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
16894         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
16895
16896         # ensure we are past the previous changelog_min_gc_interval set above
16897         local sleep2=$((start + 2 - SECONDS))
16898         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16899
16900         # Generate one more changelog to trigger GC
16901         for ((i = 0; i < MDSCOUNT; i++)); do
16902                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
16903                         error "create $DIR/$tdir/d$i.3 failed"
16904         done
16905
16906         # ensure gc thread is done
16907         for node in $(mdts_nodes); do
16908                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
16909                         error "$node: GC-thread not done"
16910         done
16911
16912         do_nodes $mdts $LCTL set_param fail_loc=0
16913
16914         for (( i = 1; i <= MDSCOUNT; i++ )); do
16915                 # check cl_user1 is purged
16916                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
16917                         error "mds$i: User ${cl_user1[mds$i]} is registered"
16918         done
16919         return 0
16920 }
16921 run_test 160s "changelog garbage collect on idle records * time"
16922
16923 test_161a() {
16924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16925
16926         test_mkdir -c1 $DIR/$tdir
16927         cp /etc/hosts $DIR/$tdir/$tfile
16928         test_mkdir -c1 $DIR/$tdir/foo1
16929         test_mkdir -c1 $DIR/$tdir/foo2
16930         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16931         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16932         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16933         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16934         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16935         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16936                 $LFS fid2path $DIR $FID
16937                 error "bad link ea"
16938         fi
16939         # middle
16940         rm $DIR/$tdir/foo2/zachary
16941         # last
16942         rm $DIR/$tdir/foo2/thor
16943         # first
16944         rm $DIR/$tdir/$tfile
16945         # rename
16946         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16947         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16948                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16949         rm $DIR/$tdir/foo2/maggie
16950
16951         # overflow the EA
16952         local longname=$tfile.avg_len_is_thirty_two_
16953         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16954                 error_noexit 'failed to unlink many hardlinks'" EXIT
16955         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16956                 error "failed to hardlink many files"
16957         links=$($LFS fid2path $DIR $FID | wc -l)
16958         echo -n "${links}/1000 links in link EA"
16959         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16960 }
16961 run_test 161a "link ea sanity"
16962
16963 test_161b() {
16964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16965         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16966
16967         local MDTIDX=1
16968         local remote_dir=$DIR/$tdir/remote_dir
16969
16970         mkdir -p $DIR/$tdir
16971         $LFS mkdir -i $MDTIDX $remote_dir ||
16972                 error "create remote directory failed"
16973
16974         cp /etc/hosts $remote_dir/$tfile
16975         mkdir -p $remote_dir/foo1
16976         mkdir -p $remote_dir/foo2
16977         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16978         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16979         ln $remote_dir/$tfile $remote_dir/foo1/luna
16980         ln $remote_dir/$tfile $remote_dir/foo2/thor
16981
16982         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16983                      tr -d ']')
16984         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16985                 $LFS fid2path $DIR $FID
16986                 error "bad link ea"
16987         fi
16988         # middle
16989         rm $remote_dir/foo2/zachary
16990         # last
16991         rm $remote_dir/foo2/thor
16992         # first
16993         rm $remote_dir/$tfile
16994         # rename
16995         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16996         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16997         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16998                 $LFS fid2path $DIR $FID
16999                 error "bad link rename"
17000         fi
17001         rm $remote_dir/foo2/maggie
17002
17003         # overflow the EA
17004         local longname=filename_avg_len_is_thirty_two_
17005         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17006                 error "failed to hardlink many files"
17007         links=$($LFS fid2path $DIR $FID | wc -l)
17008         echo -n "${links}/1000 links in link EA"
17009         [[ ${links} -gt 60 ]] ||
17010                 error "expected at least 60 links in link EA"
17011         unlinkmany $remote_dir/foo2/$longname 1000 ||
17012         error "failed to unlink many hardlinks"
17013 }
17014 run_test 161b "link ea sanity under remote directory"
17015
17016 test_161c() {
17017         remote_mds_nodsh && skip "remote MDS with nodsh"
17018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17019         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17020                 skip "Need MDS version at least 2.1.5"
17021
17022         # define CLF_RENAME_LAST 0x0001
17023         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17024         changelog_register || error "changelog_register failed"
17025
17026         rm -rf $DIR/$tdir
17027         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17028         touch $DIR/$tdir/foo_161c
17029         touch $DIR/$tdir/bar_161c
17030         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17031         changelog_dump | grep RENME | tail -n 5
17032         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17033         changelog_clear 0 || error "changelog_clear failed"
17034         if [ x$flags != "x0x1" ]; then
17035                 error "flag $flags is not 0x1"
17036         fi
17037
17038         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17039         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17040         touch $DIR/$tdir/foo_161c
17041         touch $DIR/$tdir/bar_161c
17042         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17043         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17044         changelog_dump | grep RENME | tail -n 5
17045         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17046         changelog_clear 0 || error "changelog_clear failed"
17047         if [ x$flags != "x0x0" ]; then
17048                 error "flag $flags is not 0x0"
17049         fi
17050         echo "rename overwrite a target having nlink > 1," \
17051                 "changelog record has flags of $flags"
17052
17053         # rename doesn't overwrite a target (changelog flag 0x0)
17054         touch $DIR/$tdir/foo_161c
17055         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17056         changelog_dump | grep RENME | tail -n 5
17057         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17058         changelog_clear 0 || error "changelog_clear failed"
17059         if [ x$flags != "x0x0" ]; then
17060                 error "flag $flags is not 0x0"
17061         fi
17062         echo "rename doesn't overwrite a target," \
17063                 "changelog record has flags of $flags"
17064
17065         # define CLF_UNLINK_LAST 0x0001
17066         # unlink a file having nlink = 1 (changelog flag 0x1)
17067         rm -f $DIR/$tdir/foo2_161c
17068         changelog_dump | grep UNLNK | tail -n 5
17069         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17070         changelog_clear 0 || error "changelog_clear failed"
17071         if [ x$flags != "x0x1" ]; then
17072                 error "flag $flags is not 0x1"
17073         fi
17074         echo "unlink a file having nlink = 1," \
17075                 "changelog record has flags of $flags"
17076
17077         # unlink a file having nlink > 1 (changelog flag 0x0)
17078         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17079         rm -f $DIR/$tdir/foobar_161c
17080         changelog_dump | grep UNLNK | tail -n 5
17081         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17082         changelog_clear 0 || error "changelog_clear failed"
17083         if [ x$flags != "x0x0" ]; then
17084                 error "flag $flags is not 0x0"
17085         fi
17086         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17087 }
17088 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17089
17090 test_161d() {
17091         remote_mds_nodsh && skip "remote MDS with nodsh"
17092         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17093
17094         local pid
17095         local fid
17096
17097         changelog_register || error "changelog_register failed"
17098
17099         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17100         # interfer with $MOUNT/.lustre/fid/ access
17101         mkdir $DIR/$tdir
17102         [[ $? -eq 0 ]] || error "mkdir failed"
17103
17104         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17105         $LCTL set_param fail_loc=0x8000140c
17106         # 5s pause
17107         $LCTL set_param fail_val=5
17108
17109         # create file
17110         echo foofoo > $DIR/$tdir/$tfile &
17111         pid=$!
17112
17113         # wait for create to be delayed
17114         sleep 2
17115
17116         ps -p $pid
17117         [[ $? -eq 0 ]] || error "create should be blocked"
17118
17119         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17120         stack_trap "rm -f $tempfile"
17121         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17122         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17123         # some delay may occur during ChangeLog publishing and file read just
17124         # above, that could allow file write to happen finally
17125         [[ -s $tempfile ]] && echo "file should be empty"
17126
17127         $LCTL set_param fail_loc=0
17128
17129         wait $pid
17130         [[ $? -eq 0 ]] || error "create failed"
17131 }
17132 run_test 161d "create with concurrent .lustre/fid access"
17133
17134 check_path() {
17135         local expected="$1"
17136         shift
17137         local fid="$2"
17138
17139         local path
17140         path=$($LFS fid2path "$@")
17141         local rc=$?
17142
17143         if [ $rc -ne 0 ]; then
17144                 error "path looked up of '$expected' failed: rc=$rc"
17145         elif [ "$path" != "$expected" ]; then
17146                 error "path looked up '$path' instead of '$expected'"
17147         else
17148                 echo "FID '$fid' resolves to path '$path' as expected"
17149         fi
17150 }
17151
17152 test_162a() { # was test_162
17153         test_mkdir -p -c1 $DIR/$tdir/d2
17154         touch $DIR/$tdir/d2/$tfile
17155         touch $DIR/$tdir/d2/x1
17156         touch $DIR/$tdir/d2/x2
17157         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17158         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17159         # regular file
17160         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17161         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17162
17163         # softlink
17164         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17165         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17166         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17167
17168         # softlink to wrong file
17169         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17170         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17171         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17172
17173         # hardlink
17174         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17175         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17176         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17177         # fid2path dir/fsname should both work
17178         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17179         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17180
17181         # hardlink count: check that there are 2 links
17182         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17183         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17184
17185         # hardlink indexing: remove the first link
17186         rm $DIR/$tdir/d2/p/q/r/hlink
17187         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17188 }
17189 run_test 162a "path lookup sanity"
17190
17191 test_162b() {
17192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17193         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17194
17195         mkdir $DIR/$tdir
17196         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17197                                 error "create striped dir failed"
17198
17199         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17200                                         tail -n 1 | awk '{print $2}')
17201         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17202
17203         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17204         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17205
17206         # regular file
17207         for ((i=0;i<5;i++)); do
17208                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17209                         error "get fid for f$i failed"
17210                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17211
17212                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17213                         error "get fid for d$i failed"
17214                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17215         done
17216
17217         return 0
17218 }
17219 run_test 162b "striped directory path lookup sanity"
17220
17221 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17222 test_162c() {
17223         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17224                 skip "Need MDS version at least 2.7.51"
17225
17226         local lpath=$tdir.local
17227         local rpath=$tdir.remote
17228
17229         test_mkdir $DIR/$lpath
17230         test_mkdir $DIR/$rpath
17231
17232         for ((i = 0; i <= 101; i++)); do
17233                 lpath="$lpath/$i"
17234                 mkdir $DIR/$lpath
17235                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17236                         error "get fid for local directory $DIR/$lpath failed"
17237                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17238
17239                 rpath="$rpath/$i"
17240                 test_mkdir $DIR/$rpath
17241                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17242                         error "get fid for remote directory $DIR/$rpath failed"
17243                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17244         done
17245
17246         return 0
17247 }
17248 run_test 162c "fid2path works with paths 100 or more directories deep"
17249
17250 oalr_event_count() {
17251         local event="${1}"
17252         local trace="${2}"
17253
17254         awk -v name="${FSNAME}-OST0000" \
17255             -v event="${event}" \
17256             '$1 == "TRACE" && $2 == event && $3 == name' \
17257             "${trace}" |
17258         wc -l
17259 }
17260
17261 oalr_expect_event_count() {
17262         local event="${1}"
17263         local trace="${2}"
17264         local expect="${3}"
17265         local count
17266
17267         count=$(oalr_event_count "${event}" "${trace}")
17268         if ((count == expect)); then
17269                 return 0
17270         fi
17271
17272         error_noexit "${event} event count was '${count}', expected ${expect}"
17273         cat "${trace}" >&2
17274         exit 1
17275 }
17276
17277 cleanup_165() {
17278         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17279         stop ost1
17280         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17281 }
17282
17283 setup_165() {
17284         sync # Flush previous IOs so we can count log entries.
17285         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17286         stack_trap cleanup_165 EXIT
17287 }
17288
17289 test_165a() {
17290         local trace="/tmp/${tfile}.trace"
17291         local rc
17292         local count
17293
17294         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17295                 skip "OFD access log unsupported"
17296
17297         setup_165
17298         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17299         sleep 5
17300
17301         do_facet ost1 ofd_access_log_reader --list
17302         stop ost1
17303
17304         do_facet ost1 killall -TERM ofd_access_log_reader
17305         wait
17306         rc=$?
17307
17308         if ((rc != 0)); then
17309                 error "ofd_access_log_reader exited with rc = '${rc}'"
17310         fi
17311
17312         # Parse trace file for discovery events:
17313         oalr_expect_event_count alr_log_add "${trace}" 1
17314         oalr_expect_event_count alr_log_eof "${trace}" 1
17315         oalr_expect_event_count alr_log_free "${trace}" 1
17316 }
17317 run_test 165a "ofd access log discovery"
17318
17319 test_165b() {
17320         local trace="/tmp/${tfile}.trace"
17321         local file="${DIR}/${tfile}"
17322         local pfid1
17323         local pfid2
17324         local -a entry
17325         local rc
17326         local count
17327         local size
17328         local flags
17329
17330         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17331                 skip "OFD access log unsupported"
17332
17333         setup_165
17334         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17335         sleep 5
17336
17337         do_facet ost1 ofd_access_log_reader --list
17338
17339         lfs setstripe -c 1 -i 0 "${file}"
17340         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17341                 error "cannot create '${file}'"
17342
17343         sleep 5
17344         do_facet ost1 killall -TERM ofd_access_log_reader
17345         wait
17346         rc=$?
17347
17348         if ((rc != 0)); then
17349                 error "ofd_access_log_reader exited with rc = '${rc}'"
17350         fi
17351
17352         oalr_expect_event_count alr_log_entry "${trace}" 1
17353
17354         pfid1=$($LFS path2fid "${file}")
17355
17356         # 1     2             3   4    5     6   7    8    9     10
17357         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17358         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17359
17360         echo "entry = '${entry[*]}'" >&2
17361
17362         pfid2=${entry[4]}
17363         if [[ "${pfid1}" != "${pfid2}" ]]; then
17364                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17365         fi
17366
17367         size=${entry[8]}
17368         if ((size != 1048576)); then
17369                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17370         fi
17371
17372         flags=${entry[10]}
17373         if [[ "${flags}" != "w" ]]; then
17374                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17375         fi
17376
17377         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17378         sleep 5
17379
17380         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17381                 error "cannot read '${file}'"
17382         sleep 5
17383
17384         do_facet ost1 killall -TERM ofd_access_log_reader
17385         wait
17386         rc=$?
17387
17388         if ((rc != 0)); then
17389                 error "ofd_access_log_reader exited with rc = '${rc}'"
17390         fi
17391
17392         oalr_expect_event_count alr_log_entry "${trace}" 1
17393
17394         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17395         echo "entry = '${entry[*]}'" >&2
17396
17397         pfid2=${entry[4]}
17398         if [[ "${pfid1}" != "${pfid2}" ]]; then
17399                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17400         fi
17401
17402         size=${entry[8]}
17403         if ((size != 524288)); then
17404                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17405         fi
17406
17407         flags=${entry[10]}
17408         if [[ "${flags}" != "r" ]]; then
17409                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17410         fi
17411 }
17412 run_test 165b "ofd access log entries are produced and consumed"
17413
17414 test_165c() {
17415         local trace="/tmp/${tfile}.trace"
17416         local file="${DIR}/${tdir}/${tfile}"
17417
17418         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17419                 skip "OFD access log unsupported"
17420
17421         test_mkdir "${DIR}/${tdir}"
17422
17423         setup_165
17424         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17425         sleep 5
17426
17427         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17428
17429         # 4096 / 64 = 64. Create twice as many entries.
17430         for ((i = 0; i < 128; i++)); do
17431                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17432                         error "cannot create file"
17433         done
17434
17435         sync
17436
17437         do_facet ost1 killall -TERM ofd_access_log_reader
17438         wait
17439         rc=$?
17440         if ((rc != 0)); then
17441                 error "ofd_access_log_reader exited with rc = '${rc}'"
17442         fi
17443
17444         unlinkmany  "${file}-%d" 128
17445 }
17446 run_test 165c "full ofd access logs do not block IOs"
17447
17448 oal_get_read_count() {
17449         local stats="$1"
17450
17451         # STATS lustre-OST0001 alr_read_count 1
17452
17453         do_facet ost1 cat "${stats}" |
17454         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17455              END { print count; }'
17456 }
17457
17458 oal_expect_read_count() {
17459         local stats="$1"
17460         local count
17461         local expect="$2"
17462
17463         # Ask ofd_access_log_reader to write stats.
17464         do_facet ost1 killall -USR1 ofd_access_log_reader
17465
17466         # Allow some time for things to happen.
17467         sleep 1
17468
17469         count=$(oal_get_read_count "${stats}")
17470         if ((count == expect)); then
17471                 return 0
17472         fi
17473
17474         error_noexit "bad read count, got ${count}, expected ${expect}"
17475         do_facet ost1 cat "${stats}" >&2
17476         exit 1
17477 }
17478
17479 test_165d() {
17480         local stats="/tmp/${tfile}.stats"
17481         local file="${DIR}/${tdir}/${tfile}"
17482         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17483
17484         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17485                 skip "OFD access log unsupported"
17486
17487         test_mkdir "${DIR}/${tdir}"
17488
17489         setup_165
17490         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17491         sleep 5
17492
17493         lfs setstripe -c 1 -i 0 "${file}"
17494
17495         do_facet ost1 lctl set_param "${param}=rw"
17496         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17497                 error "cannot create '${file}'"
17498         oal_expect_read_count "${stats}" 1
17499
17500         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17501                 error "cannot read '${file}'"
17502         oal_expect_read_count "${stats}" 2
17503
17504         do_facet ost1 lctl set_param "${param}=r"
17505         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17506                 error "cannot create '${file}'"
17507         oal_expect_read_count "${stats}" 2
17508
17509         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17510                 error "cannot read '${file}'"
17511         oal_expect_read_count "${stats}" 3
17512
17513         do_facet ost1 lctl set_param "${param}=w"
17514         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17515                 error "cannot create '${file}'"
17516         oal_expect_read_count "${stats}" 4
17517
17518         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17519                 error "cannot read '${file}'"
17520         oal_expect_read_count "${stats}" 4
17521
17522         do_facet ost1 lctl set_param "${param}=0"
17523         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17524                 error "cannot create '${file}'"
17525         oal_expect_read_count "${stats}" 4
17526
17527         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17528                 error "cannot read '${file}'"
17529         oal_expect_read_count "${stats}" 4
17530
17531         do_facet ost1 killall -TERM ofd_access_log_reader
17532         wait
17533         rc=$?
17534         if ((rc != 0)); then
17535                 error "ofd_access_log_reader exited with rc = '${rc}'"
17536         fi
17537 }
17538 run_test 165d "ofd_access_log mask works"
17539
17540 test_165e() {
17541         local stats="/tmp/${tfile}.stats"
17542         local file0="${DIR}/${tdir}-0/${tfile}"
17543         local file1="${DIR}/${tdir}-1/${tfile}"
17544
17545         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17546                 skip "OFD access log unsupported"
17547
17548         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17549
17550         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17551         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17552
17553         lfs setstripe -c 1 -i 0 "${file0}"
17554         lfs setstripe -c 1 -i 0 "${file1}"
17555
17556         setup_165
17557         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17558         sleep 5
17559
17560         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17561                 error "cannot create '${file0}'"
17562         sync
17563         oal_expect_read_count "${stats}" 0
17564
17565         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17566                 error "cannot create '${file1}'"
17567         sync
17568         oal_expect_read_count "${stats}" 1
17569
17570         do_facet ost1 killall -TERM ofd_access_log_reader
17571         wait
17572         rc=$?
17573         if ((rc != 0)); then
17574                 error "ofd_access_log_reader exited with rc = '${rc}'"
17575         fi
17576 }
17577 run_test 165e "ofd_access_log MDT index filter works"
17578
17579 test_165f() {
17580         local trace="/tmp/${tfile}.trace"
17581         local rc
17582         local count
17583
17584         setup_165
17585         do_facet ost1 timeout 60 ofd_access_log_reader \
17586                 --exit-on-close --debug=- --trace=- > "${trace}" &
17587         sleep 5
17588         stop ost1
17589
17590         wait
17591         rc=$?
17592
17593         if ((rc != 0)); then
17594                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17595                 cat "${trace}"
17596                 exit 1
17597         fi
17598 }
17599 run_test 165f "ofd_access_log_reader --exit-on-close works"
17600
17601 test_169() {
17602         # do directio so as not to populate the page cache
17603         log "creating a 10 Mb file"
17604         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17605                 error "multiop failed while creating a file"
17606         log "starting reads"
17607         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17608         log "truncating the file"
17609         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17610                 error "multiop failed while truncating the file"
17611         log "killing dd"
17612         kill %+ || true # reads might have finished
17613         echo "wait until dd is finished"
17614         wait
17615         log "removing the temporary file"
17616         rm -rf $DIR/$tfile || error "tmp file removal failed"
17617 }
17618 run_test 169 "parallel read and truncate should not deadlock"
17619
17620 test_170() {
17621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17622
17623         $LCTL clear     # bug 18514
17624         $LCTL debug_daemon start $TMP/${tfile}_log_good
17625         touch $DIR/$tfile
17626         $LCTL debug_daemon stop
17627         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17628                 error "sed failed to read log_good"
17629
17630         $LCTL debug_daemon start $TMP/${tfile}_log_good
17631         rm -rf $DIR/$tfile
17632         $LCTL debug_daemon stop
17633
17634         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17635                error "lctl df log_bad failed"
17636
17637         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17638         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17639
17640         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17641         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17642
17643         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17644                 error "bad_line good_line1 good_line2 are empty"
17645
17646         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17647         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17648         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17649
17650         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17651         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17652         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17653
17654         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17655                 error "bad_line_new good_line_new are empty"
17656
17657         local expected_good=$((good_line1 + good_line2*2))
17658
17659         rm -f $TMP/${tfile}*
17660         # LU-231, short malformed line may not be counted into bad lines
17661         if [ $bad_line -ne $bad_line_new ] &&
17662                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17663                 error "expected $bad_line bad lines, but got $bad_line_new"
17664                 return 1
17665         fi
17666
17667         if [ $expected_good -ne $good_line_new ]; then
17668                 error "expected $expected_good good lines, but got $good_line_new"
17669                 return 2
17670         fi
17671         true
17672 }
17673 run_test 170 "test lctl df to handle corrupted log ====================="
17674
17675 test_171() { # bug20592
17676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17677
17678         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17679         $LCTL set_param fail_loc=0x50e
17680         $LCTL set_param fail_val=3000
17681         multiop_bg_pause $DIR/$tfile O_s || true
17682         local MULTIPID=$!
17683         kill -USR1 $MULTIPID
17684         # cause log dump
17685         sleep 3
17686         wait $MULTIPID
17687         if dmesg | grep "recursive fault"; then
17688                 error "caught a recursive fault"
17689         fi
17690         $LCTL set_param fail_loc=0
17691         true
17692 }
17693 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17694
17695 # it would be good to share it with obdfilter-survey/iokit-libecho code
17696 setup_obdecho_osc () {
17697         local rc=0
17698         local ost_nid=$1
17699         local obdfilter_name=$2
17700         echo "Creating new osc for $obdfilter_name on $ost_nid"
17701         # make sure we can find loopback nid
17702         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17703
17704         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17705                            ${obdfilter_name}_osc_UUID || rc=2; }
17706         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17707                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17708         return $rc
17709 }
17710
17711 cleanup_obdecho_osc () {
17712         local obdfilter_name=$1
17713         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17714         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17715         return 0
17716 }
17717
17718 obdecho_test() {
17719         local OBD=$1
17720         local node=$2
17721         local pages=${3:-64}
17722         local rc=0
17723         local id
17724
17725         local count=10
17726         local obd_size=$(get_obd_size $node $OBD)
17727         local page_size=$(get_page_size $node)
17728         if [[ -n "$obd_size" ]]; then
17729                 local new_count=$((obd_size / (pages * page_size / 1024)))
17730                 [[ $new_count -ge $count ]] || count=$new_count
17731         fi
17732
17733         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17734         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17735                            rc=2; }
17736         if [ $rc -eq 0 ]; then
17737             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17738             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17739         fi
17740         echo "New object id is $id"
17741         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17742                            rc=4; }
17743         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17744                            "test_brw $count w v $pages $id" || rc=4; }
17745         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17746                            rc=4; }
17747         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17748                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17749         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17750                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17751         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17752         return $rc
17753 }
17754
17755 test_180a() {
17756         skip "obdecho on osc is no longer supported"
17757 }
17758 run_test 180a "test obdecho on osc"
17759
17760 test_180b() {
17761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17762         remote_ost_nodsh && skip "remote OST with nodsh"
17763
17764         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17765                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17766                 error "failed to load module obdecho"
17767
17768         local target=$(do_facet ost1 $LCTL dl |
17769                        awk '/obdfilter/ { print $4; exit; }')
17770
17771         if [ -n "$target" ]; then
17772                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17773         else
17774                 do_facet ost1 $LCTL dl
17775                 error "there is no obdfilter target on ost1"
17776         fi
17777 }
17778 run_test 180b "test obdecho directly on obdfilter"
17779
17780 test_180c() { # LU-2598
17781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17782         remote_ost_nodsh && skip "remote OST with nodsh"
17783         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17784                 skip "Need MDS version at least 2.4.0"
17785
17786         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17787                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17788                 error "failed to load module obdecho"
17789
17790         local target=$(do_facet ost1 $LCTL dl |
17791                        awk '/obdfilter/ { print $4; exit; }')
17792
17793         if [ -n "$target" ]; then
17794                 local pages=16384 # 64MB bulk I/O RPC size
17795
17796                 obdecho_test "$target" ost1 "$pages" ||
17797                         error "obdecho_test with pages=$pages failed with $?"
17798         else
17799                 do_facet ost1 $LCTL dl
17800                 error "there is no obdfilter target on ost1"
17801         fi
17802 }
17803 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17804
17805 test_181() { # bug 22177
17806         test_mkdir $DIR/$tdir
17807         # create enough files to index the directory
17808         createmany -o $DIR/$tdir/foobar 4000
17809         # print attributes for debug purpose
17810         lsattr -d .
17811         # open dir
17812         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17813         MULTIPID=$!
17814         # remove the files & current working dir
17815         unlinkmany $DIR/$tdir/foobar 4000
17816         rmdir $DIR/$tdir
17817         kill -USR1 $MULTIPID
17818         wait $MULTIPID
17819         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17820         return 0
17821 }
17822 run_test 181 "Test open-unlinked dir ========================"
17823
17824 test_182a() {
17825         local fcount=1000
17826         local tcount=10
17827
17828         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17829
17830         $LCTL set_param mdc.*.rpc_stats=clear
17831
17832         for (( i = 0; i < $tcount; i++ )) ; do
17833                 mkdir $DIR/$tdir/$i
17834         done
17835
17836         for (( i = 0; i < $tcount; i++ )) ; do
17837                 createmany -o $DIR/$tdir/$i/f- $fcount &
17838         done
17839         wait
17840
17841         for (( i = 0; i < $tcount; i++ )) ; do
17842                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17843         done
17844         wait
17845
17846         $LCTL get_param mdc.*.rpc_stats
17847
17848         rm -rf $DIR/$tdir
17849 }
17850 run_test 182a "Test parallel modify metadata operations from mdc"
17851
17852 test_182b() {
17853         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
17854         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
17855         local dcount=1000
17856         local tcount=10
17857         local stime
17858         local etime
17859         local delta
17860
17861         do_facet mds1 $LCTL list_param \
17862                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
17863                 skip "MDS lacks parallel RPC handling"
17864
17865         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17866
17867         rpc_count=$(do_facet mds1 $LCTL get_param -n \
17868                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
17869
17870         stime=$(date +%s)
17871         createmany -i 0 -d $DIR/$tdir/t- $tcount
17872
17873         for (( i = 0; i < $tcount; i++ )) ; do
17874                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
17875         done
17876         wait
17877         etime=$(date +%s)
17878         delta=$((etime - stime))
17879         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
17880
17881         stime=$(date +%s)
17882         for (( i = 0; i < $tcount; i++ )) ; do
17883                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
17884         done
17885         wait
17886         etime=$(date +%s)
17887         delta=$((etime - stime))
17888         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
17889
17890         rm -rf $DIR/$tdir
17891
17892         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17893
17894         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
17895
17896         stime=$(date +%s)
17897         createmany -i 0 -d $DIR/$tdir/t- $tcount
17898
17899         for (( i = 0; i < $tcount; i++ )) ; do
17900                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
17901         done
17902         wait
17903         etime=$(date +%s)
17904         delta=$((etime - stime))
17905         echo "Time for file creation $delta sec for 1 RPC sent at a time"
17906
17907         stime=$(date +%s)
17908         for (( i = 0; i < $tcount; i++ )) ; do
17909                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
17910         done
17911         wait
17912         etime=$(date +%s)
17913         delta=$((etime - stime))
17914         echo "Time for file removal $delta sec for 1 RPC sent at a time"
17915
17916         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
17917 }
17918 run_test 182b "Test parallel modify metadata operations from osp"
17919
17920 test_183() { # LU-2275
17921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17922         remote_mds_nodsh && skip "remote MDS with nodsh"
17923         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17924                 skip "Need MDS version at least 2.3.56"
17925
17926         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17927         echo aaa > $DIR/$tdir/$tfile
17928
17929 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17930         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17931
17932         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17933         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17934
17935         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17936
17937         # Flush negative dentry cache
17938         touch $DIR/$tdir/$tfile
17939
17940         # We are not checking for any leaked references here, they'll
17941         # become evident next time we do cleanup with module unload.
17942         rm -rf $DIR/$tdir
17943 }
17944 run_test 183 "No crash or request leak in case of strange dispositions ========"
17945
17946 # test suite 184 is for LU-2016, LU-2017
17947 test_184a() {
17948         check_swap_layouts_support
17949
17950         dir0=$DIR/$tdir/$testnum
17951         test_mkdir -p -c1 $dir0
17952         ref1=/etc/passwd
17953         ref2=/etc/group
17954         file1=$dir0/f1
17955         file2=$dir0/f2
17956         $LFS setstripe -c1 $file1
17957         cp $ref1 $file1
17958         $LFS setstripe -c2 $file2
17959         cp $ref2 $file2
17960         gen1=$($LFS getstripe -g $file1)
17961         gen2=$($LFS getstripe -g $file2)
17962
17963         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17964         gen=$($LFS getstripe -g $file1)
17965         [[ $gen1 != $gen ]] ||
17966                 error "Layout generation on $file1 does not change"
17967         gen=$($LFS getstripe -g $file2)
17968         [[ $gen2 != $gen ]] ||
17969                 error "Layout generation on $file2 does not change"
17970
17971         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17972         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17973
17974         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17975 }
17976 run_test 184a "Basic layout swap"
17977
17978 test_184b() {
17979         check_swap_layouts_support
17980
17981         dir0=$DIR/$tdir/$testnum
17982         mkdir -p $dir0 || error "creating dir $dir0"
17983         file1=$dir0/f1
17984         file2=$dir0/f2
17985         file3=$dir0/f3
17986         dir1=$dir0/d1
17987         dir2=$dir0/d2
17988         mkdir $dir1 $dir2
17989         $LFS setstripe -c1 $file1
17990         $LFS setstripe -c2 $file2
17991         $LFS setstripe -c1 $file3
17992         chown $RUNAS_ID $file3
17993         gen1=$($LFS getstripe -g $file1)
17994         gen2=$($LFS getstripe -g $file2)
17995
17996         $LFS swap_layouts $dir1 $dir2 &&
17997                 error "swap of directories layouts should fail"
17998         $LFS swap_layouts $dir1 $file1 &&
17999                 error "swap of directory and file layouts should fail"
18000         $RUNAS $LFS swap_layouts $file1 $file2 &&
18001                 error "swap of file we cannot write should fail"
18002         $LFS swap_layouts $file1 $file3 &&
18003                 error "swap of file with different owner should fail"
18004         /bin/true # to clear error code
18005 }
18006 run_test 184b "Forbidden layout swap (will generate errors)"
18007
18008 test_184c() {
18009         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18010         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18011         check_swap_layouts_support
18012         check_swap_layout_no_dom $DIR
18013
18014         local dir0=$DIR/$tdir/$testnum
18015         mkdir -p $dir0 || error "creating dir $dir0"
18016
18017         local ref1=$dir0/ref1
18018         local ref2=$dir0/ref2
18019         local file1=$dir0/file1
18020         local file2=$dir0/file2
18021         # create a file large enough for the concurrent test
18022         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18023         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18024         echo "ref file size: ref1($(stat -c %s $ref1))," \
18025              "ref2($(stat -c %s $ref2))"
18026
18027         cp $ref2 $file2
18028         dd if=$ref1 of=$file1 bs=16k &
18029         local DD_PID=$!
18030
18031         # Make sure dd starts to copy file, but wait at most 5 seconds
18032         local loops=0
18033         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18034
18035         $LFS swap_layouts $file1 $file2
18036         local rc=$?
18037         wait $DD_PID
18038         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18039         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18040
18041         # how many bytes copied before swapping layout
18042         local copied=$(stat -c %s $file2)
18043         local remaining=$(stat -c %s $ref1)
18044         remaining=$((remaining - copied))
18045         echo "Copied $copied bytes before swapping layout..."
18046
18047         cmp -n $copied $file1 $ref2 | grep differ &&
18048                 error "Content mismatch [0, $copied) of ref2 and file1"
18049         cmp -n $copied $file2 $ref1 ||
18050                 error "Content mismatch [0, $copied) of ref1 and file2"
18051         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18052                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18053
18054         # clean up
18055         rm -f $ref1 $ref2 $file1 $file2
18056 }
18057 run_test 184c "Concurrent write and layout swap"
18058
18059 test_184d() {
18060         check_swap_layouts_support
18061         check_swap_layout_no_dom $DIR
18062         [ -z "$(which getfattr 2>/dev/null)" ] &&
18063                 skip_env "no getfattr command"
18064
18065         local file1=$DIR/$tdir/$tfile-1
18066         local file2=$DIR/$tdir/$tfile-2
18067         local file3=$DIR/$tdir/$tfile-3
18068         local lovea1
18069         local lovea2
18070
18071         mkdir -p $DIR/$tdir
18072         touch $file1 || error "create $file1 failed"
18073         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18074                 error "create $file2 failed"
18075         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18076                 error "create $file3 failed"
18077         lovea1=$(get_layout_param $file1)
18078
18079         $LFS swap_layouts $file2 $file3 ||
18080                 error "swap $file2 $file3 layouts failed"
18081         $LFS swap_layouts $file1 $file2 ||
18082                 error "swap $file1 $file2 layouts failed"
18083
18084         lovea2=$(get_layout_param $file2)
18085         echo "$lovea1"
18086         echo "$lovea2"
18087         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18088
18089         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18090         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18091 }
18092 run_test 184d "allow stripeless layouts swap"
18093
18094 test_184e() {
18095         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18096                 skip "Need MDS version at least 2.6.94"
18097         check_swap_layouts_support
18098         check_swap_layout_no_dom $DIR
18099         [ -z "$(which getfattr 2>/dev/null)" ] &&
18100                 skip_env "no getfattr command"
18101
18102         local file1=$DIR/$tdir/$tfile-1
18103         local file2=$DIR/$tdir/$tfile-2
18104         local file3=$DIR/$tdir/$tfile-3
18105         local lovea
18106
18107         mkdir -p $DIR/$tdir
18108         touch $file1 || error "create $file1 failed"
18109         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18110                 error "create $file2 failed"
18111         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18112                 error "create $file3 failed"
18113
18114         $LFS swap_layouts $file1 $file2 ||
18115                 error "swap $file1 $file2 layouts failed"
18116
18117         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18118         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18119
18120         echo 123 > $file1 || error "Should be able to write into $file1"
18121
18122         $LFS swap_layouts $file1 $file3 ||
18123                 error "swap $file1 $file3 layouts failed"
18124
18125         echo 123 > $file1 || error "Should be able to write into $file1"
18126
18127         rm -rf $file1 $file2 $file3
18128 }
18129 run_test 184e "Recreate layout after stripeless layout swaps"
18130
18131 test_184f() {
18132         # Create a file with name longer than sizeof(struct stat) ==
18133         # 144 to see if we can get chars from the file name to appear
18134         # in the returned striping. Note that 'f' == 0x66.
18135         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18136
18137         mkdir -p $DIR/$tdir
18138         mcreate $DIR/$tdir/$file
18139         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18140                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18141         fi
18142 }
18143 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18144
18145 test_185() { # LU-2441
18146         # LU-3553 - no volatile file support in old servers
18147         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18148                 skip "Need MDS version at least 2.3.60"
18149
18150         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18151         touch $DIR/$tdir/spoo
18152         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18153         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18154                 error "cannot create/write a volatile file"
18155         [ "$FILESET" == "" ] &&
18156         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18157                 error "FID is still valid after close"
18158
18159         multiop_bg_pause $DIR/$tdir vVw4096_c
18160         local multi_pid=$!
18161
18162         local OLD_IFS=$IFS
18163         IFS=":"
18164         local fidv=($fid)
18165         IFS=$OLD_IFS
18166         # assume that the next FID for this client is sequential, since stdout
18167         # is unfortunately eaten by multiop_bg_pause
18168         local n=$((${fidv[1]} + 1))
18169         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18170         if [ "$FILESET" == "" ]; then
18171                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18172                         error "FID is missing before close"
18173         fi
18174         kill -USR1 $multi_pid
18175         # 1 second delay, so if mtime change we will see it
18176         sleep 1
18177         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18178         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18179 }
18180 run_test 185 "Volatile file support"
18181
18182 function create_check_volatile() {
18183         local idx=$1
18184         local tgt
18185
18186         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18187         local PID=$!
18188         sleep 1
18189         local FID=$(cat /tmp/${tfile}.fid)
18190         [ "$FID" == "" ] && error "can't get FID for volatile"
18191         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18192         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18193         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18194         kill -USR1 $PID
18195         wait
18196         sleep 1
18197         cancel_lru_locks mdc # flush opencache
18198         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18199         return 0
18200 }
18201
18202 test_185a(){
18203         # LU-12516 - volatile creation via .lustre
18204         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18205                 skip "Need MDS version at least 2.3.55"
18206
18207         create_check_volatile 0
18208         [ $MDSCOUNT -lt 2 ] && return 0
18209
18210         # DNE case
18211         create_check_volatile 1
18212
18213         return 0
18214 }
18215 run_test 185a "Volatile file creation in .lustre/fid/"
18216
18217 test_187a() {
18218         remote_mds_nodsh && skip "remote MDS with nodsh"
18219         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18220                 skip "Need MDS version at least 2.3.0"
18221
18222         local dir0=$DIR/$tdir/$testnum
18223         mkdir -p $dir0 || error "creating dir $dir0"
18224
18225         local file=$dir0/file1
18226         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18227         local dv1=$($LFS data_version $file)
18228         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18229         local dv2=$($LFS data_version $file)
18230         [[ $dv1 != $dv2 ]] ||
18231                 error "data version did not change on write $dv1 == $dv2"
18232
18233         # clean up
18234         rm -f $file1
18235 }
18236 run_test 187a "Test data version change"
18237
18238 test_187b() {
18239         remote_mds_nodsh && skip "remote MDS with nodsh"
18240         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18241                 skip "Need MDS version at least 2.3.0"
18242
18243         local dir0=$DIR/$tdir/$testnum
18244         mkdir -p $dir0 || error "creating dir $dir0"
18245
18246         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18247         [[ ${DV[0]} != ${DV[1]} ]] ||
18248                 error "data version did not change on write"\
18249                       " ${DV[0]} == ${DV[1]}"
18250
18251         # clean up
18252         rm -f $file1
18253 }
18254 run_test 187b "Test data version change on volatile file"
18255
18256 test_200() {
18257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18258         remote_mgs_nodsh && skip "remote MGS with nodsh"
18259         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18260
18261         local POOL=${POOL:-cea1}
18262         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18263         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18264         # Pool OST targets
18265         local first_ost=0
18266         local last_ost=$(($OSTCOUNT - 1))
18267         local ost_step=2
18268         local ost_list=$(seq $first_ost $ost_step $last_ost)
18269         local ost_range="$first_ost $last_ost $ost_step"
18270         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18271         local file_dir=$POOL_ROOT/file_tst
18272         local subdir=$test_path/subdir
18273         local rc=0
18274
18275         while : ; do
18276                 # former test_200a test_200b
18277                 pool_add $POOL                          || { rc=$? ; break; }
18278                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18279                 # former test_200c test_200d
18280                 mkdir -p $test_path
18281                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18282                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18283                 mkdir -p $subdir
18284                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18285                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18286                                                         || { rc=$? ; break; }
18287                 # former test_200e test_200f
18288                 local files=$((OSTCOUNT*3))
18289                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18290                                                         || { rc=$? ; break; }
18291                 pool_create_files $POOL $file_dir $files "$ost_list" \
18292                                                         || { rc=$? ; break; }
18293                 # former test_200g test_200h
18294                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18295                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18296
18297                 # former test_201a test_201b test_201c
18298                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18299
18300                 local f=$test_path/$tfile
18301                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18302                 pool_remove $POOL $f                    || { rc=$? ; break; }
18303                 break
18304         done
18305
18306         destroy_test_pools
18307
18308         return $rc
18309 }
18310 run_test 200 "OST pools"
18311
18312 # usage: default_attr <count | size | offset>
18313 default_attr() {
18314         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18315 }
18316
18317 # usage: check_default_stripe_attr
18318 check_default_stripe_attr() {
18319         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18320         case $1 in
18321         --stripe-count|-c)
18322                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18323         --stripe-size|-S)
18324                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18325         --stripe-index|-i)
18326                 EXPECTED=-1;;
18327         *)
18328                 error "unknown getstripe attr '$1'"
18329         esac
18330
18331         [ $ACTUAL == $EXPECTED ] ||
18332                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18333 }
18334
18335 test_204a() {
18336         test_mkdir $DIR/$tdir
18337         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18338
18339         check_default_stripe_attr --stripe-count
18340         check_default_stripe_attr --stripe-size
18341         check_default_stripe_attr --stripe-index
18342 }
18343 run_test 204a "Print default stripe attributes"
18344
18345 test_204b() {
18346         test_mkdir $DIR/$tdir
18347         $LFS setstripe --stripe-count 1 $DIR/$tdir
18348
18349         check_default_stripe_attr --stripe-size
18350         check_default_stripe_attr --stripe-index
18351 }
18352 run_test 204b "Print default stripe size and offset"
18353
18354 test_204c() {
18355         test_mkdir $DIR/$tdir
18356         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18357
18358         check_default_stripe_attr --stripe-count
18359         check_default_stripe_attr --stripe-index
18360 }
18361 run_test 204c "Print default stripe count and offset"
18362
18363 test_204d() {
18364         test_mkdir $DIR/$tdir
18365         $LFS setstripe --stripe-index 0 $DIR/$tdir
18366
18367         check_default_stripe_attr --stripe-count
18368         check_default_stripe_attr --stripe-size
18369 }
18370 run_test 204d "Print default stripe count and size"
18371
18372 test_204e() {
18373         test_mkdir $DIR/$tdir
18374         $LFS setstripe -d $DIR/$tdir
18375
18376         check_default_stripe_attr --stripe-count --raw
18377         check_default_stripe_attr --stripe-size --raw
18378         check_default_stripe_attr --stripe-index --raw
18379 }
18380 run_test 204e "Print raw stripe attributes"
18381
18382 test_204f() {
18383         test_mkdir $DIR/$tdir
18384         $LFS setstripe --stripe-count 1 $DIR/$tdir
18385
18386         check_default_stripe_attr --stripe-size --raw
18387         check_default_stripe_attr --stripe-index --raw
18388 }
18389 run_test 204f "Print raw stripe size and offset"
18390
18391 test_204g() {
18392         test_mkdir $DIR/$tdir
18393         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18394
18395         check_default_stripe_attr --stripe-count --raw
18396         check_default_stripe_attr --stripe-index --raw
18397 }
18398 run_test 204g "Print raw stripe count and offset"
18399
18400 test_204h() {
18401         test_mkdir $DIR/$tdir
18402         $LFS setstripe --stripe-index 0 $DIR/$tdir
18403
18404         check_default_stripe_attr --stripe-count --raw
18405         check_default_stripe_attr --stripe-size --raw
18406 }
18407 run_test 204h "Print raw stripe count and size"
18408
18409 # Figure out which job scheduler is being used, if any,
18410 # or use a fake one
18411 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18412         JOBENV=SLURM_JOB_ID
18413 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18414         JOBENV=LSB_JOBID
18415 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18416         JOBENV=PBS_JOBID
18417 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18418         JOBENV=LOADL_STEP_ID
18419 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18420         JOBENV=JOB_ID
18421 else
18422         $LCTL list_param jobid_name > /dev/null 2>&1
18423         if [ $? -eq 0 ]; then
18424                 JOBENV=nodelocal
18425         else
18426                 JOBENV=FAKE_JOBID
18427         fi
18428 fi
18429 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18430
18431 verify_jobstats() {
18432         local cmd=($1)
18433         shift
18434         local facets="$@"
18435
18436 # we don't really need to clear the stats for this test to work, since each
18437 # command has a unique jobid, but it makes debugging easier if needed.
18438 #       for facet in $facets; do
18439 #               local dev=$(convert_facet2label $facet)
18440 #               # clear old jobstats
18441 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18442 #       done
18443
18444         # use a new JobID for each test, or we might see an old one
18445         [ "$JOBENV" = "FAKE_JOBID" ] &&
18446                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18447
18448         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18449
18450         [ "$JOBENV" = "nodelocal" ] && {
18451                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18452                 $LCTL set_param jobid_name=$FAKE_JOBID
18453                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18454         }
18455
18456         log "Test: ${cmd[*]}"
18457         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18458
18459         if [ $JOBENV = "FAKE_JOBID" ]; then
18460                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18461         else
18462                 ${cmd[*]}
18463         fi
18464
18465         # all files are created on OST0000
18466         for facet in $facets; do
18467                 local stats="*.$(convert_facet2label $facet).job_stats"
18468
18469                 # strip out libtool wrappers for in-tree executables
18470                 if (( $(do_facet $facet lctl get_param $stats |
18471                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18472                         do_facet $facet lctl get_param $stats
18473                         error "No jobstats for $JOBVAL found on $facet::$stats"
18474                 fi
18475         done
18476 }
18477
18478 jobstats_set() {
18479         local new_jobenv=$1
18480
18481         set_persistent_param_and_check client "jobid_var" \
18482                 "$FSNAME.sys.jobid_var" $new_jobenv
18483 }
18484
18485 test_205a() { # Job stats
18486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18487         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18488                 skip "Need MDS version with at least 2.7.1"
18489         remote_mgs_nodsh && skip "remote MGS with nodsh"
18490         remote_mds_nodsh && skip "remote MDS with nodsh"
18491         remote_ost_nodsh && skip "remote OST with nodsh"
18492         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18493                 skip "Server doesn't support jobstats"
18494         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18495
18496         local old_jobenv=$($LCTL get_param -n jobid_var)
18497         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18498
18499         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18500                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18501         else
18502                 stack_trap "do_facet mgs $PERM_CMD \
18503                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18504         fi
18505         changelog_register
18506
18507         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18508                                 mdt.*.job_cleanup_interval | head -n 1)
18509         local new_interval=5
18510         do_facet $SINGLEMDS \
18511                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18512         stack_trap "do_facet $SINGLEMDS \
18513                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18514         local start=$SECONDS
18515
18516         local cmd
18517         # mkdir
18518         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18519         verify_jobstats "$cmd" "$SINGLEMDS"
18520         # rmdir
18521         cmd="rmdir $DIR/$tdir"
18522         verify_jobstats "$cmd" "$SINGLEMDS"
18523         # mkdir on secondary MDT
18524         if [ $MDSCOUNT -gt 1 ]; then
18525                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18526                 verify_jobstats "$cmd" "mds2"
18527         fi
18528         # mknod
18529         cmd="mknod $DIR/$tfile c 1 3"
18530         verify_jobstats "$cmd" "$SINGLEMDS"
18531         # unlink
18532         cmd="rm -f $DIR/$tfile"
18533         verify_jobstats "$cmd" "$SINGLEMDS"
18534         # create all files on OST0000 so verify_jobstats can find OST stats
18535         # open & close
18536         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18537         verify_jobstats "$cmd" "$SINGLEMDS"
18538         # setattr
18539         cmd="touch $DIR/$tfile"
18540         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18541         # write
18542         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18543         verify_jobstats "$cmd" "ost1"
18544         # read
18545         cancel_lru_locks osc
18546         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18547         verify_jobstats "$cmd" "ost1"
18548         # truncate
18549         cmd="$TRUNCATE $DIR/$tfile 0"
18550         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18551         # rename
18552         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18553         verify_jobstats "$cmd" "$SINGLEMDS"
18554         # jobstats expiry - sleep until old stats should be expired
18555         local left=$((new_interval + 5 - (SECONDS - start)))
18556         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18557                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18558                         "0" $left
18559         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18560         verify_jobstats "$cmd" "$SINGLEMDS"
18561         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18562             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18563
18564         # Ensure that jobid are present in changelog (if supported by MDS)
18565         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18566                 changelog_dump | tail -10
18567                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18568                 [ $jobids -eq 9 ] ||
18569                         error "Wrong changelog jobid count $jobids != 9"
18570
18571                 # LU-5862
18572                 JOBENV="disable"
18573                 jobstats_set $JOBENV
18574                 touch $DIR/$tfile
18575                 changelog_dump | grep $tfile
18576                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18577                 [ $jobids -eq 0 ] ||
18578                         error "Unexpected jobids when jobid_var=$JOBENV"
18579         fi
18580
18581         # test '%j' access to environment variable - if supported
18582         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18583                 JOBENV="JOBCOMPLEX"
18584                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18585
18586                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18587         fi
18588
18589         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18590                 JOBENV="JOBCOMPLEX"
18591                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18592
18593                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18594         fi
18595
18596         # test '%j' access to per-session jobid - if supported
18597         if lctl list_param jobid_this_session > /dev/null 2>&1
18598         then
18599                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18600                 lctl set_param jobid_this_session=$USER
18601
18602                 JOBENV="JOBCOMPLEX"
18603                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18604
18605                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18606         fi
18607 }
18608 run_test 205a "Verify job stats"
18609
18610 # LU-13117, LU-13597
18611 test_205b() {
18612         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18613                 skip "Need MDS version at least 2.13.54.91"
18614
18615         job_stats="mdt.*.job_stats"
18616         $LCTL set_param $job_stats=clear
18617         # Setting jobid_var to USER might not be supported
18618         $LCTL set_param jobid_var=USER || true
18619         $LCTL set_param jobid_name="%e.%u"
18620         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18621         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18622                 grep "job_id:.*foolish" &&
18623                         error "Unexpected jobid found"
18624         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18625                 grep "open:.*min.*max.*sum" ||
18626                         error "wrong job_stats format found"
18627 }
18628 run_test 205b "Verify job stats jobid and output format"
18629
18630 # LU-13733
18631 test_205c() {
18632         $LCTL set_param llite.*.stats=0
18633         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18634         $LCTL get_param llite.*.stats
18635         $LCTL get_param llite.*.stats | grep \
18636                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18637                         error "wrong client stats format found"
18638 }
18639 run_test 205c "Verify client stats format"
18640
18641 # LU-1480, LU-1773 and LU-1657
18642 test_206() {
18643         mkdir -p $DIR/$tdir
18644         $LFS setstripe -c -1 $DIR/$tdir
18645 #define OBD_FAIL_LOV_INIT 0x1403
18646         $LCTL set_param fail_loc=0xa0001403
18647         $LCTL set_param fail_val=1
18648         touch $DIR/$tdir/$tfile || true
18649 }
18650 run_test 206 "fail lov_init_raid0() doesn't lbug"
18651
18652 test_207a() {
18653         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18654         local fsz=`stat -c %s $DIR/$tfile`
18655         cancel_lru_locks mdc
18656
18657         # do not return layout in getattr intent
18658 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18659         $LCTL set_param fail_loc=0x170
18660         local sz=`stat -c %s $DIR/$tfile`
18661
18662         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18663
18664         rm -rf $DIR/$tfile
18665 }
18666 run_test 207a "can refresh layout at glimpse"
18667
18668 test_207b() {
18669         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18670         local cksum=`md5sum $DIR/$tfile`
18671         local fsz=`stat -c %s $DIR/$tfile`
18672         cancel_lru_locks mdc
18673         cancel_lru_locks osc
18674
18675         # do not return layout in getattr intent
18676 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18677         $LCTL set_param fail_loc=0x171
18678
18679         # it will refresh layout after the file is opened but before read issues
18680         echo checksum is "$cksum"
18681         echo "$cksum" |md5sum -c --quiet || error "file differs"
18682
18683         rm -rf $DIR/$tfile
18684 }
18685 run_test 207b "can refresh layout at open"
18686
18687 test_208() {
18688         # FIXME: in this test suite, only RD lease is used. This is okay
18689         # for now as only exclusive open is supported. After generic lease
18690         # is done, this test suite should be revised. - Jinshan
18691
18692         remote_mds_nodsh && skip "remote MDS with nodsh"
18693         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18694                 skip "Need MDS version at least 2.4.52"
18695
18696         echo "==== test 1: verify get lease work"
18697         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18698
18699         echo "==== test 2: verify lease can be broken by upcoming open"
18700         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18701         local PID=$!
18702         sleep 2
18703
18704         $MULTIOP $DIR/$tfile oO_RDWR:c
18705         kill -USR1 $PID && wait $PID || error "break lease error"
18706
18707         echo "==== test 3: verify lease can't be granted if an open already exists"
18708         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18709         local PID=$!
18710         sleep 2
18711
18712         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18713         kill -USR1 $PID && wait $PID || error "open file error"
18714
18715         echo "==== test 4: lease can sustain over recovery"
18716         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18717         PID=$!
18718         sleep 2
18719
18720         fail mds1
18721
18722         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18723
18724         echo "==== test 5: lease broken can't be regained by replay"
18725         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18726         PID=$!
18727         sleep 2
18728
18729         # open file to break lease and then recovery
18730         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18731         fail mds1
18732
18733         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18734
18735         rm -f $DIR/$tfile
18736 }
18737 run_test 208 "Exclusive open"
18738
18739 test_209() {
18740         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18741                 skip_env "must have disp_stripe"
18742
18743         touch $DIR/$tfile
18744         sync; sleep 5; sync;
18745
18746         echo 3 > /proc/sys/vm/drop_caches
18747         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18748                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18749         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18750
18751         # open/close 500 times
18752         for i in $(seq 500); do
18753                 cat $DIR/$tfile
18754         done
18755
18756         echo 3 > /proc/sys/vm/drop_caches
18757         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18758                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18759         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18760
18761         echo "before: $req_before, after: $req_after"
18762         [ $((req_after - req_before)) -ge 300 ] &&
18763                 error "open/close requests are not freed"
18764         return 0
18765 }
18766 run_test 209 "read-only open/close requests should be freed promptly"
18767
18768 test_210() {
18769         local pid
18770
18771         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18772         pid=$!
18773         sleep 1
18774
18775         $LFS getstripe $DIR/$tfile
18776         kill -USR1 $pid
18777         wait $pid || error "multiop failed"
18778
18779         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18780         pid=$!
18781         sleep 1
18782
18783         $LFS getstripe $DIR/$tfile
18784         kill -USR1 $pid
18785         wait $pid || error "multiop failed"
18786 }
18787 run_test 210 "lfs getstripe does not break leases"
18788
18789 test_212() {
18790         size=`date +%s`
18791         size=$((size % 8192 + 1))
18792         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18793         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18794         rm -f $DIR/f212 $DIR/f212.xyz
18795 }
18796 run_test 212 "Sendfile test ============================================"
18797
18798 test_213() {
18799         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18800         cancel_lru_locks osc
18801         lctl set_param fail_loc=0x8000040f
18802         # generate a read lock
18803         cat $DIR/$tfile > /dev/null
18804         # write to the file, it will try to cancel the above read lock.
18805         cat /etc/hosts >> $DIR/$tfile
18806 }
18807 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18808
18809 test_214() { # for bug 20133
18810         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18811         for (( i=0; i < 340; i++ )) ; do
18812                 touch $DIR/$tdir/d214c/a$i
18813         done
18814
18815         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18816         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18817         ls $DIR/d214c || error "ls $DIR/d214c failed"
18818         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18819         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18820 }
18821 run_test 214 "hash-indexed directory test - bug 20133"
18822
18823 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18824 create_lnet_proc_files() {
18825         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18826 }
18827
18828 # counterpart of create_lnet_proc_files
18829 remove_lnet_proc_files() {
18830         rm -f $TMP/lnet_$1.sys
18831 }
18832
18833 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18834 # 3rd arg as regexp for body
18835 check_lnet_proc_stats() {
18836         local l=$(cat "$TMP/lnet_$1" |wc -l)
18837         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18838
18839         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18840 }
18841
18842 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18843 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18844 # optional and can be regexp for 2nd line (lnet.routes case)
18845 check_lnet_proc_entry() {
18846         local blp=2          # blp stands for 'position of 1st line of body'
18847         [ -z "$5" ] || blp=3 # lnet.routes case
18848
18849         local l=$(cat "$TMP/lnet_$1" |wc -l)
18850         # subtracting one from $blp because the body can be empty
18851         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18852
18853         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18854                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18855
18856         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18857                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18858
18859         # bail out if any unexpected line happened
18860         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18861         [ "$?" != 0 ] || error "$2 misformatted"
18862 }
18863
18864 test_215() { # for bugs 18102, 21079, 21517
18865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18866
18867         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18868         local P='[1-9][0-9]*'           # positive numeric
18869         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18870         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18871         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18872         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18873
18874         local L1 # regexp for 1st line
18875         local L2 # regexp for 2nd line (optional)
18876         local BR # regexp for the rest (body)
18877
18878         # lnet.stats should look as 11 space-separated non-negative numerics
18879         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18880         create_lnet_proc_files "stats"
18881         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18882         remove_lnet_proc_files "stats"
18883
18884         # lnet.routes should look like this:
18885         # Routing disabled/enabled
18886         # net hops priority state router
18887         # where net is a string like tcp0, hops > 0, priority >= 0,
18888         # state is up/down,
18889         # router is a string like 192.168.1.1@tcp2
18890         L1="^Routing (disabled|enabled)$"
18891         L2="^net +hops +priority +state +router$"
18892         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18893         create_lnet_proc_files "routes"
18894         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18895         remove_lnet_proc_files "routes"
18896
18897         # lnet.routers should look like this:
18898         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18899         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18900         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18901         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18902         L1="^ref +rtr_ref +alive +router$"
18903         BR="^$P +$P +(up|down) +$NID$"
18904         create_lnet_proc_files "routers"
18905         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18906         remove_lnet_proc_files "routers"
18907
18908         # lnet.peers should look like this:
18909         # nid refs state last max rtr min tx min queue
18910         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18911         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18912         # numeric (0 or >0 or <0), queue >= 0.
18913         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18914         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18915         create_lnet_proc_files "peers"
18916         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18917         remove_lnet_proc_files "peers"
18918
18919         # lnet.buffers  should look like this:
18920         # pages count credits min
18921         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18922         L1="^pages +count +credits +min$"
18923         BR="^ +$N +$N +$I +$I$"
18924         create_lnet_proc_files "buffers"
18925         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18926         remove_lnet_proc_files "buffers"
18927
18928         # lnet.nis should look like this:
18929         # nid status alive refs peer rtr max tx min
18930         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18931         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18932         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18933         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18934         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18935         create_lnet_proc_files "nis"
18936         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18937         remove_lnet_proc_files "nis"
18938
18939         # can we successfully write to lnet.stats?
18940         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18941 }
18942 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18943
18944 test_216() { # bug 20317
18945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18946         remote_ost_nodsh && skip "remote OST with nodsh"
18947
18948         local node
18949         local facets=$(get_facets OST)
18950         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18951
18952         save_lustre_params client "osc.*.contention_seconds" > $p
18953         save_lustre_params $facets \
18954                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18955         save_lustre_params $facets \
18956                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18957         save_lustre_params $facets \
18958                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18959         clear_stats osc.*.osc_stats
18960
18961         # agressive lockless i/o settings
18962         do_nodes $(comma_list $(osts_nodes)) \
18963                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18964                         ldlm.namespaces.filter-*.contended_locks=0 \
18965                         ldlm.namespaces.filter-*.contention_seconds=60"
18966         lctl set_param -n osc.*.contention_seconds=60
18967
18968         $DIRECTIO write $DIR/$tfile 0 10 4096
18969         $CHECKSTAT -s 40960 $DIR/$tfile
18970
18971         # disable lockless i/o
18972         do_nodes $(comma_list $(osts_nodes)) \
18973                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18974                         ldlm.namespaces.filter-*.contended_locks=32 \
18975                         ldlm.namespaces.filter-*.contention_seconds=0"
18976         lctl set_param -n osc.*.contention_seconds=0
18977         clear_stats osc.*.osc_stats
18978
18979         dd if=/dev/zero of=$DIR/$tfile count=0
18980         $CHECKSTAT -s 0 $DIR/$tfile
18981
18982         restore_lustre_params <$p
18983         rm -f $p
18984         rm $DIR/$tfile
18985 }
18986 run_test 216 "check lockless direct write updates file size and kms correctly"
18987
18988 test_217() { # bug 22430
18989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18990
18991         local node
18992         local nid
18993
18994         for node in $(nodes_list); do
18995                 nid=$(host_nids_address $node $NETTYPE)
18996                 if [[ $nid = *-* ]] ; then
18997                         echo "lctl ping $(h2nettype $nid)"
18998                         lctl ping $(h2nettype $nid)
18999                 else
19000                         echo "skipping $node (no hyphen detected)"
19001                 fi
19002         done
19003 }
19004 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19005
19006 test_218() {
19007        # do directio so as not to populate the page cache
19008        log "creating a 10 Mb file"
19009        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19010        log "starting reads"
19011        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19012        log "truncating the file"
19013        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19014        log "killing dd"
19015        kill %+ || true # reads might have finished
19016        echo "wait until dd is finished"
19017        wait
19018        log "removing the temporary file"
19019        rm -rf $DIR/$tfile || error "tmp file removal failed"
19020 }
19021 run_test 218 "parallel read and truncate should not deadlock"
19022
19023 test_219() {
19024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19025
19026         # write one partial page
19027         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19028         # set no grant so vvp_io_commit_write will do sync write
19029         $LCTL set_param fail_loc=0x411
19030         # write a full page at the end of file
19031         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19032
19033         $LCTL set_param fail_loc=0
19034         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19035         $LCTL set_param fail_loc=0x411
19036         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19037
19038         # LU-4201
19039         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19040         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19041 }
19042 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19043
19044 test_220() { #LU-325
19045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19046         remote_ost_nodsh && skip "remote OST with nodsh"
19047         remote_mds_nodsh && skip "remote MDS with nodsh"
19048         remote_mgs_nodsh && skip "remote MGS with nodsh"
19049
19050         local OSTIDX=0
19051
19052         # create on MDT0000 so the last_id and next_id are correct
19053         mkdir_on_mdt0 $DIR/$tdir
19054         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19055         OST=${OST%_UUID}
19056
19057         # on the mdt's osc
19058         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19059         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19060                         osp.$mdtosc_proc1.prealloc_last_id)
19061         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19062                         osp.$mdtosc_proc1.prealloc_next_id)
19063
19064         $LFS df -i
19065
19066         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19067         #define OBD_FAIL_OST_ENOINO              0x229
19068         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19069         create_pool $FSNAME.$TESTNAME || return 1
19070         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19071
19072         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19073
19074         MDSOBJS=$((last_id - next_id))
19075         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19076
19077         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19078         echo "OST still has $count kbytes free"
19079
19080         echo "create $MDSOBJS files @next_id..."
19081         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19082
19083         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19084                         osp.$mdtosc_proc1.prealloc_last_id)
19085         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19086                         osp.$mdtosc_proc1.prealloc_next_id)
19087
19088         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19089         $LFS df -i
19090
19091         echo "cleanup..."
19092
19093         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19094         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19095
19096         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19097                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19098         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19099                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19100         echo "unlink $MDSOBJS files @$next_id..."
19101         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19102 }
19103 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19104
19105 test_221() {
19106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19107
19108         dd if=`which date` of=$MOUNT/date oflag=sync
19109         chmod +x $MOUNT/date
19110
19111         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19112         $LCTL set_param fail_loc=0x80001401
19113
19114         $MOUNT/date > /dev/null
19115         rm -f $MOUNT/date
19116 }
19117 run_test 221 "make sure fault and truncate race to not cause OOM"
19118
19119 test_222a () {
19120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19121
19122         rm -rf $DIR/$tdir
19123         test_mkdir $DIR/$tdir
19124         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19125         createmany -o $DIR/$tdir/$tfile 10
19126         cancel_lru_locks mdc
19127         cancel_lru_locks osc
19128         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19129         $LCTL set_param fail_loc=0x31a
19130         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19131         $LCTL set_param fail_loc=0
19132         rm -r $DIR/$tdir
19133 }
19134 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19135
19136 test_222b () {
19137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19138
19139         rm -rf $DIR/$tdir
19140         test_mkdir $DIR/$tdir
19141         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19142         createmany -o $DIR/$tdir/$tfile 10
19143         cancel_lru_locks mdc
19144         cancel_lru_locks osc
19145         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19146         $LCTL set_param fail_loc=0x31a
19147         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19148         $LCTL set_param fail_loc=0
19149 }
19150 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19151
19152 test_223 () {
19153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19154
19155         rm -rf $DIR/$tdir
19156         test_mkdir $DIR/$tdir
19157         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19158         createmany -o $DIR/$tdir/$tfile 10
19159         cancel_lru_locks mdc
19160         cancel_lru_locks osc
19161         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19162         $LCTL set_param fail_loc=0x31b
19163         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19164         $LCTL set_param fail_loc=0
19165         rm -r $DIR/$tdir
19166 }
19167 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19168
19169 test_224a() { # LU-1039, MRP-303
19170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19171         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19172         $LCTL set_param fail_loc=0x508
19173         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19174         $LCTL set_param fail_loc=0
19175         df $DIR
19176 }
19177 run_test 224a "Don't panic on bulk IO failure"
19178
19179 test_224bd_sub() { # LU-1039, MRP-303
19180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19181         local timeout=$1
19182
19183         shift
19184         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19185
19186         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19187
19188         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19189         cancel_lru_locks osc
19190         set_checksums 0
19191         stack_trap "set_checksums $ORIG_CSUM" EXIT
19192         local at_max_saved=0
19193
19194         # adaptive timeouts may prevent seeing the issue
19195         if at_is_enabled; then
19196                 at_max_saved=$(at_max_get mds)
19197                 at_max_set 0 mds client
19198                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19199         fi
19200
19201         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19202         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19203         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19204
19205         do_facet ost1 $LCTL set_param fail_loc=0
19206         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19207         df $DIR
19208 }
19209
19210 test_224b() {
19211         test_224bd_sub 3 error "dd failed"
19212 }
19213 run_test 224b "Don't panic on bulk IO failure"
19214
19215 test_224c() { # LU-6441
19216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19217         remote_mds_nodsh && skip "remote MDS with nodsh"
19218
19219         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19220         save_writethrough $p
19221         set_cache writethrough on
19222
19223         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19224         local at_max=$($LCTL get_param -n at_max)
19225         local timeout=$($LCTL get_param -n timeout)
19226         local test_at="at_max"
19227         local param_at="$FSNAME.sys.at_max"
19228         local test_timeout="timeout"
19229         local param_timeout="$FSNAME.sys.timeout"
19230
19231         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19232
19233         set_persistent_param_and_check client "$test_at" "$param_at" 0
19234         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19235
19236         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19237         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19238         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19239         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19240         sync
19241         do_facet ost1 "$LCTL set_param fail_loc=0"
19242
19243         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19244         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19245                 $timeout
19246
19247         $LCTL set_param -n $pages_per_rpc
19248         restore_lustre_params < $p
19249         rm -f $p
19250 }
19251 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19252
19253 test_224d() { # LU-11169
19254         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19255 }
19256 run_test 224d "Don't corrupt data on bulk IO timeout"
19257
19258 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19259 test_225a () {
19260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19261         if [ -z ${MDSSURVEY} ]; then
19262                 skip_env "mds-survey not found"
19263         fi
19264         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19265                 skip "Need MDS version at least 2.2.51"
19266
19267         local mds=$(facet_host $SINGLEMDS)
19268         local target=$(do_nodes $mds 'lctl dl' |
19269                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19270
19271         local cmd1="file_count=1000 thrhi=4"
19272         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19273         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19274         local cmd="$cmd1 $cmd2 $cmd3"
19275
19276         rm -f ${TMP}/mds_survey*
19277         echo + $cmd
19278         eval $cmd || error "mds-survey with zero-stripe failed"
19279         cat ${TMP}/mds_survey*
19280         rm -f ${TMP}/mds_survey*
19281 }
19282 run_test 225a "Metadata survey sanity with zero-stripe"
19283
19284 test_225b () {
19285         if [ -z ${MDSSURVEY} ]; then
19286                 skip_env "mds-survey not found"
19287         fi
19288         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19289                 skip "Need MDS version at least 2.2.51"
19290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19291         remote_mds_nodsh && skip "remote MDS with nodsh"
19292         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19293                 skip_env "Need to mount OST to test"
19294         fi
19295
19296         local mds=$(facet_host $SINGLEMDS)
19297         local target=$(do_nodes $mds 'lctl dl' |
19298                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19299
19300         local cmd1="file_count=1000 thrhi=4"
19301         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19302         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19303         local cmd="$cmd1 $cmd2 $cmd3"
19304
19305         rm -f ${TMP}/mds_survey*
19306         echo + $cmd
19307         eval $cmd || error "mds-survey with stripe_count failed"
19308         cat ${TMP}/mds_survey*
19309         rm -f ${TMP}/mds_survey*
19310 }
19311 run_test 225b "Metadata survey sanity with stripe_count = 1"
19312
19313 mcreate_path2fid () {
19314         local mode=$1
19315         local major=$2
19316         local minor=$3
19317         local name=$4
19318         local desc=$5
19319         local path=$DIR/$tdir/$name
19320         local fid
19321         local rc
19322         local fid_path
19323
19324         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19325                 error "cannot create $desc"
19326
19327         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19328         rc=$?
19329         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19330
19331         fid_path=$($LFS fid2path $MOUNT $fid)
19332         rc=$?
19333         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19334
19335         [ "$path" == "$fid_path" ] ||
19336                 error "fid2path returned $fid_path, expected $path"
19337
19338         echo "pass with $path and $fid"
19339 }
19340
19341 test_226a () {
19342         rm -rf $DIR/$tdir
19343         mkdir -p $DIR/$tdir
19344
19345         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19346         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19347         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19348         mcreate_path2fid 0040666 0 0 dir "directory"
19349         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19350         mcreate_path2fid 0100666 0 0 file "regular file"
19351         mcreate_path2fid 0120666 0 0 link "symbolic link"
19352         mcreate_path2fid 0140666 0 0 sock "socket"
19353 }
19354 run_test 226a "call path2fid and fid2path on files of all type"
19355
19356 test_226b () {
19357         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19358
19359         local MDTIDX=1
19360
19361         rm -rf $DIR/$tdir
19362         mkdir -p $DIR/$tdir
19363         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19364                 error "create remote directory failed"
19365         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19366         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19367                                 "character special file (null)"
19368         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19369                                 "character special file (no device)"
19370         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19371         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19372                                 "block special file (loop)"
19373         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19374         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19375         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19376 }
19377 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19378
19379 test_226c () {
19380         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19381         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19382                 skip "Need MDS version at least 2.13.55"
19383
19384         local submnt=/mnt/submnt
19385         local srcfile=/etc/passwd
19386         local dstfile=$submnt/passwd
19387         local path
19388         local fid
19389
19390         rm -rf $DIR/$tdir
19391         rm -rf $submnt
19392         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19393                 error "create remote directory failed"
19394         mkdir -p $submnt || error "create $submnt failed"
19395         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19396                 error "mount $submnt failed"
19397         stack_trap "umount $submnt" EXIT
19398
19399         cp $srcfile $dstfile
19400         fid=$($LFS path2fid $dstfile)
19401         path=$($LFS fid2path $submnt "$fid")
19402         [ "$path" = "$dstfile" ] ||
19403                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19404 }
19405 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19406
19407 # LU-1299 Executing or running ldd on a truncated executable does not
19408 # cause an out-of-memory condition.
19409 test_227() {
19410         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19411         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19412
19413         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19414         chmod +x $MOUNT/date
19415
19416         $MOUNT/date > /dev/null
19417         ldd $MOUNT/date > /dev/null
19418         rm -f $MOUNT/date
19419 }
19420 run_test 227 "running truncated executable does not cause OOM"
19421
19422 # LU-1512 try to reuse idle OI blocks
19423 test_228a() {
19424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19425         remote_mds_nodsh && skip "remote MDS with nodsh"
19426         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19427
19428         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19429         local myDIR=$DIR/$tdir
19430
19431         mkdir -p $myDIR
19432         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19433         $LCTL set_param fail_loc=0x80001002
19434         createmany -o $myDIR/t- 10000
19435         $LCTL set_param fail_loc=0
19436         # The guard is current the largest FID holder
19437         touch $myDIR/guard
19438         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19439                     tr -d '[')
19440         local IDX=$(($SEQ % 64))
19441
19442         do_facet $SINGLEMDS sync
19443         # Make sure journal flushed.
19444         sleep 6
19445         local blk1=$(do_facet $SINGLEMDS \
19446                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19447                      grep Blockcount | awk '{print $4}')
19448
19449         # Remove old files, some OI blocks will become idle.
19450         unlinkmany $myDIR/t- 10000
19451         # Create new files, idle OI blocks should be reused.
19452         createmany -o $myDIR/t- 2000
19453         do_facet $SINGLEMDS sync
19454         # Make sure journal flushed.
19455         sleep 6
19456         local blk2=$(do_facet $SINGLEMDS \
19457                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19458                      grep Blockcount | awk '{print $4}')
19459
19460         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19461 }
19462 run_test 228a "try to reuse idle OI blocks"
19463
19464 test_228b() {
19465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19466         remote_mds_nodsh && skip "remote MDS with nodsh"
19467         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19468
19469         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19470         local myDIR=$DIR/$tdir
19471
19472         mkdir -p $myDIR
19473         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19474         $LCTL set_param fail_loc=0x80001002
19475         createmany -o $myDIR/t- 10000
19476         $LCTL set_param fail_loc=0
19477         # The guard is current the largest FID holder
19478         touch $myDIR/guard
19479         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19480                     tr -d '[')
19481         local IDX=$(($SEQ % 64))
19482
19483         do_facet $SINGLEMDS sync
19484         # Make sure journal flushed.
19485         sleep 6
19486         local blk1=$(do_facet $SINGLEMDS \
19487                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19488                      grep Blockcount | awk '{print $4}')
19489
19490         # Remove old files, some OI blocks will become idle.
19491         unlinkmany $myDIR/t- 10000
19492
19493         # stop the MDT
19494         stop $SINGLEMDS || error "Fail to stop MDT."
19495         # remount the MDT
19496         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
19497                 error "Fail to start MDT."
19498
19499         df $MOUNT || error "Fail to df."
19500         # Create new files, idle OI blocks should be reused.
19501         createmany -o $myDIR/t- 2000
19502         do_facet $SINGLEMDS sync
19503         # Make sure journal flushed.
19504         sleep 6
19505         local blk2=$(do_facet $SINGLEMDS \
19506                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19507                      grep Blockcount | awk '{print $4}')
19508
19509         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19510 }
19511 run_test 228b "idle OI blocks can be reused after MDT restart"
19512
19513 #LU-1881
19514 test_228c() {
19515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19516         remote_mds_nodsh && skip "remote MDS with nodsh"
19517         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19518
19519         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19520         local myDIR=$DIR/$tdir
19521
19522         mkdir -p $myDIR
19523         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19524         $LCTL set_param fail_loc=0x80001002
19525         # 20000 files can guarantee there are index nodes in the OI file
19526         createmany -o $myDIR/t- 20000
19527         $LCTL set_param fail_loc=0
19528         # The guard is current the largest FID holder
19529         touch $myDIR/guard
19530         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19531                     tr -d '[')
19532         local IDX=$(($SEQ % 64))
19533
19534         do_facet $SINGLEMDS sync
19535         # Make sure journal flushed.
19536         sleep 6
19537         local blk1=$(do_facet $SINGLEMDS \
19538                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19539                      grep Blockcount | awk '{print $4}')
19540
19541         # Remove old files, some OI blocks will become idle.
19542         unlinkmany $myDIR/t- 20000
19543         rm -f $myDIR/guard
19544         # The OI file should become empty now
19545
19546         # Create new files, idle OI blocks should be reused.
19547         createmany -o $myDIR/t- 2000
19548         do_facet $SINGLEMDS sync
19549         # Make sure journal flushed.
19550         sleep 6
19551         local blk2=$(do_facet $SINGLEMDS \
19552                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19553                      grep Blockcount | awk '{print $4}')
19554
19555         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19556 }
19557 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19558
19559 test_229() { # LU-2482, LU-3448
19560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19561         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19562         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19563                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19564
19565         rm -f $DIR/$tfile
19566
19567         # Create a file with a released layout and stripe count 2.
19568         $MULTIOP $DIR/$tfile H2c ||
19569                 error "failed to create file with released layout"
19570
19571         $LFS getstripe -v $DIR/$tfile
19572
19573         local pattern=$($LFS getstripe -L $DIR/$tfile)
19574         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19575
19576         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19577                 error "getstripe"
19578         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19579         stat $DIR/$tfile || error "failed to stat released file"
19580
19581         chown $RUNAS_ID $DIR/$tfile ||
19582                 error "chown $RUNAS_ID $DIR/$tfile failed"
19583
19584         chgrp $RUNAS_ID $DIR/$tfile ||
19585                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19586
19587         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19588         rm $DIR/$tfile || error "failed to remove released file"
19589 }
19590 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19591
19592 test_230a() {
19593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19594         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19595         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19596                 skip "Need MDS version at least 2.11.52"
19597
19598         local MDTIDX=1
19599
19600         test_mkdir $DIR/$tdir
19601         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19602         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19603         [ $mdt_idx -ne 0 ] &&
19604                 error "create local directory on wrong MDT $mdt_idx"
19605
19606         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19607                         error "create remote directory failed"
19608         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19609         [ $mdt_idx -ne $MDTIDX ] &&
19610                 error "create remote directory on wrong MDT $mdt_idx"
19611
19612         createmany -o $DIR/$tdir/test_230/t- 10 ||
19613                 error "create files on remote directory failed"
19614         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19615         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19616         rm -r $DIR/$tdir || error "unlink remote directory failed"
19617 }
19618 run_test 230a "Create remote directory and files under the remote directory"
19619
19620 test_230b() {
19621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19622         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19623         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19624                 skip "Need MDS version at least 2.11.52"
19625
19626         local MDTIDX=1
19627         local mdt_index
19628         local i
19629         local file
19630         local pid
19631         local stripe_count
19632         local migrate_dir=$DIR/$tdir/migrate_dir
19633         local other_dir=$DIR/$tdir/other_dir
19634
19635         test_mkdir $DIR/$tdir
19636         test_mkdir -i0 -c1 $migrate_dir
19637         test_mkdir -i0 -c1 $other_dir
19638         for ((i=0; i<10; i++)); do
19639                 mkdir -p $migrate_dir/dir_${i}
19640                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19641                         error "create files under remote dir failed $i"
19642         done
19643
19644         cp /etc/passwd $migrate_dir/$tfile
19645         cp /etc/passwd $other_dir/$tfile
19646         chattr +SAD $migrate_dir
19647         chattr +SAD $migrate_dir/$tfile
19648
19649         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19650         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19651         local old_dir_mode=$(stat -c%f $migrate_dir)
19652         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19653
19654         mkdir -p $migrate_dir/dir_default_stripe2
19655         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19656         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19657
19658         mkdir -p $other_dir
19659         ln $migrate_dir/$tfile $other_dir/luna
19660         ln $migrate_dir/$tfile $migrate_dir/sofia
19661         ln $other_dir/$tfile $migrate_dir/david
19662         ln -s $migrate_dir/$tfile $other_dir/zachary
19663         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19664         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19665
19666         local len
19667         local lnktgt
19668
19669         # inline symlink
19670         for len in 58 59 60; do
19671                 lnktgt=$(str_repeat 'l' $len)
19672                 touch $migrate_dir/$lnktgt
19673                 ln -s $lnktgt $migrate_dir/${len}char_ln
19674         done
19675
19676         # PATH_MAX
19677         for len in 4094 4095; do
19678                 lnktgt=$(str_repeat 'l' $len)
19679                 ln -s $lnktgt $migrate_dir/${len}char_ln
19680         done
19681
19682         # NAME_MAX
19683         for len in 254 255; do
19684                 touch $migrate_dir/$(str_repeat 'l' $len)
19685         done
19686
19687         $LFS migrate -m $MDTIDX $migrate_dir ||
19688                 error "fails on migrating remote dir to MDT1"
19689
19690         echo "migratate to MDT1, then checking.."
19691         for ((i = 0; i < 10; i++)); do
19692                 for file in $(find $migrate_dir/dir_${i}); do
19693                         mdt_index=$($LFS getstripe -m $file)
19694                         # broken symlink getstripe will fail
19695                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19696                                 error "$file is not on MDT${MDTIDX}"
19697                 done
19698         done
19699
19700         # the multiple link file should still in MDT0
19701         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19702         [ $mdt_index == 0 ] ||
19703                 error "$file is not on MDT${MDTIDX}"
19704
19705         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19706         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19707                 error " expect $old_dir_flag get $new_dir_flag"
19708
19709         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19710         [ "$old_file_flag" = "$new_file_flag" ] ||
19711                 error " expect $old_file_flag get $new_file_flag"
19712
19713         local new_dir_mode=$(stat -c%f $migrate_dir)
19714         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19715                 error "expect mode $old_dir_mode get $new_dir_mode"
19716
19717         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19718         [ "$old_file_mode" = "$new_file_mode" ] ||
19719                 error "expect mode $old_file_mode get $new_file_mode"
19720
19721         diff /etc/passwd $migrate_dir/$tfile ||
19722                 error "$tfile different after migration"
19723
19724         diff /etc/passwd $other_dir/luna ||
19725                 error "luna different after migration"
19726
19727         diff /etc/passwd $migrate_dir/sofia ||
19728                 error "sofia different after migration"
19729
19730         diff /etc/passwd $migrate_dir/david ||
19731                 error "david different after migration"
19732
19733         diff /etc/passwd $other_dir/zachary ||
19734                 error "zachary different after migration"
19735
19736         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19737                 error "${tfile}_ln different after migration"
19738
19739         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19740                 error "${tfile}_ln_other different after migration"
19741
19742         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19743         [ $stripe_count = 2 ] ||
19744                 error "dir strpe_count $d != 2 after migration."
19745
19746         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19747         [ $stripe_count = 2 ] ||
19748                 error "file strpe_count $d != 2 after migration."
19749
19750         #migrate back to MDT0
19751         MDTIDX=0
19752
19753         $LFS migrate -m $MDTIDX $migrate_dir ||
19754                 error "fails on migrating remote dir to MDT0"
19755
19756         echo "migrate back to MDT0, checking.."
19757         for file in $(find $migrate_dir); do
19758                 mdt_index=$($LFS getstripe -m $file)
19759                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19760                         error "$file is not on MDT${MDTIDX}"
19761         done
19762
19763         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19764         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19765                 error " expect $old_dir_flag get $new_dir_flag"
19766
19767         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19768         [ "$old_file_flag" = "$new_file_flag" ] ||
19769                 error " expect $old_file_flag get $new_file_flag"
19770
19771         local new_dir_mode=$(stat -c%f $migrate_dir)
19772         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19773                 error "expect mode $old_dir_mode get $new_dir_mode"
19774
19775         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19776         [ "$old_file_mode" = "$new_file_mode" ] ||
19777                 error "expect mode $old_file_mode get $new_file_mode"
19778
19779         diff /etc/passwd ${migrate_dir}/$tfile ||
19780                 error "$tfile different after migration"
19781
19782         diff /etc/passwd ${other_dir}/luna ||
19783                 error "luna different after migration"
19784
19785         diff /etc/passwd ${migrate_dir}/sofia ||
19786                 error "sofia different after migration"
19787
19788         diff /etc/passwd ${other_dir}/zachary ||
19789                 error "zachary different after migration"
19790
19791         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19792                 error "${tfile}_ln different after migration"
19793
19794         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19795                 error "${tfile}_ln_other different after migration"
19796
19797         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19798         [ $stripe_count = 2 ] ||
19799                 error "dir strpe_count $d != 2 after migration."
19800
19801         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19802         [ $stripe_count = 2 ] ||
19803                 error "file strpe_count $d != 2 after migration."
19804
19805         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19806 }
19807 run_test 230b "migrate directory"
19808
19809 test_230c() {
19810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19811         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19812         remote_mds_nodsh && skip "remote MDS with nodsh"
19813         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19814                 skip "Need MDS version at least 2.11.52"
19815
19816         local MDTIDX=1
19817         local total=3
19818         local mdt_index
19819         local file
19820         local migrate_dir=$DIR/$tdir/migrate_dir
19821
19822         #If migrating directory fails in the middle, all entries of
19823         #the directory is still accessiable.
19824         test_mkdir $DIR/$tdir
19825         test_mkdir -i0 -c1 $migrate_dir
19826         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19827         stat $migrate_dir
19828         createmany -o $migrate_dir/f $total ||
19829                 error "create files under ${migrate_dir} failed"
19830
19831         # fail after migrating top dir, and this will fail only once, so the
19832         # first sub file migration will fail (currently f3), others succeed.
19833         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19834         do_facet mds1 lctl set_param fail_loc=0x1801
19835         local t=$(ls $migrate_dir | wc -l)
19836         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19837                 error "migrate should fail"
19838         local u=$(ls $migrate_dir | wc -l)
19839         [ "$u" == "$t" ] || error "$u != $t during migration"
19840
19841         # add new dir/file should succeed
19842         mkdir $migrate_dir/dir ||
19843                 error "mkdir failed under migrating directory"
19844         touch $migrate_dir/file ||
19845                 error "create file failed under migrating directory"
19846
19847         # add file with existing name should fail
19848         for file in $migrate_dir/f*; do
19849                 stat $file > /dev/null || error "stat $file failed"
19850                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19851                         error "open(O_CREAT|O_EXCL) $file should fail"
19852                 $MULTIOP $file m && error "create $file should fail"
19853                 touch $DIR/$tdir/remote_dir/$tfile ||
19854                         error "touch $tfile failed"
19855                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19856                         error "link $file should fail"
19857                 mdt_index=$($LFS getstripe -m $file)
19858                 if [ $mdt_index == 0 ]; then
19859                         # file failed to migrate is not allowed to rename to
19860                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19861                                 error "rename to $file should fail"
19862                 else
19863                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19864                                 error "rename to $file failed"
19865                 fi
19866                 echo hello >> $file || error "write $file failed"
19867         done
19868
19869         # resume migration with different options should fail
19870         $LFS migrate -m 0 $migrate_dir &&
19871                 error "migrate -m 0 $migrate_dir should fail"
19872
19873         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19874                 error "migrate -c 2 $migrate_dir should fail"
19875
19876         # resume migration should succeed
19877         $LFS migrate -m $MDTIDX $migrate_dir ||
19878                 error "migrate $migrate_dir failed"
19879
19880         echo "Finish migration, then checking.."
19881         for file in $(find $migrate_dir); do
19882                 mdt_index=$($LFS getstripe -m $file)
19883                 [ $mdt_index == $MDTIDX ] ||
19884                         error "$file is not on MDT${MDTIDX}"
19885         done
19886
19887         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19888 }
19889 run_test 230c "check directory accessiblity if migration failed"
19890
19891 test_230d() {
19892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19893         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19894         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19895                 skip "Need MDS version at least 2.11.52"
19896         # LU-11235
19897         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19898
19899         local migrate_dir=$DIR/$tdir/migrate_dir
19900         local old_index
19901         local new_index
19902         local old_count
19903         local new_count
19904         local new_hash
19905         local mdt_index
19906         local i
19907         local j
19908
19909         old_index=$((RANDOM % MDSCOUNT))
19910         old_count=$((MDSCOUNT - old_index))
19911         new_index=$((RANDOM % MDSCOUNT))
19912         new_count=$((MDSCOUNT - new_index))
19913         new_hash=1 # for all_char
19914
19915         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19916         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19917
19918         test_mkdir $DIR/$tdir
19919         test_mkdir -i $old_index -c $old_count $migrate_dir
19920
19921         for ((i=0; i<100; i++)); do
19922                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19923                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19924                         error "create files under remote dir failed $i"
19925         done
19926
19927         echo -n "Migrate from MDT$old_index "
19928         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19929         echo -n "to MDT$new_index"
19930         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19931         echo
19932
19933         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19934         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19935                 error "migrate remote dir error"
19936
19937         echo "Finish migration, then checking.."
19938         for file in $(find $migrate_dir -maxdepth 1); do
19939                 mdt_index=$($LFS getstripe -m $file)
19940                 if [ $mdt_index -lt $new_index ] ||
19941                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19942                         error "$file is on MDT$mdt_index"
19943                 fi
19944         done
19945
19946         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19947 }
19948 run_test 230d "check migrate big directory"
19949
19950 test_230e() {
19951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19952         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19953         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19954                 skip "Need MDS version at least 2.11.52"
19955
19956         local i
19957         local j
19958         local a_fid
19959         local b_fid
19960
19961         mkdir_on_mdt0 $DIR/$tdir
19962         mkdir $DIR/$tdir/migrate_dir
19963         mkdir $DIR/$tdir/other_dir
19964         touch $DIR/$tdir/migrate_dir/a
19965         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19966         ls $DIR/$tdir/other_dir
19967
19968         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19969                 error "migrate dir fails"
19970
19971         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19972         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19973
19974         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19975         [ $mdt_index == 0 ] || error "a is not on MDT0"
19976
19977         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19978                 error "migrate dir fails"
19979
19980         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19981         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19982
19983         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19984         [ $mdt_index == 1 ] || error "a is not on MDT1"
19985
19986         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19987         [ $mdt_index == 1 ] || error "b is not on MDT1"
19988
19989         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19990         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19991
19992         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19993
19994         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19995 }
19996 run_test 230e "migrate mulitple local link files"
19997
19998 test_230f() {
19999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20000         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20001         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20002                 skip "Need MDS version at least 2.11.52"
20003
20004         local a_fid
20005         local ln_fid
20006
20007         mkdir -p $DIR/$tdir
20008         mkdir $DIR/$tdir/migrate_dir
20009         $LFS mkdir -i1 $DIR/$tdir/other_dir
20010         touch $DIR/$tdir/migrate_dir/a
20011         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20012         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20013         ls $DIR/$tdir/other_dir
20014
20015         # a should be migrated to MDT1, since no other links on MDT0
20016         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20017                 error "#1 migrate dir fails"
20018         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20019         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20020         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20021         [ $mdt_index == 1 ] || error "a is not on MDT1"
20022
20023         # a should stay on MDT1, because it is a mulitple link file
20024         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20025                 error "#2 migrate dir fails"
20026         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20027         [ $mdt_index == 1 ] || error "a is not on MDT1"
20028
20029         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20030                 error "#3 migrate dir fails"
20031
20032         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20033         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20034         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20035
20036         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20037         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20038
20039         # a should be migrated to MDT0, since no other links on MDT1
20040         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20041                 error "#4 migrate dir fails"
20042         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20043         [ $mdt_index == 0 ] || error "a is not on MDT0"
20044
20045         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20046 }
20047 run_test 230f "migrate mulitple remote link files"
20048
20049 test_230g() {
20050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20051         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20052         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20053                 skip "Need MDS version at least 2.11.52"
20054
20055         mkdir -p $DIR/$tdir/migrate_dir
20056
20057         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20058                 error "migrating dir to non-exist MDT succeeds"
20059         true
20060 }
20061 run_test 230g "migrate dir to non-exist MDT"
20062
20063 test_230h() {
20064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20065         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20066         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20067                 skip "Need MDS version at least 2.11.52"
20068
20069         local mdt_index
20070
20071         mkdir -p $DIR/$tdir/migrate_dir
20072
20073         $LFS migrate -m1 $DIR &&
20074                 error "migrating mountpoint1 should fail"
20075
20076         $LFS migrate -m1 $DIR/$tdir/.. &&
20077                 error "migrating mountpoint2 should fail"
20078
20079         # same as mv
20080         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20081                 error "migrating $tdir/migrate_dir/.. should fail"
20082
20083         true
20084 }
20085 run_test 230h "migrate .. and root"
20086
20087 test_230i() {
20088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20089         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20090         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20091                 skip "Need MDS version at least 2.11.52"
20092
20093         mkdir -p $DIR/$tdir/migrate_dir
20094
20095         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20096                 error "migration fails with a tailing slash"
20097
20098         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20099                 error "migration fails with two tailing slashes"
20100 }
20101 run_test 230i "lfs migrate -m tolerates trailing slashes"
20102
20103 test_230j() {
20104         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20105         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20106                 skip "Need MDS version at least 2.11.52"
20107
20108         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20109         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20110                 error "create $tfile failed"
20111         cat /etc/passwd > $DIR/$tdir/$tfile
20112
20113         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20114
20115         cmp /etc/passwd $DIR/$tdir/$tfile ||
20116                 error "DoM file mismatch after migration"
20117 }
20118 run_test 230j "DoM file data not changed after dir migration"
20119
20120 test_230k() {
20121         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20122         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20123                 skip "Need MDS version at least 2.11.56"
20124
20125         local total=20
20126         local files_on_starting_mdt=0
20127
20128         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20129         $LFS getdirstripe $DIR/$tdir
20130         for i in $(seq $total); do
20131                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20132                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20133                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20134         done
20135
20136         echo "$files_on_starting_mdt files on MDT0"
20137
20138         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20139         $LFS getdirstripe $DIR/$tdir
20140
20141         files_on_starting_mdt=0
20142         for i in $(seq $total); do
20143                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20144                         error "file $tfile.$i mismatch after migration"
20145                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20146                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20147         done
20148
20149         echo "$files_on_starting_mdt files on MDT1 after migration"
20150         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20151
20152         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20153         $LFS getdirstripe $DIR/$tdir
20154
20155         files_on_starting_mdt=0
20156         for i in $(seq $total); do
20157                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20158                         error "file $tfile.$i mismatch after 2nd migration"
20159                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20160                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20161         done
20162
20163         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20164         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20165
20166         true
20167 }
20168 run_test 230k "file data not changed after dir migration"
20169
20170 test_230l() {
20171         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20172         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20173                 skip "Need MDS version at least 2.11.56"
20174
20175         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20176         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20177                 error "create files under remote dir failed $i"
20178         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20179 }
20180 run_test 230l "readdir between MDTs won't crash"
20181
20182 test_230m() {
20183         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20184         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20185                 skip "Need MDS version at least 2.11.56"
20186
20187         local MDTIDX=1
20188         local mig_dir=$DIR/$tdir/migrate_dir
20189         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20190         local shortstr="b"
20191         local val
20192
20193         echo "Creating files and dirs with xattrs"
20194         test_mkdir $DIR/$tdir
20195         test_mkdir -i0 -c1 $mig_dir
20196         mkdir $mig_dir/dir
20197         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20198                 error "cannot set xattr attr1 on dir"
20199         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20200                 error "cannot set xattr attr2 on dir"
20201         touch $mig_dir/dir/f0
20202         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20203                 error "cannot set xattr attr1 on file"
20204         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20205                 error "cannot set xattr attr2 on file"
20206         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20207         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20208         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20209         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20210         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20211         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20212         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20213         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20214         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20215
20216         echo "Migrating to MDT1"
20217         $LFS migrate -m $MDTIDX $mig_dir ||
20218                 error "fails on migrating dir to MDT1"
20219
20220         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20221         echo "Checking xattrs"
20222         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20223         [ "$val" = $longstr ] ||
20224                 error "expecting xattr1 $longstr on dir, found $val"
20225         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20226         [ "$val" = $shortstr ] ||
20227                 error "expecting xattr2 $shortstr on dir, found $val"
20228         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20229         [ "$val" = $longstr ] ||
20230                 error "expecting xattr1 $longstr on file, found $val"
20231         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20232         [ "$val" = $shortstr ] ||
20233                 error "expecting xattr2 $shortstr on file, found $val"
20234 }
20235 run_test 230m "xattrs not changed after dir migration"
20236
20237 test_230n() {
20238         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20239         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20240                 skip "Need MDS version at least 2.13.53"
20241
20242         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20243         cat /etc/hosts > $DIR/$tdir/$tfile
20244         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20245         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20246
20247         cmp /etc/hosts $DIR/$tdir/$tfile ||
20248                 error "File data mismatch after migration"
20249 }
20250 run_test 230n "Dir migration with mirrored file"
20251
20252 test_230o() {
20253         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20254         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20255                 skip "Need MDS version at least 2.13.52"
20256
20257         local mdts=$(comma_list $(mdts_nodes))
20258         local timeout=100
20259         local restripe_status
20260         local delta
20261         local i
20262
20263         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20264
20265         # in case "crush" hash type is not set
20266         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20267
20268         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20269                            mdt.*MDT0000.enable_dir_restripe)
20270         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20271         stack_trap "do_nodes $mdts $LCTL set_param \
20272                     mdt.*.enable_dir_restripe=$restripe_status"
20273
20274         mkdir $DIR/$tdir
20275         createmany -m $DIR/$tdir/f 100 ||
20276                 error "create files under remote dir failed $i"
20277         createmany -d $DIR/$tdir/d 100 ||
20278                 error "create dirs under remote dir failed $i"
20279
20280         for i in $(seq 2 $MDSCOUNT); do
20281                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20282                 $LFS setdirstripe -c $i $DIR/$tdir ||
20283                         error "split -c $i $tdir failed"
20284                 wait_update $HOSTNAME \
20285                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20286                         error "dir split not finished"
20287                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20288                         awk '/migrate/ {sum += $2} END { print sum }')
20289                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20290                 # delta is around total_files/stripe_count
20291                 (( $delta < 200 / (i - 1) + 4 )) ||
20292                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20293         done
20294 }
20295 run_test 230o "dir split"
20296
20297 test_230p() {
20298         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20299         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20300                 skip "Need MDS version at least 2.13.52"
20301
20302         local mdts=$(comma_list $(mdts_nodes))
20303         local timeout=100
20304         local restripe_status
20305         local delta
20306         local c
20307
20308         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20309
20310         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20311
20312         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20313                            mdt.*MDT0000.enable_dir_restripe)
20314         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20315         stack_trap "do_nodes $mdts $LCTL set_param \
20316                     mdt.*.enable_dir_restripe=$restripe_status"
20317
20318         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20319         createmany -m $DIR/$tdir/f 100 ||
20320                 error "create files under remote dir failed"
20321         createmany -d $DIR/$tdir/d 100 ||
20322                 error "create dirs under remote dir failed"
20323
20324         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20325                 local mdt_hash="crush"
20326
20327                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20328                 $LFS setdirstripe -c $c $DIR/$tdir ||
20329                         error "split -c $c $tdir failed"
20330                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20331                         mdt_hash="$mdt_hash,fixed"
20332                 elif [ $c -eq 1 ]; then
20333                         mdt_hash="none"
20334                 fi
20335                 wait_update $HOSTNAME \
20336                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20337                         error "dir merge not finished"
20338                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20339                         awk '/migrate/ {sum += $2} END { print sum }')
20340                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20341                 # delta is around total_files/stripe_count
20342                 (( delta < 200 / c + 4 )) ||
20343                         error "$delta files migrated >= $((200 / c + 4))"
20344         done
20345 }
20346 run_test 230p "dir merge"
20347
20348 test_230q() {
20349         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20350         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20351                 skip "Need MDS version at least 2.13.52"
20352
20353         local mdts=$(comma_list $(mdts_nodes))
20354         local saved_threshold=$(do_facet mds1 \
20355                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20356         local saved_delta=$(do_facet mds1 \
20357                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20358         local threshold=100
20359         local delta=2
20360         local total=0
20361         local stripe_count=0
20362         local stripe_index
20363         local nr_files
20364         local create
20365
20366         # test with fewer files on ZFS
20367         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20368
20369         stack_trap "do_nodes $mdts $LCTL set_param \
20370                     mdt.*.dir_split_count=$saved_threshold"
20371         stack_trap "do_nodes $mdts $LCTL set_param \
20372                     mdt.*.dir_split_delta=$saved_delta"
20373         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20374         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20375         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20376         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20377         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20378         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20379
20380         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20381         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20382
20383         create=$((threshold * 3 / 2))
20384         while [ $stripe_count -lt $MDSCOUNT ]; do
20385                 createmany -m $DIR/$tdir/f $total $create ||
20386                         error "create sub files failed"
20387                 stat $DIR/$tdir > /dev/null
20388                 total=$((total + create))
20389                 stripe_count=$((stripe_count + delta))
20390                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20391
20392                 wait_update $HOSTNAME \
20393                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20394                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20395
20396                 wait_update $HOSTNAME \
20397                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20398                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20399
20400                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20401                 echo "$nr_files/$total files on MDT$stripe_index after split"
20402                 # allow 10% margin of imbalance with crush hash
20403                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20404                         error "$nr_files files on MDT$stripe_index after split"
20405
20406                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20407                 [ $nr_files -eq $total ] ||
20408                         error "total sub files $nr_files != $total"
20409         done
20410
20411         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20412
20413         echo "fixed layout directory won't auto split"
20414         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20415         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20416                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20417         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20418                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20419 }
20420 run_test 230q "dir auto split"
20421
20422 test_230r() {
20423         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20424         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20425         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20426                 skip "Need MDS version at least 2.13.54"
20427
20428         # maximum amount of local locks:
20429         # parent striped dir - 2 locks
20430         # new stripe in parent to migrate to - 1 lock
20431         # source and target - 2 locks
20432         # Total 5 locks for regular file
20433         mkdir -p $DIR/$tdir
20434         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20435         touch $DIR/$tdir/dir1/eee
20436
20437         # create 4 hardlink for 4 more locks
20438         # Total: 9 locks > RS_MAX_LOCKS (8)
20439         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20440         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20441         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20442         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20443         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20444         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20445         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20446         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20447
20448         cancel_lru_locks mdc
20449
20450         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20451                 error "migrate dir fails"
20452
20453         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20454 }
20455 run_test 230r "migrate with too many local locks"
20456
20457 test_230s() {
20458         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
20459                 skip "Need MDS version at least 2.14.52"
20460
20461         local mdts=$(comma_list $(mdts_nodes))
20462         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20463                                 mdt.*MDT0000.enable_dir_restripe)
20464
20465         stack_trap "do_nodes $mdts $LCTL set_param \
20466                     mdt.*.enable_dir_restripe=$restripe_status"
20467
20468         local st
20469         for st in 0 1; do
20470                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20471                 test_mkdir $DIR/$tdir
20472                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20473                         error "$LFS mkdir should return EEXIST if target exists"
20474                 rmdir $DIR/$tdir
20475         done
20476 }
20477 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20478
20479 test_230t()
20480 {
20481         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20482         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20483                 skip "Need MDS version at least 2.14.50"
20484
20485         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20486         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20487         $LFS project -p 1 -s $DIR/$tdir ||
20488                 error "set $tdir project id failed"
20489         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20490                 error "set subdir project id failed"
20491         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20492 }
20493 run_test 230t "migrate directory with project ID set"
20494
20495 test_230u()
20496 {
20497         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20498         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20499                 skip "Need MDS version at least 2.14.53"
20500
20501         local count
20502
20503         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20504         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20505         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20506         for i in $(seq 0 $((MDSCOUNT - 1))); do
20507                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20508                 echo "$count dirs migrated to MDT$i"
20509         done
20510         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20511         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20512 }
20513 run_test 230u "migrate directory by QOS"
20514
20515 test_230v()
20516 {
20517         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20518         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20519                 skip "Need MDS version at least 2.14.53"
20520
20521         local count
20522
20523         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20524         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20525         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20526         for i in $(seq 0 $((MDSCOUNT - 1))); do
20527                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20528                 echo "$count subdirs migrated to MDT$i"
20529                 (( i == 3 )) && (( count > 0 )) &&
20530                         error "subdir shouldn't be migrated to MDT3"
20531         done
20532         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20533         (( count == 3 )) || error "dirs migrated to $count MDTs"
20534 }
20535 run_test 230v "subdir migrated to the MDT where its parent is located"
20536
20537 test_230w() {
20538         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20539         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20540                 skip "Need MDS version at least 2.14.53"
20541
20542         mkdir -p $DIR/$tdir/sub || error "mkdir failed"
20543
20544         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
20545                 error "migrate failed"
20546
20547         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
20548                 error "$tdir stripe count mismatch"
20549
20550         (( $($LFS getdirstripe -c $DIR/$tdir/sub) == 0 )) ||
20551                 error "$tdir/sub is striped"
20552 }
20553 run_test 230w "non-recursive mode dir migration"
20554
20555 test_231a()
20556 {
20557         # For simplicity this test assumes that max_pages_per_rpc
20558         # is the same across all OSCs
20559         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20560         local bulk_size=$((max_pages * PAGE_SIZE))
20561         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20562                                        head -n 1)
20563
20564         mkdir -p $DIR/$tdir
20565         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20566                 error "failed to set stripe with -S ${brw_size}M option"
20567
20568         # clear the OSC stats
20569         $LCTL set_param osc.*.stats=0 &>/dev/null
20570         stop_writeback
20571
20572         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20573         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20574                 oflag=direct &>/dev/null || error "dd failed"
20575
20576         sync; sleep 1; sync # just to be safe
20577         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20578         if [ x$nrpcs != "x1" ]; then
20579                 $LCTL get_param osc.*.stats
20580                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20581         fi
20582
20583         start_writeback
20584         # Drop the OSC cache, otherwise we will read from it
20585         cancel_lru_locks osc
20586
20587         # clear the OSC stats
20588         $LCTL set_param osc.*.stats=0 &>/dev/null
20589
20590         # Client reads $bulk_size.
20591         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20592                 iflag=direct &>/dev/null || error "dd failed"
20593
20594         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20595         if [ x$nrpcs != "x1" ]; then
20596                 $LCTL get_param osc.*.stats
20597                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20598         fi
20599 }
20600 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20601
20602 test_231b() {
20603         mkdir -p $DIR/$tdir
20604         local i
20605         for i in {0..1023}; do
20606                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20607                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20608                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20609         done
20610         sync
20611 }
20612 run_test 231b "must not assert on fully utilized OST request buffer"
20613
20614 test_232a() {
20615         mkdir -p $DIR/$tdir
20616         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20617
20618         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20619         do_facet ost1 $LCTL set_param fail_loc=0x31c
20620
20621         # ignore dd failure
20622         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20623
20624         do_facet ost1 $LCTL set_param fail_loc=0
20625         umount_client $MOUNT || error "umount failed"
20626         mount_client $MOUNT || error "mount failed"
20627         stop ost1 || error "cannot stop ost1"
20628         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20629 }
20630 run_test 232a "failed lock should not block umount"
20631
20632 test_232b() {
20633         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20634                 skip "Need MDS version at least 2.10.58"
20635
20636         mkdir -p $DIR/$tdir
20637         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20638         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20639         sync
20640         cancel_lru_locks osc
20641
20642         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20643         do_facet ost1 $LCTL set_param fail_loc=0x31c
20644
20645         # ignore failure
20646         $LFS data_version $DIR/$tdir/$tfile || true
20647
20648         do_facet ost1 $LCTL set_param fail_loc=0
20649         umount_client $MOUNT || error "umount failed"
20650         mount_client $MOUNT || error "mount failed"
20651         stop ost1 || error "cannot stop ost1"
20652         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20653 }
20654 run_test 232b "failed data version lock should not block umount"
20655
20656 test_233a() {
20657         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20658                 skip "Need MDS version at least 2.3.64"
20659         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20660
20661         local fid=$($LFS path2fid $MOUNT)
20662
20663         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20664                 error "cannot access $MOUNT using its FID '$fid'"
20665 }
20666 run_test 233a "checking that OBF of the FS root succeeds"
20667
20668 test_233b() {
20669         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20670                 skip "Need MDS version at least 2.5.90"
20671         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20672
20673         local fid=$($LFS path2fid $MOUNT/.lustre)
20674
20675         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20676                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20677
20678         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20679         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20680                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20681 }
20682 run_test 233b "checking that OBF of the FS .lustre succeeds"
20683
20684 test_234() {
20685         local p="$TMP/sanityN-$TESTNAME.parameters"
20686         save_lustre_params client "llite.*.xattr_cache" > $p
20687         lctl set_param llite.*.xattr_cache 1 ||
20688                 skip_env "xattr cache is not supported"
20689
20690         mkdir -p $DIR/$tdir || error "mkdir failed"
20691         touch $DIR/$tdir/$tfile || error "touch failed"
20692         # OBD_FAIL_LLITE_XATTR_ENOMEM
20693         $LCTL set_param fail_loc=0x1405
20694         getfattr -n user.attr $DIR/$tdir/$tfile &&
20695                 error "getfattr should have failed with ENOMEM"
20696         $LCTL set_param fail_loc=0x0
20697         rm -rf $DIR/$tdir
20698
20699         restore_lustre_params < $p
20700         rm -f $p
20701 }
20702 run_test 234 "xattr cache should not crash on ENOMEM"
20703
20704 test_235() {
20705         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20706                 skip "Need MDS version at least 2.4.52"
20707
20708         flock_deadlock $DIR/$tfile
20709         local RC=$?
20710         case $RC in
20711                 0)
20712                 ;;
20713                 124) error "process hangs on a deadlock"
20714                 ;;
20715                 *) error "error executing flock_deadlock $DIR/$tfile"
20716                 ;;
20717         esac
20718 }
20719 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20720
20721 #LU-2935
20722 test_236() {
20723         check_swap_layouts_support
20724
20725         local ref1=/etc/passwd
20726         local ref2=/etc/group
20727         local file1=$DIR/$tdir/f1
20728         local file2=$DIR/$tdir/f2
20729
20730         test_mkdir -c1 $DIR/$tdir
20731         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20732         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20733         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20734         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20735         local fd=$(free_fd)
20736         local cmd="exec $fd<>$file2"
20737         eval $cmd
20738         rm $file2
20739         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20740                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20741         cmd="exec $fd>&-"
20742         eval $cmd
20743         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20744
20745         #cleanup
20746         rm -rf $DIR/$tdir
20747 }
20748 run_test 236 "Layout swap on open unlinked file"
20749
20750 # LU-4659 linkea consistency
20751 test_238() {
20752         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20753                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20754                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20755                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20756
20757         touch $DIR/$tfile
20758         ln $DIR/$tfile $DIR/$tfile.lnk
20759         touch $DIR/$tfile.new
20760         mv $DIR/$tfile.new $DIR/$tfile
20761         local fid1=$($LFS path2fid $DIR/$tfile)
20762         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20763         local path1=$($LFS fid2path $FSNAME "$fid1")
20764         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20765         local path2=$($LFS fid2path $FSNAME "$fid2")
20766         [ $tfile.lnk == $path2 ] ||
20767                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20768         rm -f $DIR/$tfile*
20769 }
20770 run_test 238 "Verify linkea consistency"
20771
20772 test_239A() { # was test_239
20773         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20774                 skip "Need MDS version at least 2.5.60"
20775
20776         local list=$(comma_list $(mdts_nodes))
20777
20778         mkdir -p $DIR/$tdir
20779         createmany -o $DIR/$tdir/f- 5000
20780         unlinkmany $DIR/$tdir/f- 5000
20781         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20782                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20783         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20784                         osp.*MDT*.sync_in_flight" | calc_sum)
20785         [ "$changes" -eq 0 ] || error "$changes not synced"
20786 }
20787 run_test 239A "osp_sync test"
20788
20789 test_239a() { #LU-5297
20790         remote_mds_nodsh && skip "remote MDS with nodsh"
20791
20792         touch $DIR/$tfile
20793         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20794         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20795         chgrp $RUNAS_GID $DIR/$tfile
20796         wait_delete_completed
20797 }
20798 run_test 239a "process invalid osp sync record correctly"
20799
20800 test_239b() { #LU-5297
20801         remote_mds_nodsh && skip "remote MDS with nodsh"
20802
20803         touch $DIR/$tfile1
20804         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20805         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20806         chgrp $RUNAS_GID $DIR/$tfile1
20807         wait_delete_completed
20808         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20809         touch $DIR/$tfile2
20810         chgrp $RUNAS_GID $DIR/$tfile2
20811         wait_delete_completed
20812 }
20813 run_test 239b "process osp sync record with ENOMEM error correctly"
20814
20815 test_240() {
20816         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20817         remote_mds_nodsh && skip "remote MDS with nodsh"
20818
20819         mkdir -p $DIR/$tdir
20820
20821         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20822                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20823         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20824                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20825
20826         umount_client $MOUNT || error "umount failed"
20827         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20828         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20829         mount_client $MOUNT || error "failed to mount client"
20830
20831         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20832         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20833 }
20834 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20835
20836 test_241_bio() {
20837         local count=$1
20838         local bsize=$2
20839
20840         for LOOP in $(seq $count); do
20841                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20842                 cancel_lru_locks $OSC || true
20843         done
20844 }
20845
20846 test_241_dio() {
20847         local count=$1
20848         local bsize=$2
20849
20850         for LOOP in $(seq $1); do
20851                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20852                         2>/dev/null
20853         done
20854 }
20855
20856 test_241a() { # was test_241
20857         local bsize=$PAGE_SIZE
20858
20859         (( bsize < 40960 )) && bsize=40960
20860         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20861         ls -la $DIR/$tfile
20862         cancel_lru_locks $OSC
20863         test_241_bio 1000 $bsize &
20864         PID=$!
20865         test_241_dio 1000 $bsize
20866         wait $PID
20867 }
20868 run_test 241a "bio vs dio"
20869
20870 test_241b() {
20871         local bsize=$PAGE_SIZE
20872
20873         (( bsize < 40960 )) && bsize=40960
20874         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20875         ls -la $DIR/$tfile
20876         test_241_dio 1000 $bsize &
20877         PID=$!
20878         test_241_dio 1000 $bsize
20879         wait $PID
20880 }
20881 run_test 241b "dio vs dio"
20882
20883 test_242() {
20884         remote_mds_nodsh && skip "remote MDS with nodsh"
20885
20886         mkdir_on_mdt0 $DIR/$tdir
20887         touch $DIR/$tdir/$tfile
20888
20889         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20890         do_facet mds1 lctl set_param fail_loc=0x105
20891         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20892
20893         do_facet mds1 lctl set_param fail_loc=0
20894         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20895 }
20896 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20897
20898 test_243()
20899 {
20900         test_mkdir $DIR/$tdir
20901         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20902 }
20903 run_test 243 "various group lock tests"
20904
20905 test_244a()
20906 {
20907         test_mkdir $DIR/$tdir
20908         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20909         sendfile_grouplock $DIR/$tdir/$tfile || \
20910                 error "sendfile+grouplock failed"
20911         rm -rf $DIR/$tdir
20912 }
20913 run_test 244a "sendfile with group lock tests"
20914
20915 test_244b()
20916 {
20917         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20918
20919         local threads=50
20920         local size=$((1024*1024))
20921
20922         test_mkdir $DIR/$tdir
20923         for i in $(seq 1 $threads); do
20924                 local file=$DIR/$tdir/file_$((i / 10))
20925                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20926                 local pids[$i]=$!
20927         done
20928         for i in $(seq 1 $threads); do
20929                 wait ${pids[$i]}
20930         done
20931 }
20932 run_test 244b "multi-threaded write with group lock"
20933
20934 test_245a() {
20935         local flagname="multi_mod_rpcs"
20936         local connect_data_name="max_mod_rpcs"
20937         local out
20938
20939         # check if multiple modify RPCs flag is set
20940         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20941                 grep "connect_flags:")
20942         echo "$out"
20943
20944         echo "$out" | grep -qw $flagname
20945         if [ $? -ne 0 ]; then
20946                 echo "connect flag $flagname is not set"
20947                 return
20948         fi
20949
20950         # check if multiple modify RPCs data is set
20951         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20952         echo "$out"
20953
20954         echo "$out" | grep -qw $connect_data_name ||
20955                 error "import should have connect data $connect_data_name"
20956 }
20957 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
20958
20959 test_245b() {
20960         local flagname="multi_mod_rpcs"
20961         local connect_data_name="max_mod_rpcs"
20962         local out
20963
20964         remote_mds_nodsh && skip "remote MDS with nodsh"
20965         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
20966
20967         # check if multiple modify RPCs flag is set
20968         out=$(do_facet mds1 \
20969               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
20970               grep "connect_flags:")
20971         echo "$out"
20972
20973         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
20974
20975         # check if multiple modify RPCs data is set
20976         out=$(do_facet mds1 \
20977               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
20978
20979         [[ "$out" =~ $connect_data_name ]] ||
20980                 {
20981                         echo "$out"
20982                         error "missing connect data $connect_data_name"
20983                 }
20984 }
20985 run_test 245b "check osp connection flag/data: multiple modify RPCs"
20986
20987 cleanup_247() {
20988         local submount=$1
20989
20990         trap 0
20991         umount_client $submount
20992         rmdir $submount
20993 }
20994
20995 test_247a() {
20996         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20997                 grep -q subtree ||
20998                 skip_env "Fileset feature is not supported"
20999
21000         local submount=${MOUNT}_$tdir
21001
21002         mkdir $MOUNT/$tdir
21003         mkdir -p $submount || error "mkdir $submount failed"
21004         FILESET="$FILESET/$tdir" mount_client $submount ||
21005                 error "mount $submount failed"
21006         trap "cleanup_247 $submount" EXIT
21007         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21008         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21009                 error "read $MOUNT/$tdir/$tfile failed"
21010         cleanup_247 $submount
21011 }
21012 run_test 247a "mount subdir as fileset"
21013
21014 test_247b() {
21015         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21016                 skip_env "Fileset feature is not supported"
21017
21018         local submount=${MOUNT}_$tdir
21019
21020         rm -rf $MOUNT/$tdir
21021         mkdir -p $submount || error "mkdir $submount failed"
21022         SKIP_FILESET=1
21023         FILESET="$FILESET/$tdir" mount_client $submount &&
21024                 error "mount $submount should fail"
21025         rmdir $submount
21026 }
21027 run_test 247b "mount subdir that dose not exist"
21028
21029 test_247c() {
21030         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21031                 skip_env "Fileset feature is not supported"
21032
21033         local submount=${MOUNT}_$tdir
21034
21035         mkdir -p $MOUNT/$tdir/dir1
21036         mkdir -p $submount || error "mkdir $submount failed"
21037         trap "cleanup_247 $submount" EXIT
21038         FILESET="$FILESET/$tdir" mount_client $submount ||
21039                 error "mount $submount failed"
21040         local fid=$($LFS path2fid $MOUNT/)
21041         $LFS fid2path $submount $fid && error "fid2path should fail"
21042         cleanup_247 $submount
21043 }
21044 run_test 247c "running fid2path outside subdirectory root"
21045
21046 test_247d() {
21047         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21048                 skip "Fileset feature is not supported"
21049
21050         local submount=${MOUNT}_$tdir
21051
21052         mkdir -p $MOUNT/$tdir/dir1
21053         mkdir -p $submount || error "mkdir $submount failed"
21054         FILESET="$FILESET/$tdir" mount_client $submount ||
21055                 error "mount $submount failed"
21056         trap "cleanup_247 $submount" EXIT
21057
21058         local td=$submount/dir1
21059         local fid=$($LFS path2fid $td)
21060         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21061
21062         # check that we get the same pathname back
21063         local rootpath
21064         local found
21065         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21066                 echo "$rootpath $fid"
21067                 found=$($LFS fid2path $rootpath "$fid")
21068                 [ -n "$found" ] || error "fid2path should succeed"
21069                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21070         done
21071         # check wrong root path format
21072         rootpath=$submount"_wrong"
21073         found=$($LFS fid2path $rootpath "$fid")
21074         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21075
21076         cleanup_247 $submount
21077 }
21078 run_test 247d "running fid2path inside subdirectory root"
21079
21080 # LU-8037
21081 test_247e() {
21082         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21083                 grep -q subtree ||
21084                 skip "Fileset feature is not supported"
21085
21086         local submount=${MOUNT}_$tdir
21087
21088         mkdir $MOUNT/$tdir
21089         mkdir -p $submount || error "mkdir $submount failed"
21090         FILESET="$FILESET/.." mount_client $submount &&
21091                 error "mount $submount should fail"
21092         rmdir $submount
21093 }
21094 run_test 247e "mount .. as fileset"
21095
21096 test_247f() {
21097         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21098         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21099                 skip "Need at least version 2.13.52"
21100         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21101                 skip "Need at least version 2.14.50"
21102         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21103                 grep -q subtree ||
21104                 skip "Fileset feature is not supported"
21105
21106         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21107         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21108                 error "mkdir remote failed"
21109         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21110                 error "mkdir remote/subdir failed"
21111         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21112                 error "mkdir striped failed"
21113         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21114
21115         local submount=${MOUNT}_$tdir
21116
21117         mkdir -p $submount || error "mkdir $submount failed"
21118         stack_trap "rmdir $submount"
21119
21120         local dir
21121         local stat
21122         local fileset=$FILESET
21123         local mdts=$(comma_list $(mdts_nodes))
21124
21125         stat=$(do_facet mds1 $LCTL get_param -n \
21126                 mdt.*MDT0000.enable_remote_subdir_mount)
21127         stack_trap "do_nodes $mdts $LCTL set_param \
21128                 mdt.*.enable_remote_subdir_mount=$stat"
21129
21130         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21131         stack_trap "umount_client $submount"
21132         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21133                 error "mount remote dir $dir should fail"
21134
21135         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21136                 $tdir/striped/. ; do
21137                 FILESET="$fileset/$dir" mount_client $submount ||
21138                         error "mount $dir failed"
21139                 umount_client $submount
21140         done
21141
21142         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21143         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21144                 error "mount $tdir/remote failed"
21145 }
21146 run_test 247f "mount striped or remote directory as fileset"
21147
21148 test_247g() {
21149         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21150         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21151                 skip "Need at least version 2.14.50"
21152
21153         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21154                 error "mkdir $tdir failed"
21155         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21156
21157         local submount=${MOUNT}_$tdir
21158
21159         mkdir -p $submount || error "mkdir $submount failed"
21160         stack_trap "rmdir $submount"
21161
21162         FILESET="$fileset/$tdir" mount_client $submount ||
21163                 error "mount $dir failed"
21164         stack_trap "umount $submount"
21165
21166         local mdts=$(comma_list $(mdts_nodes))
21167
21168         local nrpcs
21169
21170         stat $submount > /dev/null
21171         cancel_lru_locks $MDC
21172         stat $submount > /dev/null
21173         stat $submount/$tfile > /dev/null
21174         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21175         stat $submount/$tfile > /dev/null
21176         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21177                 awk '/getattr/ {sum += $2} END {print sum}')
21178
21179         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21180 }
21181 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21182
21183 test_248a() {
21184         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21185         [ -z "$fast_read_sav" ] && skip "no fast read support"
21186
21187         # create a large file for fast read verification
21188         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21189
21190         # make sure the file is created correctly
21191         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21192                 { rm -f $DIR/$tfile; skip "file creation error"; }
21193
21194         echo "Test 1: verify that fast read is 4 times faster on cache read"
21195
21196         # small read with fast read enabled
21197         $LCTL set_param -n llite.*.fast_read=1
21198         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21199                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21200                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21201         # small read with fast read disabled
21202         $LCTL set_param -n llite.*.fast_read=0
21203         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21204                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21205                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21206
21207         # verify that fast read is 4 times faster for cache read
21208         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21209                 error_not_in_vm "fast read was not 4 times faster: " \
21210                            "$t_fast vs $t_slow"
21211
21212         echo "Test 2: verify the performance between big and small read"
21213         $LCTL set_param -n llite.*.fast_read=1
21214
21215         # 1k non-cache read
21216         cancel_lru_locks osc
21217         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21218                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21219                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21220
21221         # 1M non-cache read
21222         cancel_lru_locks osc
21223         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21224                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21225                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21226
21227         # verify that big IO is not 4 times faster than small IO
21228         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21229                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21230
21231         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21232         rm -f $DIR/$tfile
21233 }
21234 run_test 248a "fast read verification"
21235
21236 test_248b() {
21237         # Default short_io_bytes=16384, try both smaller and larger sizes.
21238         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21239         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21240         echo "bs=53248 count=113 normal buffered write"
21241         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21242                 error "dd of initial data file failed"
21243         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21244
21245         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21246         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21247                 error "dd with sync normal writes failed"
21248         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21249
21250         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21251         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21252                 error "dd with sync small writes failed"
21253         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21254
21255         cancel_lru_locks osc
21256
21257         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21258         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21259         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21260         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21261                 iflag=direct || error "dd with O_DIRECT small read failed"
21262         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21263         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21264                 error "compare $TMP/$tfile.1 failed"
21265
21266         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21267         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21268
21269         # just to see what the maximum tunable value is, and test parsing
21270         echo "test invalid parameter 2MB"
21271         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21272                 error "too-large short_io_bytes allowed"
21273         echo "test maximum parameter 512KB"
21274         # if we can set a larger short_io_bytes, run test regardless of version
21275         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21276                 # older clients may not allow setting it this large, that's OK
21277                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21278                         skip "Need at least client version 2.13.50"
21279                 error "medium short_io_bytes failed"
21280         fi
21281         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21282         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21283
21284         echo "test large parameter 64KB"
21285         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21286         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21287
21288         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21289         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21290                 error "dd with sync large writes failed"
21291         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21292
21293         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21294         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21295         num=$((113 * 4096 / PAGE_SIZE))
21296         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21297         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21298                 error "dd with O_DIRECT large writes failed"
21299         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21300                 error "compare $DIR/$tfile.3 failed"
21301
21302         cancel_lru_locks osc
21303
21304         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21305         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21306                 error "dd with O_DIRECT large read failed"
21307         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21308                 error "compare $TMP/$tfile.2 failed"
21309
21310         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21311         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21312                 error "dd with O_DIRECT large read failed"
21313         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21314                 error "compare $TMP/$tfile.3 failed"
21315 }
21316 run_test 248b "test short_io read and write for both small and large sizes"
21317
21318 test_249() { # LU-7890
21319         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21320                 skip "Need at least version 2.8.54"
21321
21322         rm -f $DIR/$tfile
21323         $LFS setstripe -c 1 $DIR/$tfile
21324         # Offset 2T == 4k * 512M
21325         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21326                 error "dd to 2T offset failed"
21327 }
21328 run_test 249 "Write above 2T file size"
21329
21330 test_250() {
21331         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21332          && skip "no 16TB file size limit on ZFS"
21333
21334         $LFS setstripe -c 1 $DIR/$tfile
21335         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21336         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21337         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21338         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21339                 conv=notrunc,fsync && error "append succeeded"
21340         return 0
21341 }
21342 run_test 250 "Write above 16T limit"
21343
21344 test_251() {
21345         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21346
21347         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21348         #Skip once - writing the first stripe will succeed
21349         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21350         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21351                 error "short write happened"
21352
21353         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21354         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21355                 error "short read happened"
21356
21357         rm -f $DIR/$tfile
21358 }
21359 run_test 251 "Handling short read and write correctly"
21360
21361 test_252() {
21362         remote_mds_nodsh && skip "remote MDS with nodsh"
21363         remote_ost_nodsh && skip "remote OST with nodsh"
21364         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21365                 skip_env "ldiskfs only test"
21366         fi
21367
21368         local tgt
21369         local dev
21370         local out
21371         local uuid
21372         local num
21373         local gen
21374
21375         # check lr_reader on OST0000
21376         tgt=ost1
21377         dev=$(facet_device $tgt)
21378         out=$(do_facet $tgt $LR_READER $dev)
21379         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21380         echo "$out"
21381         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21382         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21383                 error "Invalid uuid returned by $LR_READER on target $tgt"
21384         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21385
21386         # check lr_reader -c on MDT0000
21387         tgt=mds1
21388         dev=$(facet_device $tgt)
21389         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21390                 skip "$LR_READER does not support additional options"
21391         fi
21392         out=$(do_facet $tgt $LR_READER -c $dev)
21393         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21394         echo "$out"
21395         num=$(echo "$out" | grep -c "mdtlov")
21396         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21397                 error "Invalid number of mdtlov clients returned by $LR_READER"
21398         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21399
21400         # check lr_reader -cr on MDT0000
21401         out=$(do_facet $tgt $LR_READER -cr $dev)
21402         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21403         echo "$out"
21404         echo "$out" | grep -q "^reply_data:$" ||
21405                 error "$LR_READER should have returned 'reply_data' section"
21406         num=$(echo "$out" | grep -c "client_generation")
21407         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21408 }
21409 run_test 252 "check lr_reader tool"
21410
21411 test_253() {
21412         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21413         remote_mds_nodsh && skip "remote MDS with nodsh"
21414         remote_mgs_nodsh && skip "remote MGS with nodsh"
21415
21416         local ostidx=0
21417         local rc=0
21418         local ost_name=$(ostname_from_index $ostidx)
21419
21420         # on the mdt's osc
21421         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21422         do_facet $SINGLEMDS $LCTL get_param -n \
21423                 osp.$mdtosc_proc1.reserved_mb_high ||
21424                 skip  "remote MDS does not support reserved_mb_high"
21425
21426         rm -rf $DIR/$tdir
21427         wait_mds_ost_sync
21428         wait_delete_completed
21429         mkdir $DIR/$tdir
21430
21431         pool_add $TESTNAME || error "Pool creation failed"
21432         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21433
21434         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21435                 error "Setstripe failed"
21436
21437         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21438
21439         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21440                     grep "watermarks")
21441         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21442
21443         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21444                         osp.$mdtosc_proc1.prealloc_status)
21445         echo "prealloc_status $oa_status"
21446
21447         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21448                 error "File creation should fail"
21449
21450         #object allocation was stopped, but we still able to append files
21451         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21452                 oflag=append || error "Append failed"
21453
21454         rm -f $DIR/$tdir/$tfile.0
21455
21456         # For this test, we want to delete the files we created to go out of
21457         # space but leave the watermark, so we remain nearly out of space
21458         ost_watermarks_enospc_delete_files $tfile $ostidx
21459
21460         wait_delete_completed
21461
21462         sleep_maxage
21463
21464         for i in $(seq 10 12); do
21465                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21466                         2>/dev/null || error "File creation failed after rm"
21467         done
21468
21469         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21470                         osp.$mdtosc_proc1.prealloc_status)
21471         echo "prealloc_status $oa_status"
21472
21473         if (( oa_status != 0 )); then
21474                 error "Object allocation still disable after rm"
21475         fi
21476 }
21477 run_test 253 "Check object allocation limit"
21478
21479 test_254() {
21480         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21481         remote_mds_nodsh && skip "remote MDS with nodsh"
21482
21483         local mdt=$(facet_svc $SINGLEMDS)
21484
21485         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21486                 skip "MDS does not support changelog_size"
21487
21488         local cl_user
21489
21490         changelog_register || error "changelog_register failed"
21491
21492         changelog_clear 0 || error "changelog_clear failed"
21493
21494         local size1=$(do_facet $SINGLEMDS \
21495                       $LCTL get_param -n mdd.$mdt.changelog_size)
21496         echo "Changelog size $size1"
21497
21498         rm -rf $DIR/$tdir
21499         $LFS mkdir -i 0 $DIR/$tdir
21500         # change something
21501         mkdir -p $DIR/$tdir/pics/2008/zachy
21502         touch $DIR/$tdir/pics/2008/zachy/timestamp
21503         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21504         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21505         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21506         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21507         rm $DIR/$tdir/pics/desktop.jpg
21508
21509         local size2=$(do_facet $SINGLEMDS \
21510                       $LCTL get_param -n mdd.$mdt.changelog_size)
21511         echo "Changelog size after work $size2"
21512
21513         (( $size2 > $size1 )) ||
21514                 error "new Changelog size=$size2 less than old size=$size1"
21515 }
21516 run_test 254 "Check changelog size"
21517
21518 ladvise_no_type()
21519 {
21520         local type=$1
21521         local file=$2
21522
21523         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21524                 awk -F: '{print $2}' | grep $type > /dev/null
21525         if [ $? -ne 0 ]; then
21526                 return 0
21527         fi
21528         return 1
21529 }
21530
21531 ladvise_no_ioctl()
21532 {
21533         local file=$1
21534
21535         lfs ladvise -a willread $file > /dev/null 2>&1
21536         if [ $? -eq 0 ]; then
21537                 return 1
21538         fi
21539
21540         lfs ladvise -a willread $file 2>&1 |
21541                 grep "Inappropriate ioctl for device" > /dev/null
21542         if [ $? -eq 0 ]; then
21543                 return 0
21544         fi
21545         return 1
21546 }
21547
21548 percent() {
21549         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21550 }
21551
21552 # run a random read IO workload
21553 # usage: random_read_iops <filename> <filesize> <iosize>
21554 random_read_iops() {
21555         local file=$1
21556         local fsize=$2
21557         local iosize=${3:-4096}
21558
21559         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21560                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21561 }
21562
21563 drop_file_oss_cache() {
21564         local file="$1"
21565         local nodes="$2"
21566
21567         $LFS ladvise -a dontneed $file 2>/dev/null ||
21568                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21569 }
21570
21571 ladvise_willread_performance()
21572 {
21573         local repeat=10
21574         local average_origin=0
21575         local average_cache=0
21576         local average_ladvise=0
21577
21578         for ((i = 1; i <= $repeat; i++)); do
21579                 echo "Iter $i/$repeat: reading without willread hint"
21580                 cancel_lru_locks osc
21581                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21582                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21583                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21584                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21585
21586                 cancel_lru_locks osc
21587                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21588                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21589                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21590
21591                 cancel_lru_locks osc
21592                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21593                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21594                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21595                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21596                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21597         done
21598         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21599         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21600         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21601
21602         speedup_cache=$(percent $average_cache $average_origin)
21603         speedup_ladvise=$(percent $average_ladvise $average_origin)
21604
21605         echo "Average uncached read: $average_origin"
21606         echo "Average speedup with OSS cached read: " \
21607                 "$average_cache = +$speedup_cache%"
21608         echo "Average speedup with ladvise willread: " \
21609                 "$average_ladvise = +$speedup_ladvise%"
21610
21611         local lowest_speedup=20
21612         if (( ${average_cache%.*} < $lowest_speedup )); then
21613                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
21614                      " got $average_cache%. Skipping ladvise willread check."
21615                 return 0
21616         fi
21617
21618         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21619         # it is still good to run until then to exercise 'ladvise willread'
21620         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21621                 [ "$ost1_FSTYPE" = "zfs" ] &&
21622                 echo "osd-zfs does not support dontneed or drop_caches" &&
21623                 return 0
21624
21625         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21626         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
21627                 error_not_in_vm "Speedup with willread is less than " \
21628                         "$lowest_speedup%, got $average_ladvise%"
21629 }
21630
21631 test_255a() {
21632         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21633                 skip "lustre < 2.8.54 does not support ladvise "
21634         remote_ost_nodsh && skip "remote OST with nodsh"
21635
21636         stack_trap "rm -f $DIR/$tfile"
21637         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21638
21639         ladvise_no_type willread $DIR/$tfile &&
21640                 skip "willread ladvise is not supported"
21641
21642         ladvise_no_ioctl $DIR/$tfile &&
21643                 skip "ladvise ioctl is not supported"
21644
21645         local size_mb=100
21646         local size=$((size_mb * 1048576))
21647         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21648                 error "dd to $DIR/$tfile failed"
21649
21650         lfs ladvise -a willread $DIR/$tfile ||
21651                 error "Ladvise failed with no range argument"
21652
21653         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21654                 error "Ladvise failed with no -l or -e argument"
21655
21656         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21657                 error "Ladvise failed with only -e argument"
21658
21659         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21660                 error "Ladvise failed with only -l argument"
21661
21662         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21663                 error "End offset should not be smaller than start offset"
21664
21665         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21666                 error "End offset should not be equal to start offset"
21667
21668         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21669                 error "Ladvise failed with overflowing -s argument"
21670
21671         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21672                 error "Ladvise failed with overflowing -e argument"
21673
21674         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21675                 error "Ladvise failed with overflowing -l argument"
21676
21677         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21678                 error "Ladvise succeeded with conflicting -l and -e arguments"
21679
21680         echo "Synchronous ladvise should wait"
21681         local delay=4
21682 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21683         do_nodes $(comma_list $(osts_nodes)) \
21684                 $LCTL set_param fail_val=$delay fail_loc=0x237
21685
21686         local start_ts=$SECONDS
21687         lfs ladvise -a willread $DIR/$tfile ||
21688                 error "Ladvise failed with no range argument"
21689         local end_ts=$SECONDS
21690         local inteval_ts=$((end_ts - start_ts))
21691
21692         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21693                 error "Synchronous advice didn't wait reply"
21694         fi
21695
21696         echo "Asynchronous ladvise shouldn't wait"
21697         local start_ts=$SECONDS
21698         lfs ladvise -a willread -b $DIR/$tfile ||
21699                 error "Ladvise failed with no range argument"
21700         local end_ts=$SECONDS
21701         local inteval_ts=$((end_ts - start_ts))
21702
21703         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21704                 error "Asynchronous advice blocked"
21705         fi
21706
21707         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21708         ladvise_willread_performance
21709 }
21710 run_test 255a "check 'lfs ladvise -a willread'"
21711
21712 facet_meminfo() {
21713         local facet=$1
21714         local info=$2
21715
21716         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21717 }
21718
21719 test_255b() {
21720         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21721                 skip "lustre < 2.8.54 does not support ladvise "
21722         remote_ost_nodsh && skip "remote OST with nodsh"
21723
21724         stack_trap "rm -f $DIR/$tfile"
21725         lfs setstripe -c 1 -i 0 $DIR/$tfile
21726
21727         ladvise_no_type dontneed $DIR/$tfile &&
21728                 skip "dontneed ladvise is not supported"
21729
21730         ladvise_no_ioctl $DIR/$tfile &&
21731                 skip "ladvise ioctl is not supported"
21732
21733         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21734                 [ "$ost1_FSTYPE" = "zfs" ] &&
21735                 skip "zfs-osd does not support 'ladvise dontneed'"
21736
21737         local size_mb=100
21738         local size=$((size_mb * 1048576))
21739         # In order to prevent disturbance of other processes, only check 3/4
21740         # of the memory usage
21741         local kibibytes=$((size_mb * 1024 * 3 / 4))
21742
21743         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21744                 error "dd to $DIR/$tfile failed"
21745
21746         #force write to complete before dropping OST cache & checking memory
21747         sync
21748
21749         local total=$(facet_meminfo ost1 MemTotal)
21750         echo "Total memory: $total KiB"
21751
21752         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21753         local before_read=$(facet_meminfo ost1 Cached)
21754         echo "Cache used before read: $before_read KiB"
21755
21756         lfs ladvise -a willread $DIR/$tfile ||
21757                 error "Ladvise willread failed"
21758         local after_read=$(facet_meminfo ost1 Cached)
21759         echo "Cache used after read: $after_read KiB"
21760
21761         lfs ladvise -a dontneed $DIR/$tfile ||
21762                 error "Ladvise dontneed again failed"
21763         local no_read=$(facet_meminfo ost1 Cached)
21764         echo "Cache used after dontneed ladvise: $no_read KiB"
21765
21766         if [ $total -lt $((before_read + kibibytes)) ]; then
21767                 echo "Memory is too small, abort checking"
21768                 return 0
21769         fi
21770
21771         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21772                 error "Ladvise willread should use more memory" \
21773                         "than $kibibytes KiB"
21774         fi
21775
21776         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21777                 error "Ladvise dontneed should release more memory" \
21778                         "than $kibibytes KiB"
21779         fi
21780 }
21781 run_test 255b "check 'lfs ladvise -a dontneed'"
21782
21783 test_255c() {
21784         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21785                 skip "lustre < 2.10.50 does not support lockahead"
21786
21787         local ost1_imp=$(get_osc_import_name client ost1)
21788         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21789                          cut -d'.' -f2)
21790         local count
21791         local new_count
21792         local difference
21793         local i
21794         local rc
21795
21796         test_mkdir -p $DIR/$tdir
21797         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21798
21799         #test 10 returns only success/failure
21800         i=10
21801         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21802         rc=$?
21803         if [ $rc -eq 255 ]; then
21804                 error "Ladvise test${i} failed, ${rc}"
21805         fi
21806
21807         #test 11 counts lock enqueue requests, all others count new locks
21808         i=11
21809         count=$(do_facet ost1 \
21810                 $LCTL get_param -n ost.OSS.ost.stats)
21811         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21812
21813         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21814         rc=$?
21815         if [ $rc -eq 255 ]; then
21816                 error "Ladvise test${i} failed, ${rc}"
21817         fi
21818
21819         new_count=$(do_facet ost1 \
21820                 $LCTL get_param -n ost.OSS.ost.stats)
21821         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21822                    awk '{ print $2 }')
21823
21824         difference="$((new_count - count))"
21825         if [ $difference -ne $rc ]; then
21826                 error "Ladvise test${i}, bad enqueue count, returned " \
21827                       "${rc}, actual ${difference}"
21828         fi
21829
21830         for i in $(seq 12 21); do
21831                 # If we do not do this, we run the risk of having too many
21832                 # locks and starting lock cancellation while we are checking
21833                 # lock counts.
21834                 cancel_lru_locks osc
21835
21836                 count=$($LCTL get_param -n \
21837                        ldlm.namespaces.$imp_name.lock_unused_count)
21838
21839                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21840                 rc=$?
21841                 if [ $rc -eq 255 ]; then
21842                         error "Ladvise test ${i} failed, ${rc}"
21843                 fi
21844
21845                 new_count=$($LCTL get_param -n \
21846                        ldlm.namespaces.$imp_name.lock_unused_count)
21847                 difference="$((new_count - count))"
21848
21849                 # Test 15 output is divided by 100 to map down to valid return
21850                 if [ $i -eq 15 ]; then
21851                         rc="$((rc * 100))"
21852                 fi
21853
21854                 if [ $difference -ne $rc ]; then
21855                         error "Ladvise test ${i}, bad lock count, returned " \
21856                               "${rc}, actual ${difference}"
21857                 fi
21858         done
21859
21860         #test 22 returns only success/failure
21861         i=22
21862         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21863         rc=$?
21864         if [ $rc -eq 255 ]; then
21865                 error "Ladvise test${i} failed, ${rc}"
21866         fi
21867 }
21868 run_test 255c "suite of ladvise lockahead tests"
21869
21870 test_256() {
21871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21872         remote_mds_nodsh && skip "remote MDS with nodsh"
21873         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21874         changelog_users $SINGLEMDS | grep "^cl" &&
21875                 skip "active changelog user"
21876
21877         local cl_user
21878         local cat_sl
21879         local mdt_dev
21880
21881         mdt_dev=$(facet_device $SINGLEMDS)
21882         echo $mdt_dev
21883
21884         changelog_register || error "changelog_register failed"
21885
21886         rm -rf $DIR/$tdir
21887         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
21888
21889         changelog_clear 0 || error "changelog_clear failed"
21890
21891         # change something
21892         touch $DIR/$tdir/{1..10}
21893
21894         # stop the MDT
21895         stop $SINGLEMDS || error "Fail to stop MDT"
21896
21897         # remount the MDT
21898         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21899                 error "Fail to start MDT"
21900
21901         #after mount new plainllog is used
21902         touch $DIR/$tdir/{11..19}
21903         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21904         stack_trap "rm -f $tmpfile"
21905         cat_sl=$(do_facet $SINGLEMDS "sync; \
21906                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21907                  llog_reader $tmpfile | grep -c type=1064553b")
21908         do_facet $SINGLEMDS llog_reader $tmpfile
21909
21910         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21911
21912         changelog_clear 0 || error "changelog_clear failed"
21913
21914         cat_sl=$(do_facet $SINGLEMDS "sync; \
21915                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21916                  llog_reader $tmpfile | grep -c type=1064553b")
21917
21918         if (( cat_sl == 2 )); then
21919                 error "Empty plain llog was not deleted from changelog catalog"
21920         elif (( cat_sl != 1 )); then
21921                 error "Active plain llog shouldn't be deleted from catalog"
21922         fi
21923 }
21924 run_test 256 "Check llog delete for empty and not full state"
21925
21926 test_257() {
21927         remote_mds_nodsh && skip "remote MDS with nodsh"
21928         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21929                 skip "Need MDS version at least 2.8.55"
21930
21931         test_mkdir $DIR/$tdir
21932
21933         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21934                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21935         stat $DIR/$tdir
21936
21937 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21938         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21939         local facet=mds$((mdtidx + 1))
21940         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21941         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21942
21943         stop $facet || error "stop MDS failed"
21944         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21945                 error "start MDS fail"
21946         wait_recovery_complete $facet
21947 }
21948 run_test 257 "xattr locks are not lost"
21949
21950 # Verify we take the i_mutex when security requires it
21951 test_258a() {
21952 #define OBD_FAIL_IMUTEX_SEC 0x141c
21953         $LCTL set_param fail_loc=0x141c
21954         touch $DIR/$tfile
21955         chmod u+s $DIR/$tfile
21956         chmod a+rwx $DIR/$tfile
21957         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21958         RC=$?
21959         if [ $RC -ne 0 ]; then
21960                 error "error, failed to take i_mutex, rc=$?"
21961         fi
21962         rm -f $DIR/$tfile
21963 }
21964 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21965
21966 # Verify we do NOT take the i_mutex in the normal case
21967 test_258b() {
21968 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21969         $LCTL set_param fail_loc=0x141d
21970         touch $DIR/$tfile
21971         chmod a+rwx $DIR
21972         chmod a+rw $DIR/$tfile
21973         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21974         RC=$?
21975         if [ $RC -ne 0 ]; then
21976                 error "error, took i_mutex unnecessarily, rc=$?"
21977         fi
21978         rm -f $DIR/$tfile
21979
21980 }
21981 run_test 258b "verify i_mutex security behavior"
21982
21983 test_259() {
21984         local file=$DIR/$tfile
21985         local before
21986         local after
21987
21988         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21989
21990         stack_trap "rm -f $file" EXIT
21991
21992         wait_delete_completed
21993         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21994         echo "before: $before"
21995
21996         $LFS setstripe -i 0 -c 1 $file
21997         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21998         sync_all_data
21999         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22000         echo "after write: $after"
22001
22002 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22003         do_facet ost1 $LCTL set_param fail_loc=0x2301
22004         $TRUNCATE $file 0
22005         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22006         echo "after truncate: $after"
22007
22008         stop ost1
22009         do_facet ost1 $LCTL set_param fail_loc=0
22010         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22011         sleep 2
22012         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22013         echo "after restart: $after"
22014         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22015                 error "missing truncate?"
22016
22017         return 0
22018 }
22019 run_test 259 "crash at delayed truncate"
22020
22021 test_260() {
22022 #define OBD_FAIL_MDC_CLOSE               0x806
22023         $LCTL set_param fail_loc=0x80000806
22024         touch $DIR/$tfile
22025
22026 }
22027 run_test 260 "Check mdc_close fail"
22028
22029 ### Data-on-MDT sanity tests ###
22030 test_270a() {
22031         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22032                 skip "Need MDS version at least 2.10.55 for DoM"
22033
22034         # create DoM file
22035         local dom=$DIR/$tdir/dom_file
22036         local tmp=$DIR/$tdir/tmp_file
22037
22038         mkdir_on_mdt0 $DIR/$tdir
22039
22040         # basic checks for DoM component creation
22041         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22042                 error "Can set MDT layout to non-first entry"
22043
22044         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22045                 error "Can define multiple entries as MDT layout"
22046
22047         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22048
22049         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22050         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22051         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22052
22053         local mdtidx=$($LFS getstripe -m $dom)
22054         local mdtname=MDT$(printf %04x $mdtidx)
22055         local facet=mds$((mdtidx + 1))
22056         local space_check=1
22057
22058         # Skip free space checks with ZFS
22059         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22060
22061         # write
22062         sync
22063         local size_tmp=$((65536 * 3))
22064         local mdtfree1=$(do_facet $facet \
22065                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22066
22067         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22068         # check also direct IO along write
22069         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22070         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22071         sync
22072         cmp $tmp $dom || error "file data is different"
22073         [ $(stat -c%s $dom) == $size_tmp ] ||
22074                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22075         if [ $space_check == 1 ]; then
22076                 local mdtfree2=$(do_facet $facet \
22077                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22078
22079                 # increase in usage from by $size_tmp
22080                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22081                         error "MDT free space wrong after write: " \
22082                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22083         fi
22084
22085         # truncate
22086         local size_dom=10000
22087
22088         $TRUNCATE $dom $size_dom
22089         [ $(stat -c%s $dom) == $size_dom ] ||
22090                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22091         if [ $space_check == 1 ]; then
22092                 mdtfree1=$(do_facet $facet \
22093                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22094                 # decrease in usage from $size_tmp to new $size_dom
22095                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22096                   $(((size_tmp - size_dom) / 1024)) ] ||
22097                         error "MDT free space is wrong after truncate: " \
22098                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22099         fi
22100
22101         # append
22102         cat $tmp >> $dom
22103         sync
22104         size_dom=$((size_dom + size_tmp))
22105         [ $(stat -c%s $dom) == $size_dom ] ||
22106                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22107         if [ $space_check == 1 ]; then
22108                 mdtfree2=$(do_facet $facet \
22109                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22110                 # increase in usage by $size_tmp from previous
22111                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22112                         error "MDT free space is wrong after append: " \
22113                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22114         fi
22115
22116         # delete
22117         rm $dom
22118         if [ $space_check == 1 ]; then
22119                 mdtfree1=$(do_facet $facet \
22120                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22121                 # decrease in usage by $size_dom from previous
22122                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22123                         error "MDT free space is wrong after removal: " \
22124                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22125         fi
22126
22127         # combined striping
22128         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22129                 error "Can't create DoM + OST striping"
22130
22131         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22132         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22133         # check also direct IO along write
22134         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22135         sync
22136         cmp $tmp $dom || error "file data is different"
22137         [ $(stat -c%s $dom) == $size_tmp ] ||
22138                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22139         rm $dom $tmp
22140
22141         return 0
22142 }
22143 run_test 270a "DoM: basic functionality tests"
22144
22145 test_270b() {
22146         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22147                 skip "Need MDS version at least 2.10.55"
22148
22149         local dom=$DIR/$tdir/dom_file
22150         local max_size=1048576
22151
22152         mkdir -p $DIR/$tdir
22153         $LFS setstripe -E $max_size -L mdt $dom
22154
22155         # truncate over the limit
22156         $TRUNCATE $dom $(($max_size + 1)) &&
22157                 error "successful truncate over the maximum size"
22158         # write over the limit
22159         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22160                 error "successful write over the maximum size"
22161         # append over the limit
22162         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22163         echo "12345" >> $dom && error "successful append over the maximum size"
22164         rm $dom
22165
22166         return 0
22167 }
22168 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22169
22170 test_270c() {
22171         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22172                 skip "Need MDS version at least 2.10.55"
22173
22174         mkdir -p $DIR/$tdir
22175         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22176
22177         # check files inherit DoM EA
22178         touch $DIR/$tdir/first
22179         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22180                 error "bad pattern"
22181         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22182                 error "bad stripe count"
22183         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22184                 error "bad stripe size"
22185
22186         # check directory inherits DoM EA and uses it as default
22187         mkdir $DIR/$tdir/subdir
22188         touch $DIR/$tdir/subdir/second
22189         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22190                 error "bad pattern in sub-directory"
22191         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22192                 error "bad stripe count in sub-directory"
22193         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22194                 error "bad stripe size in sub-directory"
22195         return 0
22196 }
22197 run_test 270c "DoM: DoM EA inheritance tests"
22198
22199 test_270d() {
22200         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22201                 skip "Need MDS version at least 2.10.55"
22202
22203         mkdir -p $DIR/$tdir
22204         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22205
22206         # inherit default DoM striping
22207         mkdir $DIR/$tdir/subdir
22208         touch $DIR/$tdir/subdir/f1
22209
22210         # change default directory striping
22211         $LFS setstripe -c 1 $DIR/$tdir/subdir
22212         touch $DIR/$tdir/subdir/f2
22213         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22214                 error "wrong default striping in file 2"
22215         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22216                 error "bad pattern in file 2"
22217         return 0
22218 }
22219 run_test 270d "DoM: change striping from DoM to RAID0"
22220
22221 test_270e() {
22222         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22223                 skip "Need MDS version at least 2.10.55"
22224
22225         mkdir -p $DIR/$tdir/dom
22226         mkdir -p $DIR/$tdir/norm
22227         DOMFILES=20
22228         NORMFILES=10
22229         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22230         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22231
22232         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22233         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22234
22235         # find DoM files by layout
22236         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22237         [ $NUM -eq  $DOMFILES ] ||
22238                 error "lfs find -L: found $NUM, expected $DOMFILES"
22239         echo "Test 1: lfs find 20 DOM files by layout: OK"
22240
22241         # there should be 1 dir with default DOM striping
22242         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22243         [ $NUM -eq  1 ] ||
22244                 error "lfs find -L: found $NUM, expected 1 dir"
22245         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22246
22247         # find DoM files by stripe size
22248         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22249         [ $NUM -eq  $DOMFILES ] ||
22250                 error "lfs find -S: found $NUM, expected $DOMFILES"
22251         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22252
22253         # find files by stripe offset except DoM files
22254         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22255         [ $NUM -eq  $NORMFILES ] ||
22256                 error "lfs find -i: found $NUM, expected $NORMFILES"
22257         echo "Test 5: lfs find no DOM files by stripe index: OK"
22258         return 0
22259 }
22260 run_test 270e "DoM: lfs find with DoM files test"
22261
22262 test_270f() {
22263         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22264                 skip "Need MDS version at least 2.10.55"
22265
22266         local mdtname=${FSNAME}-MDT0000-mdtlov
22267         local dom=$DIR/$tdir/dom_file
22268         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22269                                                 lod.$mdtname.dom_stripesize)
22270         local dom_limit=131072
22271
22272         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22273         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22274                                                 lod.$mdtname.dom_stripesize)
22275         [ ${dom_limit} -eq ${dom_current} ] ||
22276                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22277
22278         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22279         $LFS setstripe -d $DIR/$tdir
22280         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22281                 error "Can't set directory default striping"
22282
22283         # exceed maximum stripe size
22284         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22285                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22286         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22287                 error "Able to create DoM component size more than LOD limit"
22288
22289         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22290         dom_current=$(do_facet mds1 $LCTL get_param -n \
22291                                                 lod.$mdtname.dom_stripesize)
22292         [ 0 -eq ${dom_current} ] ||
22293                 error "Can't set zero DoM stripe limit"
22294         rm $dom
22295
22296         # attempt to create DoM file on server with disabled DoM should
22297         # remove DoM entry from layout and be succeed
22298         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22299                 error "Can't create DoM file (DoM is disabled)"
22300         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22301                 error "File has DoM component while DoM is disabled"
22302         rm $dom
22303
22304         # attempt to create DoM file with only DoM stripe should return error
22305         $LFS setstripe -E $dom_limit -L mdt $dom &&
22306                 error "Able to create DoM-only file while DoM is disabled"
22307
22308         # too low values to be aligned with smallest stripe size 64K
22309         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22310         dom_current=$(do_facet mds1 $LCTL get_param -n \
22311                                                 lod.$mdtname.dom_stripesize)
22312         [ 30000 -eq ${dom_current} ] &&
22313                 error "Can set too small DoM stripe limit"
22314
22315         # 64K is a minimal stripe size in Lustre, expect limit of that size
22316         [ 65536 -eq ${dom_current} ] ||
22317                 error "Limit is not set to 64K but ${dom_current}"
22318
22319         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22320         dom_current=$(do_facet mds1 $LCTL get_param -n \
22321                                                 lod.$mdtname.dom_stripesize)
22322         echo $dom_current
22323         [ 2147483648 -eq ${dom_current} ] &&
22324                 error "Can set too large DoM stripe limit"
22325
22326         do_facet mds1 $LCTL set_param -n \
22327                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22328         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22329                 error "Can't create DoM component size after limit change"
22330         do_facet mds1 $LCTL set_param -n \
22331                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22332         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22333                 error "Can't create DoM file after limit decrease"
22334         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22335                 error "Can create big DoM component after limit decrease"
22336         touch ${dom}_def ||
22337                 error "Can't create file with old default layout"
22338
22339         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22340         return 0
22341 }
22342 run_test 270f "DoM: maximum DoM stripe size checks"
22343
22344 test_270g() {
22345         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22346                 skip "Need MDS version at least 2.13.52"
22347         local dom=$DIR/$tdir/$tfile
22348
22349         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22350         local lodname=${FSNAME}-MDT0000-mdtlov
22351
22352         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22353         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22354         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22355         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22356
22357         local dom_limit=1024
22358         local dom_threshold="50%"
22359
22360         $LFS setstripe -d $DIR/$tdir
22361         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22362                 error "Can't set directory default striping"
22363
22364         do_facet mds1 $LCTL set_param -n \
22365                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22366         # set 0 threshold and create DOM file to change tunable stripesize
22367         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22368         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22369                 error "Failed to create $dom file"
22370         # now tunable dom_cur_stripesize should reach maximum
22371         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22372                                         lod.${lodname}.dom_stripesize_cur_kb)
22373         [[ $dom_current == $dom_limit ]] ||
22374                 error "Current DOM stripesize is not maximum"
22375         rm $dom
22376
22377         # set threshold for further tests
22378         do_facet mds1 $LCTL set_param -n \
22379                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22380         echo "DOM threshold is $dom_threshold free space"
22381         local dom_def
22382         local dom_set
22383         # Spoof bfree to exceed threshold
22384         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22385         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22386         for spfree in 40 20 0 15 30 55; do
22387                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22388                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22389                         error "Failed to create $dom file"
22390                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22391                                         lod.${lodname}.dom_stripesize_cur_kb)
22392                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22393                 [[ $dom_def != $dom_current ]] ||
22394                         error "Default stripe size was not changed"
22395                 if (( spfree > 0 )) ; then
22396                         dom_set=$($LFS getstripe -S $dom)
22397                         (( dom_set == dom_def * 1024 )) ||
22398                                 error "DOM component size is still old"
22399                 else
22400                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22401                                 error "DoM component is set with no free space"
22402                 fi
22403                 rm $dom
22404                 dom_current=$dom_def
22405         done
22406 }
22407 run_test 270g "DoM: default DoM stripe size depends on free space"
22408
22409 test_270h() {
22410         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22411                 skip "Need MDS version at least 2.13.53"
22412
22413         local mdtname=${FSNAME}-MDT0000-mdtlov
22414         local dom=$DIR/$tdir/$tfile
22415         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22416
22417         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22418         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22419
22420         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22421         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22422                 error "can't create OST file"
22423         # mirrored file with DOM entry in the second mirror
22424         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22425                 error "can't create mirror with DoM component"
22426
22427         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22428
22429         # DOM component in the middle and has other enries in the same mirror,
22430         # should succeed but lost DoM component
22431         $LFS setstripe --copy=${dom}_1 $dom ||
22432                 error "Can't create file from OST|DOM mirror layout"
22433         # check new file has no DoM layout after all
22434         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22435                 error "File has DoM component while DoM is disabled"
22436 }
22437 run_test 270h "DoM: DoM stripe removal when disabled on server"
22438
22439 test_270i() {
22440         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22441                 skip "Need MDS version at least 2.14.54"
22442
22443         mkdir $DIR/$tdir
22444         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22445                 error "setstripe should fail" || true
22446 }
22447 run_test 270i "DoM: setting invalid DoM striping should fail"
22448
22449 test_271a() {
22450         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22451                 skip "Need MDS version at least 2.10.55"
22452
22453         local dom=$DIR/$tdir/dom
22454
22455         mkdir -p $DIR/$tdir
22456
22457         $LFS setstripe -E 1024K -L mdt $dom
22458
22459         lctl set_param -n mdc.*.stats=clear
22460         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22461         cat $dom > /dev/null
22462         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22463         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22464         ls $dom
22465         rm -f $dom
22466 }
22467 run_test 271a "DoM: data is cached for read after write"
22468
22469 test_271b() {
22470         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22471                 skip "Need MDS version at least 2.10.55"
22472
22473         local dom=$DIR/$tdir/dom
22474
22475         mkdir -p $DIR/$tdir
22476
22477         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22478
22479         lctl set_param -n mdc.*.stats=clear
22480         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22481         cancel_lru_locks mdc
22482         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22483         # second stat to check size is cached on client
22484         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22485         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22486         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22487         rm -f $dom
22488 }
22489 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22490
22491 test_271ba() {
22492         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22493                 skip "Need MDS version at least 2.10.55"
22494
22495         local dom=$DIR/$tdir/dom
22496
22497         mkdir -p $DIR/$tdir
22498
22499         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22500
22501         lctl set_param -n mdc.*.stats=clear
22502         lctl set_param -n osc.*.stats=clear
22503         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22504         cancel_lru_locks mdc
22505         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22506         # second stat to check size is cached on client
22507         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22508         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22509         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22510         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22511         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22512         rm -f $dom
22513 }
22514 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22515
22516
22517 get_mdc_stats() {
22518         local mdtidx=$1
22519         local param=$2
22520         local mdt=MDT$(printf %04x $mdtidx)
22521
22522         if [ -z $param ]; then
22523                 lctl get_param -n mdc.*$mdt*.stats
22524         else
22525                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22526         fi
22527 }
22528
22529 test_271c() {
22530         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22531                 skip "Need MDS version at least 2.10.55"
22532
22533         local dom=$DIR/$tdir/dom
22534
22535         mkdir -p $DIR/$tdir
22536
22537         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22538
22539         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22540         local facet=mds$((mdtidx + 1))
22541
22542         cancel_lru_locks mdc
22543         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22544         createmany -o $dom 1000
22545         lctl set_param -n mdc.*.stats=clear
22546         smalliomany -w $dom 1000 200
22547         get_mdc_stats $mdtidx
22548         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22549         # Each file has 1 open, 1 IO enqueues, total 2000
22550         # but now we have also +1 getxattr for security.capability, total 3000
22551         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22552         unlinkmany $dom 1000
22553
22554         cancel_lru_locks mdc
22555         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22556         createmany -o $dom 1000
22557         lctl set_param -n mdc.*.stats=clear
22558         smalliomany -w $dom 1000 200
22559         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22560         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22561         # for OPEN and IO lock.
22562         [ $((enq - enq_2)) -ge 1000 ] ||
22563                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22564         unlinkmany $dom 1000
22565         return 0
22566 }
22567 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22568
22569 cleanup_271def_tests() {
22570         trap 0
22571         rm -f $1
22572 }
22573
22574 test_271d() {
22575         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22576                 skip "Need MDS version at least 2.10.57"
22577
22578         local dom=$DIR/$tdir/dom
22579         local tmp=$TMP/$tfile
22580         trap "cleanup_271def_tests $tmp" EXIT
22581
22582         mkdir -p $DIR/$tdir
22583
22584         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22585
22586         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22587
22588         cancel_lru_locks mdc
22589         dd if=/dev/urandom of=$tmp bs=1000 count=1
22590         dd if=$tmp of=$dom bs=1000 count=1
22591         cancel_lru_locks mdc
22592
22593         cat /etc/hosts >> $tmp
22594         lctl set_param -n mdc.*.stats=clear
22595
22596         # append data to the same file it should update local page
22597         echo "Append to the same page"
22598         cat /etc/hosts >> $dom
22599         local num=$(get_mdc_stats $mdtidx ost_read)
22600         local ra=$(get_mdc_stats $mdtidx req_active)
22601         local rw=$(get_mdc_stats $mdtidx req_waittime)
22602
22603         [ -z $num ] || error "$num READ RPC occured"
22604         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22605         echo "... DONE"
22606
22607         # compare content
22608         cmp $tmp $dom || error "file miscompare"
22609
22610         cancel_lru_locks mdc
22611         lctl set_param -n mdc.*.stats=clear
22612
22613         echo "Open and read file"
22614         cat $dom > /dev/null
22615         local num=$(get_mdc_stats $mdtidx ost_read)
22616         local ra=$(get_mdc_stats $mdtidx req_active)
22617         local rw=$(get_mdc_stats $mdtidx req_waittime)
22618
22619         [ -z $num ] || error "$num READ RPC occured"
22620         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22621         echo "... DONE"
22622
22623         # compare content
22624         cmp $tmp $dom || error "file miscompare"
22625
22626         return 0
22627 }
22628 run_test 271d "DoM: read on open (1K file in reply buffer)"
22629
22630 test_271f() {
22631         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22632                 skip "Need MDS version at least 2.10.57"
22633
22634         local dom=$DIR/$tdir/dom
22635         local tmp=$TMP/$tfile
22636         trap "cleanup_271def_tests $tmp" EXIT
22637
22638         mkdir -p $DIR/$tdir
22639
22640         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22641
22642         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22643
22644         cancel_lru_locks mdc
22645         dd if=/dev/urandom of=$tmp bs=265000 count=1
22646         dd if=$tmp of=$dom bs=265000 count=1
22647         cancel_lru_locks mdc
22648         cat /etc/hosts >> $tmp
22649         lctl set_param -n mdc.*.stats=clear
22650
22651         echo "Append to the same page"
22652         cat /etc/hosts >> $dom
22653         local num=$(get_mdc_stats $mdtidx ost_read)
22654         local ra=$(get_mdc_stats $mdtidx req_active)
22655         local rw=$(get_mdc_stats $mdtidx req_waittime)
22656
22657         [ -z $num ] || error "$num READ RPC occured"
22658         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22659         echo "... DONE"
22660
22661         # compare content
22662         cmp $tmp $dom || error "file miscompare"
22663
22664         cancel_lru_locks mdc
22665         lctl set_param -n mdc.*.stats=clear
22666
22667         echo "Open and read file"
22668         cat $dom > /dev/null
22669         local num=$(get_mdc_stats $mdtidx ost_read)
22670         local ra=$(get_mdc_stats $mdtidx req_active)
22671         local rw=$(get_mdc_stats $mdtidx req_waittime)
22672
22673         [ -z $num ] && num=0
22674         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22675         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22676         echo "... DONE"
22677
22678         # compare content
22679         cmp $tmp $dom || error "file miscompare"
22680
22681         return 0
22682 }
22683 run_test 271f "DoM: read on open (200K file and read tail)"
22684
22685 test_271g() {
22686         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22687                 skip "Skipping due to old client or server version"
22688
22689         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22690         # to get layout
22691         $CHECKSTAT -t file $DIR1/$tfile
22692
22693         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22694         MULTIOP_PID=$!
22695         sleep 1
22696         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22697         $LCTL set_param fail_loc=0x80000314
22698         rm $DIR1/$tfile || error "Unlink fails"
22699         RC=$?
22700         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22701         [ $RC -eq 0 ] || error "Failed write to stale object"
22702 }
22703 run_test 271g "Discard DoM data vs client flush race"
22704
22705 test_272a() {
22706         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22707                 skip "Need MDS version at least 2.11.50"
22708
22709         local dom=$DIR/$tdir/dom
22710         mkdir -p $DIR/$tdir
22711
22712         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22713         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22714                 error "failed to write data into $dom"
22715         local old_md5=$(md5sum $dom)
22716
22717         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22718                 error "failed to migrate to the same DoM component"
22719
22720         local new_md5=$(md5sum $dom)
22721
22722         [ "$old_md5" == "$new_md5" ] ||
22723                 error "md5sum differ: $old_md5, $new_md5"
22724
22725         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22726                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22727 }
22728 run_test 272a "DoM migration: new layout with the same DOM component"
22729
22730 test_272b() {
22731         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22732                 skip "Need MDS version at least 2.11.50"
22733
22734         local dom=$DIR/$tdir/dom
22735         mkdir -p $DIR/$tdir
22736         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22737
22738         local mdtidx=$($LFS getstripe -m $dom)
22739         local mdtname=MDT$(printf %04x $mdtidx)
22740         local facet=mds$((mdtidx + 1))
22741
22742         local mdtfree1=$(do_facet $facet \
22743                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22744         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22745                 error "failed to write data into $dom"
22746         local old_md5=$(md5sum $dom)
22747         cancel_lru_locks mdc
22748         local mdtfree1=$(do_facet $facet \
22749                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22750
22751         $LFS migrate -c2 $dom ||
22752                 error "failed to migrate to the new composite layout"
22753         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22754                 error "MDT stripe was not removed"
22755
22756         cancel_lru_locks mdc
22757         local new_md5=$(md5sum $dom)
22758         [ "$old_md5" == "$new_md5" ] ||
22759                 error "$old_md5 != $new_md5"
22760
22761         # Skip free space checks with ZFS
22762         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22763                 local mdtfree2=$(do_facet $facet \
22764                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22765                 [ $mdtfree2 -gt $mdtfree1 ] ||
22766                         error "MDT space is not freed after migration"
22767         fi
22768         return 0
22769 }
22770 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22771
22772 test_272c() {
22773         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22774                 skip "Need MDS version at least 2.11.50"
22775
22776         local dom=$DIR/$tdir/$tfile
22777         mkdir -p $DIR/$tdir
22778         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22779
22780         local mdtidx=$($LFS getstripe -m $dom)
22781         local mdtname=MDT$(printf %04x $mdtidx)
22782         local facet=mds$((mdtidx + 1))
22783
22784         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22785                 error "failed to write data into $dom"
22786         local old_md5=$(md5sum $dom)
22787         cancel_lru_locks mdc
22788         local mdtfree1=$(do_facet $facet \
22789                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22790
22791         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22792                 error "failed to migrate to the new composite layout"
22793         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22794                 error "MDT stripe was not removed"
22795
22796         cancel_lru_locks mdc
22797         local new_md5=$(md5sum $dom)
22798         [ "$old_md5" == "$new_md5" ] ||
22799                 error "$old_md5 != $new_md5"
22800
22801         # Skip free space checks with ZFS
22802         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22803                 local mdtfree2=$(do_facet $facet \
22804                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22805                 [ $mdtfree2 -gt $mdtfree1 ] ||
22806                         error "MDS space is not freed after migration"
22807         fi
22808         return 0
22809 }
22810 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22811
22812 test_272d() {
22813         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22814                 skip "Need MDS version at least 2.12.55"
22815
22816         local dom=$DIR/$tdir/$tfile
22817         mkdir -p $DIR/$tdir
22818         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22819
22820         local mdtidx=$($LFS getstripe -m $dom)
22821         local mdtname=MDT$(printf %04x $mdtidx)
22822         local facet=mds$((mdtidx + 1))
22823
22824         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22825                 error "failed to write data into $dom"
22826         local old_md5=$(md5sum $dom)
22827         cancel_lru_locks mdc
22828         local mdtfree1=$(do_facet $facet \
22829                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22830
22831         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22832                 error "failed mirroring to the new composite layout"
22833         $LFS mirror resync $dom ||
22834                 error "failed mirror resync"
22835         $LFS mirror split --mirror-id 1 -d $dom ||
22836                 error "failed mirror split"
22837
22838         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22839                 error "MDT stripe was not removed"
22840
22841         cancel_lru_locks mdc
22842         local new_md5=$(md5sum $dom)
22843         [ "$old_md5" == "$new_md5" ] ||
22844                 error "$old_md5 != $new_md5"
22845
22846         # Skip free space checks with ZFS
22847         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22848                 local mdtfree2=$(do_facet $facet \
22849                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22850                 [ $mdtfree2 -gt $mdtfree1 ] ||
22851                         error "MDS space is not freed after DOM mirror deletion"
22852         fi
22853         return 0
22854 }
22855 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22856
22857 test_272e() {
22858         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22859                 skip "Need MDS version at least 2.12.55"
22860
22861         local dom=$DIR/$tdir/$tfile
22862         mkdir -p $DIR/$tdir
22863         $LFS setstripe -c 2 $dom
22864
22865         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22866                 error "failed to write data into $dom"
22867         local old_md5=$(md5sum $dom)
22868         cancel_lru_locks
22869
22870         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22871                 error "failed mirroring to the DOM layout"
22872         $LFS mirror resync $dom ||
22873                 error "failed mirror resync"
22874         $LFS mirror split --mirror-id 1 -d $dom ||
22875                 error "failed mirror split"
22876
22877         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22878                 error "MDT stripe wasn't set"
22879
22880         cancel_lru_locks
22881         local new_md5=$(md5sum $dom)
22882         [ "$old_md5" == "$new_md5" ] ||
22883                 error "$old_md5 != $new_md5"
22884
22885         return 0
22886 }
22887 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22888
22889 test_272f() {
22890         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22891                 skip "Need MDS version at least 2.12.55"
22892
22893         local dom=$DIR/$tdir/$tfile
22894         mkdir -p $DIR/$tdir
22895         $LFS setstripe -c 2 $dom
22896
22897         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22898                 error "failed to write data into $dom"
22899         local old_md5=$(md5sum $dom)
22900         cancel_lru_locks
22901
22902         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22903                 error "failed migrating to the DOM file"
22904
22905         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22906                 error "MDT stripe wasn't set"
22907
22908         cancel_lru_locks
22909         local new_md5=$(md5sum $dom)
22910         [ "$old_md5" != "$new_md5" ] &&
22911                 error "$old_md5 != $new_md5"
22912
22913         return 0
22914 }
22915 run_test 272f "DoM migration: OST-striped file to DOM file"
22916
22917 test_273a() {
22918         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22919                 skip "Need MDS version at least 2.11.50"
22920
22921         # Layout swap cannot be done if either file has DOM component,
22922         # this will never be supported, migration should be used instead
22923
22924         local dom=$DIR/$tdir/$tfile
22925         mkdir -p $DIR/$tdir
22926
22927         $LFS setstripe -c2 ${dom}_plain
22928         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22929         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22930                 error "can swap layout with DoM component"
22931         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22932                 error "can swap layout with DoM component"
22933
22934         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22935         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22936                 error "can swap layout with DoM component"
22937         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22938                 error "can swap layout with DoM component"
22939         return 0
22940 }
22941 run_test 273a "DoM: layout swapping should fail with DOM"
22942
22943 test_273b() {
22944         mkdir -p $DIR/$tdir
22945         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22946
22947 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22948         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22949
22950         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22951 }
22952 run_test 273b "DoM: race writeback and object destroy"
22953
22954 test_275() {
22955         remote_ost_nodsh && skip "remote OST with nodsh"
22956         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22957                 skip "Need OST version >= 2.10.57"
22958
22959         local file=$DIR/$tfile
22960         local oss
22961
22962         oss=$(comma_list $(osts_nodes))
22963
22964         dd if=/dev/urandom of=$file bs=1M count=2 ||
22965                 error "failed to create a file"
22966         cancel_lru_locks osc
22967
22968         #lock 1
22969         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22970                 error "failed to read a file"
22971
22972 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22973         $LCTL set_param fail_loc=0x8000031f
22974
22975         cancel_lru_locks osc &
22976         sleep 1
22977
22978 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22979         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22980         #IO takes another lock, but matches the PENDING one
22981         #and places it to the IO RPC
22982         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22983                 error "failed to read a file with PENDING lock"
22984 }
22985 run_test 275 "Read on a canceled duplicate lock"
22986
22987 test_276() {
22988         remote_ost_nodsh && skip "remote OST with nodsh"
22989         local pid
22990
22991         do_facet ost1 "(while true; do \
22992                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22993                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22994         pid=$!
22995
22996         for LOOP in $(seq 20); do
22997                 stop ost1
22998                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22999         done
23000         kill -9 $pid
23001         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23002                 rm $TMP/sanity_276_pid"
23003 }
23004 run_test 276 "Race between mount and obd_statfs"
23005
23006 test_277() {
23007         $LCTL set_param ldlm.namespaces.*.lru_size=0
23008         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23009         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23010                         grep ^used_mb | awk '{print $2}')
23011         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23012         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23013                 oflag=direct conv=notrunc
23014         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23015                         grep ^used_mb | awk '{print $2}')
23016         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23017 }
23018 run_test 277 "Direct IO shall drop page cache"
23019
23020 test_278() {
23021         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23022         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23023         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23024                 skip "needs the same host for mdt1 mdt2" && return
23025
23026         local pid1
23027         local pid2
23028
23029 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
23030         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
23031         stop mds2 &
23032         pid2=$!
23033
23034         stop mds1
23035
23036         echo "Starting MDTs"
23037         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23038         wait $pid2
23039 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23040 #will return NULL
23041         do_facet mds2 $LCTL set_param fail_loc=0
23042
23043         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23044         wait_recovery_complete mds2
23045 }
23046 run_test 278 "Race starting MDS between MDTs stop/start"
23047
23048 test_280() {
23049         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23050                 skip "Need MGS version at least 2.13.52"
23051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23052         combined_mgs_mds || skip "needs combined MGS/MDT"
23053
23054         umount_client $MOUNT
23055 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23056         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23057
23058         mount_client $MOUNT &
23059         sleep 1
23060         stop mgs || error "stop mgs failed"
23061         #for a race mgs would crash
23062         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23063         # make sure we unmount client before remounting
23064         wait
23065         umount_client $MOUNT
23066         mount_client $MOUNT || error "mount client failed"
23067 }
23068 run_test 280 "Race between MGS umount and client llog processing"
23069
23070 cleanup_test_300() {
23071         trap 0
23072         umask $SAVE_UMASK
23073 }
23074 test_striped_dir() {
23075         local mdt_index=$1
23076         local stripe_count
23077         local stripe_index
23078
23079         mkdir -p $DIR/$tdir
23080
23081         SAVE_UMASK=$(umask)
23082         trap cleanup_test_300 RETURN EXIT
23083
23084         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23085                                                 $DIR/$tdir/striped_dir ||
23086                 error "set striped dir error"
23087
23088         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23089         [ "$mode" = "755" ] || error "expect 755 got $mode"
23090
23091         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23092                 error "getdirstripe failed"
23093         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23094         if [ "$stripe_count" != "2" ]; then
23095                 error "1:stripe_count is $stripe_count, expect 2"
23096         fi
23097         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23098         if [ "$stripe_count" != "2" ]; then
23099                 error "2:stripe_count is $stripe_count, expect 2"
23100         fi
23101
23102         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23103         if [ "$stripe_index" != "$mdt_index" ]; then
23104                 error "stripe_index is $stripe_index, expect $mdt_index"
23105         fi
23106
23107         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23108                 error "nlink error after create striped dir"
23109
23110         mkdir $DIR/$tdir/striped_dir/a
23111         mkdir $DIR/$tdir/striped_dir/b
23112
23113         stat $DIR/$tdir/striped_dir/a ||
23114                 error "create dir under striped dir failed"
23115         stat $DIR/$tdir/striped_dir/b ||
23116                 error "create dir under striped dir failed"
23117
23118         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23119                 error "nlink error after mkdir"
23120
23121         rmdir $DIR/$tdir/striped_dir/a
23122         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23123                 error "nlink error after rmdir"
23124
23125         rmdir $DIR/$tdir/striped_dir/b
23126         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23127                 error "nlink error after rmdir"
23128
23129         chattr +i $DIR/$tdir/striped_dir
23130         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23131                 error "immutable flags not working under striped dir!"
23132         chattr -i $DIR/$tdir/striped_dir
23133
23134         rmdir $DIR/$tdir/striped_dir ||
23135                 error "rmdir striped dir error"
23136
23137         cleanup_test_300
23138
23139         true
23140 }
23141
23142 test_300a() {
23143         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23144                 skip "skipped for lustre < 2.7.0"
23145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23146         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23147
23148         test_striped_dir 0 || error "failed on striped dir on MDT0"
23149         test_striped_dir 1 || error "failed on striped dir on MDT0"
23150 }
23151 run_test 300a "basic striped dir sanity test"
23152
23153 test_300b() {
23154         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23155                 skip "skipped for lustre < 2.7.0"
23156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23157         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23158
23159         local i
23160         local mtime1
23161         local mtime2
23162         local mtime3
23163
23164         test_mkdir $DIR/$tdir || error "mkdir fail"
23165         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23166                 error "set striped dir error"
23167         for i in {0..9}; do
23168                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23169                 sleep 1
23170                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23171                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23172                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23173                 sleep 1
23174                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23175                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23176                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23177         done
23178         true
23179 }
23180 run_test 300b "check ctime/mtime for striped dir"
23181
23182 test_300c() {
23183         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23184                 skip "skipped for lustre < 2.7.0"
23185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23186         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23187
23188         local file_count
23189
23190         mkdir_on_mdt0 $DIR/$tdir
23191         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23192                 error "set striped dir error"
23193
23194         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23195                 error "chown striped dir failed"
23196
23197         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23198                 error "create 5k files failed"
23199
23200         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23201
23202         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23203
23204         rm -rf $DIR/$tdir
23205 }
23206 run_test 300c "chown && check ls under striped directory"
23207
23208 test_300d() {
23209         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23210                 skip "skipped for lustre < 2.7.0"
23211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23212         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23213
23214         local stripe_count
23215         local file
23216
23217         mkdir -p $DIR/$tdir
23218         $LFS setstripe -c 2 $DIR/$tdir
23219
23220         #local striped directory
23221         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23222                 error "set striped dir error"
23223         #look at the directories for debug purposes
23224         ls -l $DIR/$tdir
23225         $LFS getdirstripe $DIR/$tdir
23226         ls -l $DIR/$tdir/striped_dir
23227         $LFS getdirstripe $DIR/$tdir/striped_dir
23228         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23229                 error "create 10 files failed"
23230
23231         #remote striped directory
23232         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23233                 error "set striped dir error"
23234         #look at the directories for debug purposes
23235         ls -l $DIR/$tdir
23236         $LFS getdirstripe $DIR/$tdir
23237         ls -l $DIR/$tdir/remote_striped_dir
23238         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23239         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23240                 error "create 10 files failed"
23241
23242         for file in $(find $DIR/$tdir); do
23243                 stripe_count=$($LFS getstripe -c $file)
23244                 [ $stripe_count -eq 2 ] ||
23245                         error "wrong stripe $stripe_count for $file"
23246         done
23247
23248         rm -rf $DIR/$tdir
23249 }
23250 run_test 300d "check default stripe under striped directory"
23251
23252 test_300e() {
23253         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23254                 skip "Need MDS version at least 2.7.55"
23255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23256         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23257
23258         local stripe_count
23259         local file
23260
23261         mkdir -p $DIR/$tdir
23262
23263         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23264                 error "set striped dir error"
23265
23266         touch $DIR/$tdir/striped_dir/a
23267         touch $DIR/$tdir/striped_dir/b
23268         touch $DIR/$tdir/striped_dir/c
23269
23270         mkdir $DIR/$tdir/striped_dir/dir_a
23271         mkdir $DIR/$tdir/striped_dir/dir_b
23272         mkdir $DIR/$tdir/striped_dir/dir_c
23273
23274         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23275                 error "set striped adir under striped dir error"
23276
23277         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23278                 error "set striped bdir under striped dir error"
23279
23280         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23281                 error "set striped cdir under striped dir error"
23282
23283         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23284                 error "rename dir under striped dir fails"
23285
23286         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23287                 error "rename dir under different stripes fails"
23288
23289         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23290                 error "rename file under striped dir should succeed"
23291
23292         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23293                 error "rename dir under striped dir should succeed"
23294
23295         rm -rf $DIR/$tdir
23296 }
23297 run_test 300e "check rename under striped directory"
23298
23299 test_300f() {
23300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23301         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23302         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23303                 skip "Need MDS version at least 2.7.55"
23304
23305         local stripe_count
23306         local file
23307
23308         rm -rf $DIR/$tdir
23309         mkdir -p $DIR/$tdir
23310
23311         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23312                 error "set striped dir error"
23313
23314         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23315                 error "set striped dir error"
23316
23317         touch $DIR/$tdir/striped_dir/a
23318         mkdir $DIR/$tdir/striped_dir/dir_a
23319         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23320                 error "create striped dir under striped dir fails"
23321
23322         touch $DIR/$tdir/striped_dir1/b
23323         mkdir $DIR/$tdir/striped_dir1/dir_b
23324         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23325                 error "create striped dir under striped dir fails"
23326
23327         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23328                 error "rename dir under different striped dir should fail"
23329
23330         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23331                 error "rename striped dir under diff striped dir should fail"
23332
23333         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23334                 error "rename file under diff striped dirs fails"
23335
23336         rm -rf $DIR/$tdir
23337 }
23338 run_test 300f "check rename cross striped directory"
23339
23340 test_300_check_default_striped_dir()
23341 {
23342         local dirname=$1
23343         local default_count=$2
23344         local default_index=$3
23345         local stripe_count
23346         local stripe_index
23347         local dir_stripe_index
23348         local dir
23349
23350         echo "checking $dirname $default_count $default_index"
23351         $LFS setdirstripe -D -c $default_count -i $default_index \
23352                                 -H all_char $DIR/$tdir/$dirname ||
23353                 error "set default stripe on striped dir error"
23354         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23355         [ $stripe_count -eq $default_count ] ||
23356                 error "expect $default_count get $stripe_count for $dirname"
23357
23358         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23359         [ $stripe_index -eq $default_index ] ||
23360                 error "expect $default_index get $stripe_index for $dirname"
23361
23362         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23363                                                 error "create dirs failed"
23364
23365         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23366         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23367         for dir in $(find $DIR/$tdir/$dirname/*); do
23368                 stripe_count=$($LFS getdirstripe -c $dir)
23369                 (( $stripe_count == $default_count )) ||
23370                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23371                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23372                 error "stripe count $default_count != $stripe_count for $dir"
23373
23374                 stripe_index=$($LFS getdirstripe -i $dir)
23375                 [ $default_index -eq -1 ] ||
23376                         [ $stripe_index -eq $default_index ] ||
23377                         error "$stripe_index != $default_index for $dir"
23378
23379                 #check default stripe
23380                 stripe_count=$($LFS getdirstripe -D -c $dir)
23381                 [ $stripe_count -eq $default_count ] ||
23382                 error "default count $default_count != $stripe_count for $dir"
23383
23384                 stripe_index=$($LFS getdirstripe -D -i $dir)
23385                 [ $stripe_index -eq $default_index ] ||
23386                 error "default index $default_index != $stripe_index for $dir"
23387         done
23388         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23389 }
23390
23391 test_300g() {
23392         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23393         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23394                 skip "Need MDS version at least 2.7.55"
23395
23396         local dir
23397         local stripe_count
23398         local stripe_index
23399
23400         mkdir_on_mdt0 $DIR/$tdir
23401         mkdir $DIR/$tdir/normal_dir
23402
23403         #Checking when client cache stripe index
23404         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23405         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23406                 error "create striped_dir failed"
23407
23408         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23409                 error "create dir0 fails"
23410         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23411         [ $stripe_index -eq 0 ] ||
23412                 error "dir0 expect index 0 got $stripe_index"
23413
23414         mkdir $DIR/$tdir/striped_dir/dir1 ||
23415                 error "create dir1 fails"
23416         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23417         [ $stripe_index -eq 1 ] ||
23418                 error "dir1 expect index 1 got $stripe_index"
23419
23420         #check default stripe count/stripe index
23421         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23422         test_300_check_default_striped_dir normal_dir 1 0
23423         test_300_check_default_striped_dir normal_dir -1 1
23424         test_300_check_default_striped_dir normal_dir 2 -1
23425
23426         #delete default stripe information
23427         echo "delete default stripeEA"
23428         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23429                 error "set default stripe on striped dir error"
23430
23431         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23432         for dir in $(find $DIR/$tdir/normal_dir/*); do
23433                 stripe_count=$($LFS getdirstripe -c $dir)
23434                 [ $stripe_count -eq 0 ] ||
23435                         error "expect 1 get $stripe_count for $dir"
23436         done
23437 }
23438 run_test 300g "check default striped directory for normal directory"
23439
23440 test_300h() {
23441         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23442         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23443                 skip "Need MDS version at least 2.7.55"
23444
23445         local dir
23446         local stripe_count
23447
23448         mkdir $DIR/$tdir
23449         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23450                 error "set striped dir error"
23451
23452         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23453         test_300_check_default_striped_dir striped_dir 1 0
23454         test_300_check_default_striped_dir striped_dir -1 1
23455         test_300_check_default_striped_dir striped_dir 2 -1
23456
23457         #delete default stripe information
23458         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23459                 error "set default stripe on striped dir error"
23460
23461         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23462         for dir in $(find $DIR/$tdir/striped_dir/*); do
23463                 stripe_count=$($LFS getdirstripe -c $dir)
23464                 [ $stripe_count -eq 0 ] ||
23465                         error "expect 1 get $stripe_count for $dir"
23466         done
23467 }
23468 run_test 300h "check default striped directory for striped directory"
23469
23470 test_300i() {
23471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23472         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23473         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23474                 skip "Need MDS version at least 2.7.55"
23475
23476         local stripe_count
23477         local file
23478
23479         mkdir $DIR/$tdir
23480
23481         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23482                 error "set striped dir error"
23483
23484         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23485                 error "create files under striped dir failed"
23486
23487         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23488                 error "set striped hashdir error"
23489
23490         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23491                 error "create dir0 under hash dir failed"
23492         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23493                 error "create dir1 under hash dir failed"
23494         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23495                 error "create dir2 under hash dir failed"
23496
23497         # unfortunately, we need to umount to clear dir layout cache for now
23498         # once we fully implement dir layout, we can drop this
23499         umount_client $MOUNT || error "umount failed"
23500         mount_client $MOUNT || error "mount failed"
23501
23502         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23503         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23504         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
23505
23506         #set the stripe to be unknown hash type
23507         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
23508         $LCTL set_param fail_loc=0x1901
23509         for ((i = 0; i < 10; i++)); do
23510                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23511                         error "stat f-$i failed"
23512                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23513         done
23514
23515         touch $DIR/$tdir/striped_dir/f0 &&
23516                 error "create under striped dir with unknown hash should fail"
23517
23518         $LCTL set_param fail_loc=0
23519
23520         umount_client $MOUNT || error "umount failed"
23521         mount_client $MOUNT || error "mount failed"
23522
23523         return 0
23524 }
23525 run_test 300i "client handle unknown hash type striped directory"
23526
23527 test_300j() {
23528         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23530         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23531                 skip "Need MDS version at least 2.7.55"
23532
23533         local stripe_count
23534         local file
23535
23536         mkdir $DIR/$tdir
23537
23538         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23539         $LCTL set_param fail_loc=0x1702
23540         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23541                 error "set striped dir error"
23542
23543         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23544                 error "create files under striped dir failed"
23545
23546         $LCTL set_param fail_loc=0
23547
23548         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23549
23550         return 0
23551 }
23552 run_test 300j "test large update record"
23553
23554 test_300k() {
23555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23556         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23557         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23558                 skip "Need MDS version at least 2.7.55"
23559
23560         # this test needs a huge transaction
23561         local kb
23562         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23563              osd*.$FSNAME-MDT0000.kbytestotal")
23564         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23565
23566         local stripe_count
23567         local file
23568
23569         mkdir $DIR/$tdir
23570
23571         #define OBD_FAIL_LARGE_STRIPE   0x1703
23572         $LCTL set_param fail_loc=0x1703
23573         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23574                 error "set striped dir error"
23575         $LCTL set_param fail_loc=0
23576
23577         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23578                 error "getstripeddir fails"
23579         rm -rf $DIR/$tdir/striped_dir ||
23580                 error "unlink striped dir fails"
23581
23582         return 0
23583 }
23584 run_test 300k "test large striped directory"
23585
23586 test_300l() {
23587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23588         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23589         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23590                 skip "Need MDS version at least 2.7.55"
23591
23592         local stripe_index
23593
23594         test_mkdir -p $DIR/$tdir/striped_dir
23595         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23596                         error "chown $RUNAS_ID failed"
23597         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23598                 error "set default striped dir failed"
23599
23600         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23601         $LCTL set_param fail_loc=0x80000158
23602         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23603
23604         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23605         [ $stripe_index -eq 1 ] ||
23606                 error "expect 1 get $stripe_index for $dir"
23607 }
23608 run_test 300l "non-root user to create dir under striped dir with stale layout"
23609
23610 test_300m() {
23611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23612         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23613         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23614                 skip "Need MDS version at least 2.7.55"
23615
23616         mkdir -p $DIR/$tdir/striped_dir
23617         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23618                 error "set default stripes dir error"
23619
23620         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23621
23622         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23623         [ $stripe_count -eq 0 ] ||
23624                         error "expect 0 get $stripe_count for a"
23625
23626         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23627                 error "set default stripes dir error"
23628
23629         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23630
23631         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23632         [ $stripe_count -eq 0 ] ||
23633                         error "expect 0 get $stripe_count for b"
23634
23635         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23636                 error "set default stripes dir error"
23637
23638         mkdir $DIR/$tdir/striped_dir/c &&
23639                 error "default stripe_index is invalid, mkdir c should fails"
23640
23641         rm -rf $DIR/$tdir || error "rmdir fails"
23642 }
23643 run_test 300m "setstriped directory on single MDT FS"
23644
23645 cleanup_300n() {
23646         local list=$(comma_list $(mdts_nodes))
23647
23648         trap 0
23649         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23650 }
23651
23652 test_300n() {
23653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23654         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23655         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23656                 skip "Need MDS version at least 2.7.55"
23657         remote_mds_nodsh && skip "remote MDS with nodsh"
23658
23659         local stripe_index
23660         local list=$(comma_list $(mdts_nodes))
23661
23662         trap cleanup_300n RETURN EXIT
23663         mkdir -p $DIR/$tdir
23664         chmod 777 $DIR/$tdir
23665         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23666                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23667                 error "create striped dir succeeds with gid=0"
23668
23669         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23670         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23671                 error "create striped dir fails with gid=-1"
23672
23673         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23674         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23675                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23676                 error "set default striped dir succeeds with gid=0"
23677
23678
23679         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23680         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23681                 error "set default striped dir fails with gid=-1"
23682
23683
23684         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23685         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23686                                         error "create test_dir fails"
23687         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23688                                         error "create test_dir1 fails"
23689         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23690                                         error "create test_dir2 fails"
23691         cleanup_300n
23692 }
23693 run_test 300n "non-root user to create dir under striped dir with default EA"
23694
23695 test_300o() {
23696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23697         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23698         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23699                 skip "Need MDS version at least 2.7.55"
23700
23701         local numfree1
23702         local numfree2
23703
23704         mkdir -p $DIR/$tdir
23705
23706         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23707         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23708         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23709                 skip "not enough free inodes $numfree1 $numfree2"
23710         fi
23711
23712         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23713         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23714         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23715                 skip "not enough free space $numfree1 $numfree2"
23716         fi
23717
23718         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23719                 error "setdirstripe fails"
23720
23721         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23722                 error "create dirs fails"
23723
23724         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23725         ls $DIR/$tdir/striped_dir > /dev/null ||
23726                 error "ls striped dir fails"
23727         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23728                 error "unlink big striped dir fails"
23729 }
23730 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23731
23732 test_300p() {
23733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23734         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23735         remote_mds_nodsh && skip "remote MDS with nodsh"
23736
23737         mkdir_on_mdt0 $DIR/$tdir
23738
23739         #define OBD_FAIL_OUT_ENOSPC     0x1704
23740         do_facet mds2 lctl set_param fail_loc=0x80001704
23741         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23742                  && error "create striped directory should fail"
23743
23744         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23745
23746         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23747         true
23748 }
23749 run_test 300p "create striped directory without space"
23750
23751 test_300q() {
23752         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23753         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23754
23755         local fd=$(free_fd)
23756         local cmd="exec $fd<$tdir"
23757         cd $DIR
23758         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23759         eval $cmd
23760         cmd="exec $fd<&-"
23761         trap "eval $cmd" EXIT
23762         cd $tdir || error "cd $tdir fails"
23763         rmdir  ../$tdir || error "rmdir $tdir fails"
23764         mkdir local_dir && error "create dir succeeds"
23765         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23766         eval $cmd
23767         return 0
23768 }
23769 run_test 300q "create remote directory under orphan directory"
23770
23771 test_300r() {
23772         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23773                 skip "Need MDS version at least 2.7.55" && return
23774         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23775
23776         mkdir $DIR/$tdir
23777
23778         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23779                 error "set striped dir error"
23780
23781         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23782                 error "getstripeddir fails"
23783
23784         local stripe_count
23785         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23786                       awk '/lmv_stripe_count:/ { print $2 }')
23787
23788         [ $MDSCOUNT -ne $stripe_count ] &&
23789                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23790
23791         rm -rf $DIR/$tdir/striped_dir ||
23792                 error "unlink striped dir fails"
23793 }
23794 run_test 300r "test -1 striped directory"
23795
23796 test_300s_helper() {
23797         local count=$1
23798
23799         local stripe_dir=$DIR/$tdir/striped_dir.$count
23800
23801         $LFS mkdir -c $count $stripe_dir ||
23802                 error "lfs mkdir -c error"
23803
23804         $LFS getdirstripe $stripe_dir ||
23805                 error "lfs getdirstripe fails"
23806
23807         local stripe_count
23808         stripe_count=$($LFS getdirstripe $stripe_dir |
23809                       awk '/lmv_stripe_count:/ { print $2 }')
23810
23811         [ $count -ne $stripe_count ] &&
23812                 error_noexit "bad stripe count $stripe_count expected $count"
23813
23814         local dupe_stripes
23815         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23816                 awk '/0x/ {count[$1] += 1}; END {
23817                         for (idx in count) {
23818                                 if (count[idx]>1) {
23819                                         print "index " idx " count " count[idx]
23820                                 }
23821                         }
23822                 }')
23823
23824         if [[ -n "$dupe_stripes" ]] ; then
23825                 lfs getdirstripe $stripe_dir
23826                 error_noexit "Dupe MDT above: $dupe_stripes "
23827         fi
23828
23829         rm -rf $stripe_dir ||
23830                 error_noexit "unlink $stripe_dir fails"
23831 }
23832
23833 test_300s() {
23834         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23835                 skip "Need MDS version at least 2.7.55" && return
23836         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23837
23838         mkdir $DIR/$tdir
23839         for count in $(seq 2 $MDSCOUNT); do
23840                 test_300s_helper $count
23841         done
23842 }
23843 run_test 300s "test lfs mkdir -c without -i"
23844
23845 test_300t() {
23846         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
23847                 skip "need MDS 2.14.55 or later"
23848         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
23849
23850         local testdir="$DIR/$tdir/striped_dir"
23851         local dir1=$testdir/dir1
23852         local dir2=$testdir/dir2
23853
23854         mkdir -p $testdir
23855
23856         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
23857                 error "failed to set default stripe count for $testdir"
23858
23859         mkdir $dir1
23860         local stripe_count=$($LFS getdirstripe -c $dir1)
23861
23862         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
23863
23864         local max_count=$((MDSCOUNT - 1))
23865         local mdts=$(comma_list $(mdts_nodes))
23866
23867         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
23868         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
23869
23870         mkdir $dir2
23871         stripe_count=$($LFS getdirstripe -c $dir2)
23872
23873         (( $stripe_count == $max_count )) || error "wrong stripe count"
23874 }
23875 run_test 300t "test max_mdt_stripecount"
23876
23877 prepare_remote_file() {
23878         mkdir $DIR/$tdir/src_dir ||
23879                 error "create remote source failed"
23880
23881         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23882                  error "cp to remote source failed"
23883         touch $DIR/$tdir/src_dir/a
23884
23885         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23886                 error "create remote target dir failed"
23887
23888         touch $DIR/$tdir/tgt_dir/b
23889
23890         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23891                 error "rename dir cross MDT failed!"
23892
23893         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23894                 error "src_child still exists after rename"
23895
23896         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23897                 error "missing file(a) after rename"
23898
23899         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
23900                 error "diff after rename"
23901 }
23902
23903 test_310a() {
23904         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23906
23907         local remote_file=$DIR/$tdir/tgt_dir/b
23908
23909         mkdir -p $DIR/$tdir
23910
23911         prepare_remote_file || error "prepare remote file failed"
23912
23913         #open-unlink file
23914         $OPENUNLINK $remote_file $remote_file ||
23915                 error "openunlink $remote_file failed"
23916         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23917 }
23918 run_test 310a "open unlink remote file"
23919
23920 test_310b() {
23921         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23923
23924         local remote_file=$DIR/$tdir/tgt_dir/b
23925
23926         mkdir -p $DIR/$tdir
23927
23928         prepare_remote_file || error "prepare remote file failed"
23929
23930         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23931         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23932         $CHECKSTAT -t file $remote_file || error "check file failed"
23933 }
23934 run_test 310b "unlink remote file with multiple links while open"
23935
23936 test_310c() {
23937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23938         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23939
23940         local remote_file=$DIR/$tdir/tgt_dir/b
23941
23942         mkdir -p $DIR/$tdir
23943
23944         prepare_remote_file || error "prepare remote file failed"
23945
23946         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23947         multiop_bg_pause $remote_file O_uc ||
23948                         error "mulitop failed for remote file"
23949         MULTIPID=$!
23950         $MULTIOP $DIR/$tfile Ouc
23951         kill -USR1 $MULTIPID
23952         wait $MULTIPID
23953 }
23954 run_test 310c "open-unlink remote file with multiple links"
23955
23956 #LU-4825
23957 test_311() {
23958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23959         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23960         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23961                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23962         remote_mds_nodsh && skip "remote MDS with nodsh"
23963
23964         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23965         local mdts=$(comma_list $(mdts_nodes))
23966
23967         mkdir -p $DIR/$tdir
23968         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23969         createmany -o $DIR/$tdir/$tfile. 1000
23970
23971         # statfs data is not real time, let's just calculate it
23972         old_iused=$((old_iused + 1000))
23973
23974         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23975                         osp.*OST0000*MDT0000.create_count")
23976         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23977                                 osp.*OST0000*MDT0000.max_create_count")
23978         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23979
23980         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23981         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23982         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23983
23984         unlinkmany $DIR/$tdir/$tfile. 1000
23985
23986         do_nodes $mdts "$LCTL set_param -n \
23987                         osp.*OST0000*.max_create_count=$max_count"
23988         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23989                 do_nodes $mdts "$LCTL set_param -n \
23990                                 osp.*OST0000*.create_count=$count"
23991         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23992                         grep "=0" && error "create_count is zero"
23993
23994         local new_iused
23995         for i in $(seq 120); do
23996                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23997                 # system may be too busy to destroy all objs in time, use
23998                 # a somewhat small value to not fail autotest
23999                 [ $((old_iused - new_iused)) -gt 400 ] && break
24000                 sleep 1
24001         done
24002
24003         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24004         [ $((old_iused - new_iused)) -gt 400 ] ||
24005                 error "objs not destroyed after unlink"
24006 }
24007 run_test 311 "disable OSP precreate, and unlink should destroy objs"
24008
24009 zfs_oid_to_objid()
24010 {
24011         local ost=$1
24012         local objid=$2
24013
24014         local vdevdir=$(dirname $(facet_vdevice $ost))
24015         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
24016         local zfs_zapid=$(do_facet $ost $cmd |
24017                           grep -w "/O/0/d$((objid%32))" -C 5 |
24018                           awk '/Object/{getline; print $1}')
24019         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
24020                           awk "/$objid = /"'{printf $3}')
24021
24022         echo $zfs_objid
24023 }
24024
24025 zfs_object_blksz() {
24026         local ost=$1
24027         local objid=$2
24028
24029         local vdevdir=$(dirname $(facet_vdevice $ost))
24030         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
24031         local blksz=$(do_facet $ost $cmd $objid |
24032                       awk '/dblk/{getline; printf $4}')
24033
24034         case "${blksz: -1}" in
24035                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24036                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24037                 *) ;;
24038         esac
24039
24040         echo $blksz
24041 }
24042
24043 test_312() { # LU-4856
24044         remote_ost_nodsh && skip "remote OST with nodsh"
24045         [ "$ost1_FSTYPE" = "zfs" ] ||
24046                 skip_env "the test only applies to zfs"
24047
24048         local max_blksz=$(do_facet ost1 \
24049                           $ZFS get -p recordsize $(facet_device ost1) |
24050                           awk '!/VALUE/{print $3}')
24051
24052         # to make life a little bit easier
24053         $LFS mkdir -c 1 -i 0 $DIR/$tdir
24054         $LFS setstripe -c 1 -i 0 $DIR/$tdir
24055
24056         local tf=$DIR/$tdir/$tfile
24057         touch $tf
24058         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24059
24060         # Get ZFS object id
24061         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24062         # block size change by sequential overwrite
24063         local bs
24064
24065         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24066                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24067
24068                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
24069                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
24070         done
24071         rm -f $tf
24072
24073         # block size change by sequential append write
24074         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24075         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24076         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24077         local count
24078
24079         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24080                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24081                         oflag=sync conv=notrunc
24082
24083                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
24084                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
24085                         error "blksz error, actual $blksz, " \
24086                                 "expected: 2 * $count * $PAGE_SIZE"
24087         done
24088         rm -f $tf
24089
24090         # random write
24091         touch $tf
24092         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24093         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24094
24095         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24096         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24097         [ $blksz -eq $PAGE_SIZE ] ||
24098                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24099
24100         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24101         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24102         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
24103
24104         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24105         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24106         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
24107 }
24108 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24109
24110 test_313() {
24111         remote_ost_nodsh && skip "remote OST with nodsh"
24112
24113         local file=$DIR/$tfile
24114
24115         rm -f $file
24116         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24117
24118         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24119         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24120         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24121                 error "write should failed"
24122         do_facet ost1 "$LCTL set_param fail_loc=0"
24123         rm -f $file
24124 }
24125 run_test 313 "io should fail after last_rcvd update fail"
24126
24127 test_314() {
24128         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24129
24130         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24131         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24132         rm -f $DIR/$tfile
24133         wait_delete_completed
24134         do_facet ost1 "$LCTL set_param fail_loc=0"
24135 }
24136 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24137
24138 test_315() { # LU-618
24139         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24140
24141         local file=$DIR/$tfile
24142         rm -f $file
24143
24144         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24145                 error "multiop file write failed"
24146         $MULTIOP $file oO_RDONLY:r4063232_c &
24147         PID=$!
24148
24149         sleep 2
24150
24151         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24152         kill -USR1 $PID
24153
24154         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24155         rm -f $file
24156 }
24157 run_test 315 "read should be accounted"
24158
24159 test_316() {
24160         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24161         large_xattr_enabled || skip "ea_inode feature disabled"
24162
24163         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
24164         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
24165         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
24166         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
24167
24168         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
24169 }
24170 run_test 316 "lfs migrate of file with large_xattr enabled"
24171
24172 test_317() {
24173         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24174                 skip "Need MDS version at least 2.11.53"
24175         if [ "$ost1_FSTYPE" == "zfs" ]; then
24176                 skip "LU-10370: no implementation for ZFS"
24177         fi
24178
24179         local trunc_sz
24180         local grant_blk_size
24181
24182         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24183                         awk '/grant_block_size:/ { print $2; exit; }')
24184         #
24185         # Create File of size 5M. Truncate it to below size's and verify
24186         # blocks count.
24187         #
24188         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24189                 error "Create file $DIR/$tfile failed"
24190         stack_trap "rm -f $DIR/$tfile" EXIT
24191
24192         for trunc_sz in 2097152 4097 4000 509 0; do
24193                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24194                         error "truncate $tfile to $trunc_sz failed"
24195                 local sz=$(stat --format=%s $DIR/$tfile)
24196                 local blk=$(stat --format=%b $DIR/$tfile)
24197                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24198                                      grant_blk_size) * 8))
24199
24200                 if [[ $blk -ne $trunc_blk ]]; then
24201                         $(which stat) $DIR/$tfile
24202                         error "Expected Block $trunc_blk got $blk for $tfile"
24203                 fi
24204
24205                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24206                         error "Expected Size $trunc_sz got $sz for $tfile"
24207         done
24208
24209         #
24210         # sparse file test
24211         # Create file with a hole and write actual 65536 bytes which aligned
24212         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24213         #
24214         local bs=65536
24215         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24216                 error "Create file : $DIR/$tfile"
24217
24218         #
24219         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24220         # blocks. The block count must drop to 8.
24221         #
24222         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
24223                 ((bs - grant_blk_size) + 1)))
24224         $TRUNCATE $DIR/$tfile $trunc_sz ||
24225                 error "truncate $tfile to $trunc_sz failed"
24226
24227         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24228         sz=$(stat --format=%s $DIR/$tfile)
24229         blk=$(stat --format=%b $DIR/$tfile)
24230
24231         if [[ $blk -ne $trunc_bsz ]]; then
24232                 $(which stat) $DIR/$tfile
24233                 error "Expected Block $trunc_bsz got $blk for $tfile"
24234         fi
24235
24236         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24237                 error "Expected Size $trunc_sz got $sz for $tfile"
24238 }
24239 run_test 317 "Verify blocks get correctly update after truncate"
24240
24241 test_318() {
24242         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24243         local old_max_active=$($LCTL get_param -n \
24244                             ${llite_name}.max_read_ahead_async_active \
24245                             2>/dev/null)
24246
24247         $LCTL set_param llite.*.max_read_ahead_async_active=256
24248         local max_active=$($LCTL get_param -n \
24249                            ${llite_name}.max_read_ahead_async_active \
24250                            2>/dev/null)
24251         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24252
24253         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24254                 error "set max_read_ahead_async_active should succeed"
24255
24256         $LCTL set_param llite.*.max_read_ahead_async_active=512
24257         max_active=$($LCTL get_param -n \
24258                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24259         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24260
24261         # restore @max_active
24262         [ $old_max_active -ne 0 ] && $LCTL set_param \
24263                 llite.*.max_read_ahead_async_active=$old_max_active
24264
24265         local old_threshold=$($LCTL get_param -n \
24266                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24267         local max_per_file_mb=$($LCTL get_param -n \
24268                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24269
24270         local invalid=$(($max_per_file_mb + 1))
24271         $LCTL set_param \
24272                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24273                         && error "set $invalid should fail"
24274
24275         local valid=$(($invalid - 1))
24276         $LCTL set_param \
24277                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24278                         error "set $valid should succeed"
24279         local threshold=$($LCTL get_param -n \
24280                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24281         [ $threshold -eq $valid ] || error \
24282                 "expect threshold $valid got $threshold"
24283         $LCTL set_param \
24284                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24285 }
24286 run_test 318 "Verify async readahead tunables"
24287
24288 test_319() {
24289         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24290
24291         local before=$(date +%s)
24292         local evict
24293         local mdir=$DIR/$tdir
24294         local file=$mdir/xxx
24295
24296         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24297         touch $file
24298
24299 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24300         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24301         $LFS migrate -m1 $mdir &
24302
24303         sleep 1
24304         dd if=$file of=/dev/null
24305         wait
24306         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24307           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24308
24309         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24310 }
24311 run_test 319 "lost lease lock on migrate error"
24312
24313 test_398a() { # LU-4198
24314         local ost1_imp=$(get_osc_import_name client ost1)
24315         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24316                          cut -d'.' -f2)
24317
24318         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24319         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24320
24321         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
24322         # request a new lock on client
24323         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24324
24325         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24326         #local lock_count=$($LCTL get_param -n \
24327         #                  ldlm.namespaces.$imp_name.lru_size)
24328         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24329
24330         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24331
24332         # no lock cached, should use lockless DIO and not enqueue new lock
24333         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
24334                 conv=notrunc ||
24335                 error "dio write failed"
24336         lock_count=$($LCTL get_param -n \
24337                      ldlm.namespaces.$imp_name.lru_size)
24338         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24339
24340         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24341
24342         # no lock cached, should use locked DIO append
24343         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
24344                 conv=notrunc || error "DIO append failed"
24345         lock_count=$($LCTL get_param -n \
24346                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
24347         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
24348 }
24349 run_test 398a "direct IO should cancel lock otherwise lockless"
24350
24351 test_398b() { # LU-4198
24352         which fio || skip_env "no fio installed"
24353         $LFS setstripe -c -1 -S 1M $DIR/$tfile
24354
24355         local size=48
24356         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24357
24358         local njobs=4
24359         # Single page, multiple pages, stripe size, 4*stripe size
24360         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
24361                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
24362                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
24363                         --numjobs=$njobs --fallocate=none \
24364                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24365                         --filename=$DIR/$tfile &
24366                 bg_pid=$!
24367
24368                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
24369                 fio --name=rand-rw --rw=randrw --bs=$bsize \
24370                         --numjobs=$njobs --fallocate=none \
24371                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24372                         --filename=$DIR/$tfile || true
24373                 wait $bg_pid
24374         done
24375
24376         evict=$(do_facet client $LCTL get_param \
24377                 osc.$FSNAME-OST*-osc-*/state |
24378             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
24379
24380         [ -z "$evict" ] || [[ $evict -le $before ]] ||
24381                 (do_facet client $LCTL get_param \
24382                         osc.$FSNAME-OST*-osc-*/state;
24383                     error "eviction happened: $evict before:$before")
24384
24385         rm -f $DIR/$tfile
24386 }
24387 run_test 398b "DIO and buffer IO race"
24388
24389 test_398c() { # LU-4198
24390         local ost1_imp=$(get_osc_import_name client ost1)
24391         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24392                          cut -d'.' -f2)
24393
24394         which fio || skip_env "no fio installed"
24395
24396         saved_debug=$($LCTL get_param -n debug)
24397         $LCTL set_param debug=0
24398
24399         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24400         ((size /= 1024)) # by megabytes
24401         ((size /= 2)) # write half of the OST at most
24402         [ $size -gt 40 ] && size=40 #reduce test time anyway
24403
24404         $LFS setstripe -c 1 $DIR/$tfile
24405
24406         # it seems like ldiskfs reserves more space than necessary if the
24407         # writing blocks are not mapped, so it extends the file firstly
24408         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24409         cancel_lru_locks osc
24410
24411         # clear and verify rpc_stats later
24412         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24413
24414         local njobs=4
24415         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24416         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24417                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24418                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24419                 --filename=$DIR/$tfile
24420         [ $? -eq 0 ] || error "fio write error"
24421
24422         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24423                 error "Locks were requested while doing AIO"
24424
24425         # get the percentage of 1-page I/O
24426         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24427                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24428                 awk '{print $7}')
24429         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24430
24431         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24432         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24433                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24434                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24435                 --filename=$DIR/$tfile
24436         [ $? -eq 0 ] || error "fio mixed read write error"
24437
24438         echo "AIO with large block size ${size}M"
24439         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24440                 --numjobs=1 --fallocate=none --ioengine=libaio \
24441                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24442                 --filename=$DIR/$tfile
24443         [ $? -eq 0 ] || error "fio large block size failed"
24444
24445         rm -f $DIR/$tfile
24446         $LCTL set_param debug="$saved_debug"
24447 }
24448 run_test 398c "run fio to test AIO"
24449
24450 test_398d() { #  LU-13846
24451         which aiocp || skip_env "no aiocp installed"
24452         local aio_file=$DIR/$tfile.aio
24453
24454         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24455
24456         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24457         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24458         stack_trap "rm -f $DIR/$tfile $aio_file"
24459
24460         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24461
24462         # make sure we don't crash and fail properly
24463         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24464                 error "aio not aligned with PAGE SIZE should fail"
24465
24466         rm -f $DIR/$tfile $aio_file
24467 }
24468 run_test 398d "run aiocp to verify block size > stripe size"
24469
24470 test_398e() {
24471         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24472         touch $DIR/$tfile.new
24473         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24474 }
24475 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24476
24477 test_398f() { #  LU-14687
24478         which aiocp || skip_env "no aiocp installed"
24479         local aio_file=$DIR/$tfile.aio
24480
24481         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24482
24483         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24484         stack_trap "rm -f $DIR/$tfile $aio_file"
24485
24486         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24487         $LCTL set_param fail_loc=0x1418
24488         # make sure we don't crash and fail properly
24489         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24490                 error "aio with page allocation failure succeeded"
24491         $LCTL set_param fail_loc=0
24492         diff $DIR/$tfile $aio_file
24493         [[ $? != 0 ]] || error "no diff after failed aiocp"
24494 }
24495 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24496
24497 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24498 # stripe and i/o size must be > stripe size
24499 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24500 # single RPC in flight.  This test shows async DIO submission is working by
24501 # showing multiple RPCs in flight.
24502 test_398g() { #  LU-13798
24503         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24504
24505         # We need to do some i/o first to acquire enough grant to put our RPCs
24506         # in flight; otherwise a new connection may not have enough grant
24507         # available
24508         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24509                 error "parallel dio failed"
24510         stack_trap "rm -f $DIR/$tfile"
24511
24512         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24513         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24514         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24515         stack_trap "$LCTL set_param -n $pages_per_rpc"
24516
24517         # Recreate file so it's empty
24518         rm -f $DIR/$tfile
24519         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24520         #Pause rpc completion to guarantee we see multiple rpcs in flight
24521         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24522         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24523         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24524
24525         # Clear rpc stats
24526         $LCTL set_param osc.*.rpc_stats=c
24527
24528         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24529                 error "parallel dio failed"
24530         stack_trap "rm -f $DIR/$tfile"
24531
24532         $LCTL get_param osc.*-OST0000-*.rpc_stats
24533         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24534                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24535                 grep "8:" | awk '{print $8}')
24536         # We look at the "8 rpcs in flight" field, and verify A) it is present
24537         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24538         # as expected for an 8M DIO to a file with 1M stripes.
24539         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24540
24541         # Verify turning off parallel dio works as expected
24542         # Clear rpc stats
24543         $LCTL set_param osc.*.rpc_stats=c
24544         $LCTL set_param llite.*.parallel_dio=0
24545         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24546
24547         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24548                 error "dio with parallel dio disabled failed"
24549
24550         # Ideally, we would see only one RPC in flight here, but there is an
24551         # unavoidable race between i/o completion and RPC in flight counting,
24552         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24553         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24554         # So instead we just verify it's always < 8.
24555         $LCTL get_param osc.*-OST0000-*.rpc_stats
24556         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24557                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24558                 grep '^$' -B1 | grep . | awk '{print $1}')
24559         [ $ret != "8:" ] ||
24560                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24561 }
24562 run_test 398g "verify parallel dio async RPC submission"
24563
24564 test_398h() { #  LU-13798
24565         local dio_file=$DIR/$tfile.dio
24566
24567         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24568
24569         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24570         stack_trap "rm -f $DIR/$tfile $dio_file"
24571
24572         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24573                 error "parallel dio failed"
24574         diff $DIR/$tfile $dio_file
24575         [[ $? == 0 ]] || error "file diff after aiocp"
24576 }
24577 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24578
24579 test_398i() { #  LU-13798
24580         local dio_file=$DIR/$tfile.dio
24581
24582         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24583
24584         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24585         stack_trap "rm -f $DIR/$tfile $dio_file"
24586
24587         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24588         $LCTL set_param fail_loc=0x1418
24589         # make sure we don't crash and fail properly
24590         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24591                 error "parallel dio page allocation failure succeeded"
24592         diff $DIR/$tfile $dio_file
24593         [[ $? != 0 ]] || error "no diff after failed aiocp"
24594 }
24595 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24596
24597 test_398j() { #  LU-13798
24598         # Stripe size > RPC size but less than i/o size tests split across
24599         # stripes and RPCs for individual i/o op
24600         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24601
24602         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24603         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24604         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24605         stack_trap "$LCTL set_param -n $pages_per_rpc"
24606
24607         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24608                 error "parallel dio write failed"
24609         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24610
24611         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24612                 error "parallel dio read failed"
24613         diff $DIR/$tfile $DIR/$tfile.2
24614         [[ $? == 0 ]] || error "file diff after parallel dio read"
24615 }
24616 run_test 398j "test parallel dio where stripe size > rpc_size"
24617
24618 test_398k() { #  LU-13798
24619         wait_delete_completed
24620         wait_mds_ost_sync
24621
24622         # 4 stripe file; we will cause out of space on OST0
24623         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24624
24625         # Fill OST0 (if it's not too large)
24626         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24627                    head -n1)
24628         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24629                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24630         fi
24631         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24632         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24633                 error "dd should fill OST0"
24634         stack_trap "rm -f $DIR/$tfile.1"
24635
24636         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24637         err=$?
24638
24639         ls -la $DIR/$tfile
24640         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24641                 error "file is not 0 bytes in size"
24642
24643         # dd above should not succeed, but don't error until here so we can
24644         # get debug info above
24645         [[ $err != 0 ]] ||
24646                 error "parallel dio write with enospc succeeded"
24647         stack_trap "rm -f $DIR/$tfile"
24648 }
24649 run_test 398k "test enospc on first stripe"
24650
24651 test_398l() { #  LU-13798
24652         wait_delete_completed
24653         wait_mds_ost_sync
24654
24655         # 4 stripe file; we will cause out of space on OST0
24656         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24657         # happens on the second i/o chunk we issue
24658         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24659
24660         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24661         stack_trap "rm -f $DIR/$tfile"
24662
24663         # Fill OST0 (if it's not too large)
24664         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24665                    head -n1)
24666         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24667                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24668         fi
24669         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24670         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24671                 error "dd should fill OST0"
24672         stack_trap "rm -f $DIR/$tfile.1"
24673
24674         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24675         err=$?
24676         stack_trap "rm -f $DIR/$tfile.2"
24677
24678         # Check that short write completed as expected
24679         ls -la $DIR/$tfile.2
24680         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24681                 error "file is not 1M in size"
24682
24683         # dd above should not succeed, but don't error until here so we can
24684         # get debug info above
24685         [[ $err != 0 ]] ||
24686                 error "parallel dio write with enospc succeeded"
24687
24688         # Truncate source file to same length as output file and diff them
24689         $TRUNCATE $DIR/$tfile 1048576
24690         diff $DIR/$tfile $DIR/$tfile.2
24691         [[ $? == 0 ]] || error "data incorrect after short write"
24692 }
24693 run_test 398l "test enospc on intermediate stripe/RPC"
24694
24695 test_398m() { #  LU-13798
24696         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24697
24698         # Set up failure on OST0, the first stripe:
24699         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24700         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24701         # So this fail_val specifies OST0
24702         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24703         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24704
24705         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24706                 error "parallel dio write with failure on first stripe succeeded"
24707         stack_trap "rm -f $DIR/$tfile"
24708         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24709
24710         # Place data in file for read
24711         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24712                 error "parallel dio write failed"
24713
24714         # Fail read on OST0, first stripe
24715         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24716         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24717         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24718                 error "parallel dio read with error on first stripe succeeded"
24719         rm -f $DIR/$tfile.2
24720         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24721
24722         # Switch to testing on OST1, second stripe
24723         # Clear file contents, maintain striping
24724         echo > $DIR/$tfile
24725         # Set up failure on OST1, second stripe:
24726         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24727         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24728
24729         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24730                 error "parallel dio write with failure on first stripe succeeded"
24731         stack_trap "rm -f $DIR/$tfile"
24732         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24733
24734         # Place data in file for read
24735         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24736                 error "parallel dio write failed"
24737
24738         # Fail read on OST1, second stripe
24739         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24740         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24741         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24742                 error "parallel dio read with error on first stripe succeeded"
24743         rm -f $DIR/$tfile.2
24744         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24745 }
24746 run_test 398m "test RPC failures with parallel dio"
24747
24748 # Parallel submission of DIO should not cause problems for append, but it's
24749 # important to verify.
24750 test_398n() { #  LU-13798
24751         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24752
24753         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24754                 error "dd to create source file failed"
24755         stack_trap "rm -f $DIR/$tfile"
24756
24757         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24758                 error "parallel dio write with failure on second stripe succeeded"
24759         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24760         diff $DIR/$tfile $DIR/$tfile.1
24761         [[ $? == 0 ]] || error "data incorrect after append"
24762
24763 }
24764 run_test 398n "test append with parallel DIO"
24765
24766 test_fake_rw() {
24767         local read_write=$1
24768         if [ "$read_write" = "write" ]; then
24769                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24770         elif [ "$read_write" = "read" ]; then
24771                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24772         else
24773                 error "argument error"
24774         fi
24775
24776         # turn off debug for performance testing
24777         local saved_debug=$($LCTL get_param -n debug)
24778         $LCTL set_param debug=0
24779
24780         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24781
24782         # get ost1 size - $FSNAME-OST0000
24783         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24784         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
24785         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
24786
24787         if [ "$read_write" = "read" ]; then
24788                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
24789         fi
24790
24791         local start_time=$(date +%s.%N)
24792         $dd_cmd bs=1M count=$blocks oflag=sync ||
24793                 error "real dd $read_write error"
24794         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
24795
24796         if [ "$read_write" = "write" ]; then
24797                 rm -f $DIR/$tfile
24798         fi
24799
24800         # define OBD_FAIL_OST_FAKE_RW           0x238
24801         do_facet ost1 $LCTL set_param fail_loc=0x238
24802
24803         local start_time=$(date +%s.%N)
24804         $dd_cmd bs=1M count=$blocks oflag=sync ||
24805                 error "fake dd $read_write error"
24806         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
24807
24808         if [ "$read_write" = "write" ]; then
24809                 # verify file size
24810                 cancel_lru_locks osc
24811                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
24812                         error "$tfile size not $blocks MB"
24813         fi
24814         do_facet ost1 $LCTL set_param fail_loc=0
24815
24816         echo "fake $read_write $duration_fake vs. normal $read_write" \
24817                 "$duration in seconds"
24818         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
24819                 error_not_in_vm "fake write is slower"
24820
24821         $LCTL set_param -n debug="$saved_debug"
24822         rm -f $DIR/$tfile
24823 }
24824 test_399a() { # LU-7655 for OST fake write
24825         remote_ost_nodsh && skip "remote OST with nodsh"
24826
24827         test_fake_rw write
24828 }
24829 run_test 399a "fake write should not be slower than normal write"
24830
24831 test_399b() { # LU-8726 for OST fake read
24832         remote_ost_nodsh && skip "remote OST with nodsh"
24833         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
24834                 skip_env "ldiskfs only test"
24835         fi
24836
24837         test_fake_rw read
24838 }
24839 run_test 399b "fake read should not be slower than normal read"
24840
24841 test_400a() { # LU-1606, was conf-sanity test_74
24842         if ! which $CC > /dev/null 2>&1; then
24843                 skip_env "$CC is not installed"
24844         fi
24845
24846         local extra_flags=''
24847         local out=$TMP/$tfile
24848         local prefix=/usr/include/lustre
24849         local prog
24850
24851         # Oleg removes c files in his test rig so test if any c files exist
24852         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24853                 skip_env "Needed c test files are missing"
24854
24855         if ! [[ -d $prefix ]]; then
24856                 # Assume we're running in tree and fixup the include path.
24857                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24858                 extra_flags+=" -L$LUSTRE/utils/.lib"
24859         fi
24860
24861         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24862                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24863                         error "client api broken"
24864         done
24865         rm -f $out
24866 }
24867 run_test 400a "Lustre client api program can compile and link"
24868
24869 test_400b() { # LU-1606, LU-5011
24870         local header
24871         local out=$TMP/$tfile
24872         local prefix=/usr/include/linux/lustre
24873
24874         # We use a hard coded prefix so that this test will not fail
24875         # when run in tree. There are headers in lustre/include/lustre/
24876         # that are not packaged (like lustre_idl.h) and have more
24877         # complicated include dependencies (like config.h and lnet/types.h).
24878         # Since this test about correct packaging we just skip them when
24879         # they don't exist (see below) rather than try to fixup cppflags.
24880
24881         if ! which $CC > /dev/null 2>&1; then
24882                 skip_env "$CC is not installed"
24883         fi
24884
24885         for header in $prefix/*.h; do
24886                 if ! [[ -f "$header" ]]; then
24887                         continue
24888                 fi
24889
24890                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24891                         continue # lustre_ioctl.h is internal header
24892                 fi
24893
24894                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24895                         error "cannot compile '$header'"
24896         done
24897         rm -f $out
24898 }
24899 run_test 400b "packaged headers can be compiled"
24900
24901 test_401a() { #LU-7437
24902         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
24903         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
24904
24905         #count the number of parameters by "list_param -R"
24906         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
24907         #count the number of parameters by listing proc files
24908         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
24909         echo "proc_dirs='$proc_dirs'"
24910         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
24911         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
24912                       sort -u | wc -l)
24913
24914         [ $params -eq $procs ] ||
24915                 error "found $params parameters vs. $procs proc files"
24916
24917         # test the list_param -D option only returns directories
24918         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
24919         #count the number of parameters by listing proc directories
24920         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
24921                 sort -u | wc -l)
24922
24923         [ $params -eq $procs ] ||
24924                 error "found $params parameters vs. $procs proc files"
24925 }
24926 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
24927
24928 test_401b() {
24929         # jobid_var may not allow arbitrary values, so use jobid_name
24930         # if available
24931         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24932                 local testname=jobid_name tmp='testing%p'
24933         else
24934                 local testname=jobid_var tmp=testing
24935         fi
24936
24937         local save=$($LCTL get_param -n $testname)
24938
24939         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
24940                 error "no error returned when setting bad parameters"
24941
24942         local jobid_new=$($LCTL get_param -n foe $testname baz)
24943         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
24944
24945         $LCTL set_param -n fog=bam $testname=$save bat=fog
24946         local jobid_old=$($LCTL get_param -n foe $testname bag)
24947         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
24948 }
24949 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
24950
24951 test_401c() {
24952         # jobid_var may not allow arbitrary values, so use jobid_name
24953         # if available
24954         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24955                 local testname=jobid_name
24956         else
24957                 local testname=jobid_var
24958         fi
24959
24960         local jobid_var_old=$($LCTL get_param -n $testname)
24961         local jobid_var_new
24962
24963         $LCTL set_param $testname= &&
24964                 error "no error returned for 'set_param a='"
24965
24966         jobid_var_new=$($LCTL get_param -n $testname)
24967         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24968                 error "$testname was changed by setting without value"
24969
24970         $LCTL set_param $testname &&
24971                 error "no error returned for 'set_param a'"
24972
24973         jobid_var_new=$($LCTL get_param -n $testname)
24974         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24975                 error "$testname was changed by setting without value"
24976 }
24977 run_test 401c "Verify 'lctl set_param' without value fails in either format."
24978
24979 test_401d() {
24980         # jobid_var may not allow arbitrary values, so use jobid_name
24981         # if available
24982         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24983                 local testname=jobid_name new_value='foo=bar%p'
24984         else
24985                 local testname=jobid_var new_valuie=foo=bar
24986         fi
24987
24988         local jobid_var_old=$($LCTL get_param -n $testname)
24989         local jobid_var_new
24990
24991         $LCTL set_param $testname=$new_value ||
24992                 error "'set_param a=b' did not accept a value containing '='"
24993
24994         jobid_var_new=$($LCTL get_param -n $testname)
24995         [[ "$jobid_var_new" == "$new_value" ]] ||
24996                 error "'set_param a=b' failed on a value containing '='"
24997
24998         # Reset the $testname to test the other format
24999         $LCTL set_param $testname=$jobid_var_old
25000         jobid_var_new=$($LCTL get_param -n $testname)
25001         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25002                 error "failed to reset $testname"
25003
25004         $LCTL set_param $testname $new_value ||
25005                 error "'set_param a b' did not accept a value containing '='"
25006
25007         jobid_var_new=$($LCTL get_param -n $testname)
25008         [[ "$jobid_var_new" == "$new_value" ]] ||
25009                 error "'set_param a b' failed on a value containing '='"
25010
25011         $LCTL set_param $testname $jobid_var_old
25012         jobid_var_new=$($LCTL get_param -n $testname)
25013         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25014                 error "failed to reset $testname"
25015 }
25016 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
25017
25018 test_401e() { # LU-14779
25019         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
25020                 error "lctl list_param MGC* failed"
25021         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
25022         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
25023                 error "lctl get_param lru_size failed"
25024 }
25025 run_test 401e "verify 'lctl get_param' works with NID in parameter"
25026
25027 test_402() {
25028         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
25029         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
25030                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
25031         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
25032                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
25033                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
25034         remote_mds_nodsh && skip "remote MDS with nodsh"
25035
25036         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
25037 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
25038         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
25039         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
25040                 echo "Touch failed - OK"
25041 }
25042 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
25043
25044 test_403() {
25045         local file1=$DIR/$tfile.1
25046         local file2=$DIR/$tfile.2
25047         local tfile=$TMP/$tfile
25048
25049         rm -f $file1 $file2 $tfile
25050
25051         touch $file1
25052         ln $file1 $file2
25053
25054         # 30 sec OBD_TIMEOUT in ll_getattr()
25055         # right before populating st_nlink
25056         $LCTL set_param fail_loc=0x80001409
25057         stat -c %h $file1 > $tfile &
25058
25059         # create an alias, drop all locks and reclaim the dentry
25060         < $file2
25061         cancel_lru_locks mdc
25062         cancel_lru_locks osc
25063         sysctl -w vm.drop_caches=2
25064
25065         wait
25066
25067         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25068
25069         rm -f $tfile $file1 $file2
25070 }
25071 run_test 403 "i_nlink should not drop to zero due to aliasing"
25072
25073 test_404() { # LU-6601
25074         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25075                 skip "Need server version newer than 2.8.52"
25076         remote_mds_nodsh && skip "remote MDS with nodsh"
25077
25078         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25079                 awk '/osp .*-osc-MDT/ { print $4}')
25080
25081         local osp
25082         for osp in $mosps; do
25083                 echo "Deactivate: " $osp
25084                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25085                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25086                         awk -vp=$osp '$4 == p { print $2 }')
25087                 [ $stat = IN ] || {
25088                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25089                         error "deactivate error"
25090                 }
25091                 echo "Activate: " $osp
25092                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25093                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25094                         awk -vp=$osp '$4 == p { print $2 }')
25095                 [ $stat = UP ] || {
25096                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25097                         error "activate error"
25098                 }
25099         done
25100 }
25101 run_test 404 "validate manual {de}activated works properly for OSPs"
25102
25103 test_405() {
25104         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25105         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25106                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25107                         skip "Layout swap lock is not supported"
25108
25109         check_swap_layouts_support
25110         check_swap_layout_no_dom $DIR
25111
25112         test_mkdir $DIR/$tdir
25113         swap_lock_test -d $DIR/$tdir ||
25114                 error "One layout swap locked test failed"
25115 }
25116 run_test 405 "Various layout swap lock tests"
25117
25118 test_406() {
25119         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25120         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25121         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25123         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25124                 skip "Need MDS version at least 2.8.50"
25125
25126         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25127         local test_pool=$TESTNAME
25128
25129         pool_add $test_pool || error "pool_add failed"
25130         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25131                 error "pool_add_targets failed"
25132
25133         save_layout_restore_at_exit $MOUNT
25134
25135         # parent set default stripe count only, child will stripe from both
25136         # parent and fs default
25137         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25138                 error "setstripe $MOUNT failed"
25139         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25140         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25141         for i in $(seq 10); do
25142                 local f=$DIR/$tdir/$tfile.$i
25143                 touch $f || error "touch failed"
25144                 local count=$($LFS getstripe -c $f)
25145                 [ $count -eq $OSTCOUNT ] ||
25146                         error "$f stripe count $count != $OSTCOUNT"
25147                 local offset=$($LFS getstripe -i $f)
25148                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25149                 local size=$($LFS getstripe -S $f)
25150                 [ $size -eq $((def_stripe_size * 2)) ] ||
25151                         error "$f stripe size $size != $((def_stripe_size * 2))"
25152                 local pool=$($LFS getstripe -p $f)
25153                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25154         done
25155
25156         # change fs default striping, delete parent default striping, now child
25157         # will stripe from new fs default striping only
25158         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25159                 error "change $MOUNT default stripe failed"
25160         $LFS setstripe -c 0 $DIR/$tdir ||
25161                 error "delete $tdir default stripe failed"
25162         for i in $(seq 11 20); do
25163                 local f=$DIR/$tdir/$tfile.$i
25164                 touch $f || error "touch $f failed"
25165                 local count=$($LFS getstripe -c $f)
25166                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25167                 local offset=$($LFS getstripe -i $f)
25168                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25169                 local size=$($LFS getstripe -S $f)
25170                 [ $size -eq $def_stripe_size ] ||
25171                         error "$f stripe size $size != $def_stripe_size"
25172                 local pool=$($LFS getstripe -p $f)
25173                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25174         done
25175
25176         unlinkmany $DIR/$tdir/$tfile. 1 20
25177
25178         local f=$DIR/$tdir/$tfile
25179         pool_remove_all_targets $test_pool $f
25180         pool_remove $test_pool $f
25181 }
25182 run_test 406 "DNE support fs default striping"
25183
25184 test_407() {
25185         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25186         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25187                 skip "Need MDS version at least 2.8.55"
25188         remote_mds_nodsh && skip "remote MDS with nodsh"
25189
25190         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25191                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25192         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25193                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25194         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25195
25196         #define OBD_FAIL_DT_TXN_STOP    0x2019
25197         for idx in $(seq $MDSCOUNT); do
25198                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25199         done
25200         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25201         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25202                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25203         true
25204 }
25205 run_test 407 "transaction fail should cause operation fail"
25206
25207 test_408() {
25208         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25209
25210         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25211         lctl set_param fail_loc=0x8000040a
25212         # let ll_prepare_partial_page() fail
25213         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25214
25215         rm -f $DIR/$tfile
25216
25217         # create at least 100 unused inodes so that
25218         # shrink_icache_memory(0) should not return 0
25219         touch $DIR/$tfile-{0..100}
25220         rm -f $DIR/$tfile-{0..100}
25221         sync
25222
25223         echo 2 > /proc/sys/vm/drop_caches
25224 }
25225 run_test 408 "drop_caches should not hang due to page leaks"
25226
25227 test_409()
25228 {
25229         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25230
25231         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25232         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25233         touch $DIR/$tdir/guard || error "(2) Fail to create"
25234
25235         local PREFIX=$(str_repeat 'A' 128)
25236         echo "Create 1K hard links start at $(date)"
25237         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25238                 error "(3) Fail to hard link"
25239
25240         echo "Links count should be right although linkEA overflow"
25241         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25242         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25243         [ $linkcount -eq 1001 ] ||
25244                 error "(5) Unexpected hard links count: $linkcount"
25245
25246         echo "List all links start at $(date)"
25247         ls -l $DIR/$tdir/foo > /dev/null ||
25248                 error "(6) Fail to list $DIR/$tdir/foo"
25249
25250         echo "Unlink hard links start at $(date)"
25251         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25252                 error "(7) Fail to unlink"
25253         echo "Unlink hard links finished at $(date)"
25254 }
25255 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25256
25257 test_410()
25258 {
25259         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25260                 skip "Need client version at least 2.9.59"
25261         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25262                 skip "Need MODULES build"
25263
25264         # Create a file, and stat it from the kernel
25265         local testfile=$DIR/$tfile
25266         touch $testfile
25267
25268         local run_id=$RANDOM
25269         local my_ino=$(stat --format "%i" $testfile)
25270
25271         # Try to insert the module. This will always fail as the
25272         # module is designed to not be inserted.
25273         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25274             &> /dev/null
25275
25276         # Anything but success is a test failure
25277         dmesg | grep -q \
25278             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25279             error "no inode match"
25280 }
25281 run_test 410 "Test inode number returned from kernel thread"
25282
25283 cleanup_test411_cgroup() {
25284         trap 0
25285         rmdir "$1"
25286 }
25287
25288 test_411() {
25289         local cg_basedir=/sys/fs/cgroup/memory
25290         # LU-9966
25291         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25292                 skip "no setup for cgroup"
25293
25294         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25295                 error "test file creation failed"
25296         cancel_lru_locks osc
25297
25298         # Create a very small memory cgroup to force a slab allocation error
25299         local cgdir=$cg_basedir/osc_slab_alloc
25300         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25301         trap "cleanup_test411_cgroup $cgdir" EXIT
25302         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25303         echo 1M > $cgdir/memory.limit_in_bytes
25304
25305         # Should not LBUG, just be killed by oom-killer
25306         # dd will return 0 even allocation failure in some environment.
25307         # So don't check return value
25308         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25309         cleanup_test411_cgroup $cgdir
25310
25311         return 0
25312 }
25313 run_test 411 "Slab allocation error with cgroup does not LBUG"
25314
25315 test_412() {
25316         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25317         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25318                 skip "Need server version at least 2.10.55"
25319
25320         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25321                 error "mkdir failed"
25322         $LFS getdirstripe $DIR/$tdir
25323         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25324         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25325                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25326         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25327         [ $stripe_count -eq 2 ] ||
25328                 error "expect 2 get $stripe_count"
25329
25330         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25331
25332         local index
25333         local index2
25334
25335         # subdirs should be on the same MDT as parent
25336         for i in $(seq 0 $((MDSCOUNT - 1))); do
25337                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25338                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25339                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25340                 (( index == i )) || error "mdt$i/sub on MDT$index"
25341         done
25342
25343         # stripe offset -1, ditto
25344         for i in {1..10}; do
25345                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25346                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25347                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25348                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25349                 (( index == index2 )) ||
25350                         error "qos$i on MDT$index, sub on MDT$index2"
25351         done
25352
25353         local testdir=$DIR/$tdir/inherit
25354
25355         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25356         # inherit 2 levels
25357         for i in 1 2; do
25358                 testdir=$testdir/s$i
25359                 mkdir $testdir || error "mkdir $testdir failed"
25360                 index=$($LFS getstripe -m $testdir)
25361                 (( index == 1 )) ||
25362                         error "$testdir on MDT$index"
25363         done
25364
25365         # not inherit any more
25366         testdir=$testdir/s3
25367         mkdir $testdir || error "mkdir $testdir failed"
25368         getfattr -d -m dmv $testdir | grep dmv &&
25369                 error "default LMV set on $testdir" || true
25370 }
25371 run_test 412 "mkdir on specific MDTs"
25372
25373 generate_uneven_mdts() {
25374         local threshold=$1
25375         local lmv_qos_maxage
25376         local lod_qos_maxage
25377         local ffree
25378         local bavail
25379         local max
25380         local min
25381         local max_index
25382         local min_index
25383         local tmp
25384         local i
25385
25386         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25387         $LCTL set_param lmv.*.qos_maxage=1
25388         stack_trap "$LCTL set_param \
25389                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25390         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25391                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25392         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25393                 lod.*.mdt_qos_maxage=1
25394         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25395                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25396
25397         echo
25398         echo "Check for uneven MDTs: "
25399
25400         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25401         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25402         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25403
25404         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25405         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25406         max_index=0
25407         min_index=0
25408         for ((i = 1; i < ${#ffree[@]}; i++)); do
25409                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25410                 if [ $tmp -gt $max ]; then
25411                         max=$tmp
25412                         max_index=$i
25413                 fi
25414                 if [ $tmp -lt $min ]; then
25415                         min=$tmp
25416                         min_index=$i
25417                 fi
25418         done
25419
25420         (( ${ffree[min_index]} > 0 )) ||
25421                 skip "no free files in MDT$min_index"
25422         (( ${ffree[min_index]} < 10000000 )) ||
25423                 skip "too many free files in MDT$min_index"
25424
25425         # Check if we need to generate uneven MDTs
25426         local diff=$(((max - min) * 100 / min))
25427         local testdir=$DIR/$tdir-fillmdt
25428         local start
25429
25430         mkdir -p $testdir
25431
25432         i=0
25433         while (( diff < threshold )); do
25434                 # generate uneven MDTs, create till $threshold% diff
25435                 echo -n "weight diff=$diff% must be > $threshold% ..."
25436                 echo "Fill MDT$min_index with 1000 files: loop $i"
25437                 testdir=$DIR/$tdir-fillmdt/$i
25438                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
25439                         error "mkdir $testdir failed"
25440                 $LFS setstripe -E 1M -L mdt $testdir ||
25441                         error "setstripe $testdir failed"
25442                 start=$SECONDS
25443                 for F in f.{0..999}; do
25444                         dd if=/dev/zero of=$testdir/$F bs=64K count=1 > \
25445                                 /dev/null 2>&1 || error "dd $F failed"
25446                 done
25447
25448                 # wait for QOS to update
25449                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25450
25451                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25452                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25453                 max=$(((${ffree[max_index]} >> 8) *
25454                         (${bavail[max_index]} * bsize >> 16)))
25455                 min=$(((${ffree[min_index]} >> 8) *
25456                         (${bavail[min_index]} * bsize >> 16)))
25457                 diff=$(((max - min) * 100 / min))
25458                 i=$((i + 1))
25459         done
25460
25461         echo "MDT filesfree available: ${ffree[*]}"
25462         echo "MDT blocks available: ${bavail[*]}"
25463         echo "weight diff=$diff%"
25464 }
25465
25466 test_qos_mkdir() {
25467         local mkdir_cmd=$1
25468         local stripe_count=$2
25469         local mdts=$(comma_list $(mdts_nodes))
25470
25471         local testdir
25472         local lmv_qos_prio_free
25473         local lmv_qos_threshold_rr
25474         local lmv_qos_maxage
25475         local lod_qos_prio_free
25476         local lod_qos_threshold_rr
25477         local lod_qos_maxage
25478         local count
25479         local i
25480
25481         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25482         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25483         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25484                 head -n1)
25485         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25486         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25487         stack_trap "$LCTL set_param \
25488                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25489         stack_trap "$LCTL set_param \
25490                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25491         stack_trap "$LCTL set_param \
25492                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25493
25494         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25495                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25496         lod_qos_prio_free=${lod_qos_prio_free%%%}
25497         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25498                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25499         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25500         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25501                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25502         stack_trap "do_nodes $mdts $LCTL set_param \
25503                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25504         stack_trap "do_nodes $mdts $LCTL set_param \
25505                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25506         stack_trap "do_nodes $mdts $LCTL set_param \
25507                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25508
25509         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25510         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25511
25512         testdir=$DIR/$tdir-s$stripe_count/rr
25513
25514         local stripe_index=$($LFS getstripe -m $testdir)
25515         local test_mkdir_rr=true
25516
25517         getfattr -d -m dmv -e hex $testdir | grep dmv
25518         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25519                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25520                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25521                         test_mkdir_rr=false
25522         fi
25523
25524         echo
25525         $test_mkdir_rr &&
25526                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25527                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25528
25529         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25530         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25531                 eval $mkdir_cmd $testdir/subdir$i ||
25532                         error "$mkdir_cmd subdir$i failed"
25533         done
25534
25535         for (( i = 0; i < $MDSCOUNT; i++ )); do
25536                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25537                 echo "$count directories created on MDT$i"
25538                 if $test_mkdir_rr; then
25539                         (( $count == 100 )) ||
25540                                 error "subdirs are not evenly distributed"
25541                 elif (( $i == $stripe_index )); then
25542                         (( $count == 100 * MDSCOUNT )) ||
25543                                 error "$count subdirs created on MDT$i"
25544                 else
25545                         (( $count == 0 )) ||
25546                                 error "$count subdirs created on MDT$i"
25547                 fi
25548
25549                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25550                         count=$($LFS getdirstripe $testdir/* |
25551                                 grep -c -P "^\s+$i\t")
25552                         echo "$count stripes created on MDT$i"
25553                         # deviation should < 5% of average
25554                         (( $count >= 95 * stripe_count &&
25555                            $count <= 105 * stripe_count)) ||
25556                                 error "stripes are not evenly distributed"
25557                 fi
25558         done
25559
25560         echo
25561         echo "Check for uneven MDTs: "
25562
25563         local ffree
25564         local bavail
25565         local max
25566         local min
25567         local max_index
25568         local min_index
25569         local tmp
25570
25571         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25572         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25573         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25574
25575         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25576         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25577         max_index=0
25578         min_index=0
25579         for ((i = 1; i < ${#ffree[@]}; i++)); do
25580                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25581                 if [ $tmp -gt $max ]; then
25582                         max=$tmp
25583                         max_index=$i
25584                 fi
25585                 if [ $tmp -lt $min ]; then
25586                         min=$tmp
25587                         min_index=$i
25588                 fi
25589         done
25590
25591         (( ${ffree[min_index]} > 0 )) ||
25592                 skip "no free files in MDT$min_index"
25593         (( ${ffree[min_index]} < 10000000 )) ||
25594                 skip "too many free files in MDT$min_index"
25595
25596         echo "MDT filesfree available: ${ffree[*]}"
25597         echo "MDT blocks available: ${bavail[*]}"
25598         echo "weight diff=$(((max - min) * 100 / min))%"
25599         echo
25600         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25601
25602         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25603         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25604         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25605         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25606         # decrease statfs age, so that it can be updated in time
25607         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25608         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25609
25610         sleep 1
25611
25612         testdir=$DIR/$tdir-s$stripe_count/qos
25613         local num=200
25614
25615         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25616         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25617                 eval $mkdir_cmd $testdir/subdir$i ||
25618                         error "$mkdir_cmd subdir$i failed"
25619         done
25620
25621         max=0
25622         for (( i = 0; i < $MDSCOUNT; i++ )); do
25623                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25624                 (( count > max )) && max=$count
25625                 echo "$count directories created on MDT$i"
25626         done
25627
25628         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25629
25630         # D-value should > 10% of averge
25631         (( max - min > num / 10 )) ||
25632                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25633
25634         # ditto for stripes
25635         if (( stripe_count > 1 )); then
25636                 max=0
25637                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25638                         count=$($LFS getdirstripe $testdir/* |
25639                                 grep -c -P "^\s+$i\t")
25640                         (( count > max )) && max=$count
25641                         echo "$count stripes created on MDT$i"
25642                 done
25643
25644                 min=$($LFS getdirstripe $testdir/* |
25645                         grep -c -P "^\s+$min_index\t")
25646                 (( max - min > num * stripe_count / 10 )) ||
25647                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25648         fi
25649 }
25650
25651 most_full_mdt() {
25652         local ffree
25653         local bavail
25654         local bsize
25655         local min
25656         local min_index
25657         local tmp
25658
25659         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25660         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25661         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25662
25663         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25664         min_index=0
25665         for ((i = 1; i < ${#ffree[@]}; i++)); do
25666                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25667                 (( tmp < min )) && min=$tmp && min_index=$i
25668         done
25669
25670         echo -n $min_index
25671 }
25672
25673 test_413a() {
25674         [ $MDSCOUNT -lt 2 ] &&
25675                 skip "We need at least 2 MDTs for this test"
25676
25677         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25678                 skip "Need server version at least 2.12.52"
25679
25680         local stripe_count
25681
25682         generate_uneven_mdts 100
25683         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25684                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25685                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25686                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25687                         error "mkdir failed"
25688                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25689         done
25690 }
25691 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25692
25693 test_413b() {
25694         [ $MDSCOUNT -lt 2 ] &&
25695                 skip "We need at least 2 MDTs for this test"
25696
25697         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25698                 skip "Need server version at least 2.12.52"
25699
25700         local testdir
25701         local stripe_count
25702
25703         generate_uneven_mdts 100
25704         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25705                 testdir=$DIR/$tdir-s$stripe_count
25706                 mkdir $testdir || error "mkdir $testdir failed"
25707                 mkdir $testdir/rr || error "mkdir rr failed"
25708                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25709                         error "mkdir qos failed"
25710                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25711                         $testdir/rr || error "setdirstripe rr failed"
25712                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25713                         error "setdirstripe failed"
25714                 test_qos_mkdir "mkdir" $stripe_count
25715         done
25716 }
25717 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25718
25719 test_413c() {
25720         (( $MDSCOUNT >= 2 )) ||
25721                 skip "We need at least 2 MDTs for this test"
25722
25723         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25724                 skip "Need server version at least 2.14.51"
25725
25726         local testdir
25727         local inherit
25728         local inherit_rr
25729
25730         testdir=$DIR/${tdir}-s1
25731         mkdir $testdir || error "mkdir $testdir failed"
25732         mkdir $testdir/rr || error "mkdir rr failed"
25733         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25734         # default max_inherit is -1, default max_inherit_rr is 0
25735         $LFS setdirstripe -D -c 1 $testdir/rr ||
25736                 error "setdirstripe rr failed"
25737         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25738                 error "setdirstripe qos failed"
25739         test_qos_mkdir "mkdir" 1
25740
25741         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25742         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25743         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25744         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25745         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25746
25747         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25748         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25749         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25750         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25751         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25752         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25753         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25754                 error "level2 shouldn't have default LMV" || true
25755 }
25756 run_test 413c "mkdir with default LMV max inherit rr"
25757
25758 test_413d() {
25759         (( MDSCOUNT >= 2 )) ||
25760                 skip "We need at least 2 MDTs for this test"
25761
25762         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25763                 skip "Need server version at least 2.14.51"
25764
25765         local lmv_qos_threshold_rr
25766
25767         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25768                 head -n1)
25769         stack_trap "$LCTL set_param \
25770                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
25771
25772         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25773         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25774         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
25775                 error "$tdir shouldn't have default LMV"
25776         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
25777                 error "mkdir sub failed"
25778
25779         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
25780
25781         (( count == 100 )) || error "$count subdirs on MDT0"
25782 }
25783 run_test 413d "inherit ROOT default LMV"
25784
25785 test_413e() {
25786         (( MDSCOUNT >= 2 )) ||
25787                 skip "We need at least 2 MDTs for this test"
25788         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25789                 skip "Need server version at least 2.14.55"
25790
25791         local testdir=$DIR/$tdir
25792         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
25793         local max_inherit
25794         local sub_max_inherit
25795
25796         mkdir -p $testdir || error "failed to create $testdir"
25797
25798         # set default max-inherit to -1 if stripe count is 0 or 1
25799         $LFS setdirstripe -D -c 1 $testdir ||
25800                 error "failed to set default LMV"
25801         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25802         (( max_inherit == -1 )) ||
25803                 error "wrong max_inherit value $max_inherit"
25804
25805         # set default max_inherit to a fixed value if stripe count is not 0 or 1
25806         $LFS setdirstripe -D -c -1 $testdir ||
25807                 error "failed to set default LMV"
25808         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25809         (( max_inherit > 0 )) ||
25810                 error "wrong max_inherit value $max_inherit"
25811
25812         # and the subdir will decrease the max_inherit by 1
25813         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
25814         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
25815         (( sub_max_inherit == max_inherit - 1)) ||
25816                 error "wrong max-inherit of subdir $sub_max_inherit"
25817
25818         # check specified --max-inherit and warning message
25819         stack_trap "rm -f $tmpfile"
25820         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
25821                 error "failed to set default LMV"
25822         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25823         (( max_inherit == -1 )) ||
25824                 error "wrong max_inherit value $max_inherit"
25825
25826         # check the warning messages
25827         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
25828                 error "failed to detect warning string"
25829         fi
25830 }
25831 run_test 413e "check default max-inherit value"
25832
25833 test_fs_dmv_inherit()
25834 {
25835         local testdir=$DIR/$tdir
25836
25837         local count
25838         local inherit
25839         local inherit_rr
25840
25841         for i in 1 2 3; do
25842                 mkdir $testdir || error "mkdir $testdir failed"
25843                 count=$($LFS getdirstripe -D -c $testdir)
25844                 (( count == 1 )) ||
25845                         error "$testdir default LMV count mismatch $count != 1"
25846                 inherit=$($LFS getdirstripe -D -X $testdir)
25847                 (( inherit == 3 - i )) ||
25848                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
25849                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
25850                 (( inherit_rr == 3 - i )) ||
25851                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
25852                 testdir=$testdir/sub
25853         done
25854
25855         mkdir $testdir || error "mkdir $testdir failed"
25856         count=$($LFS getdirstripe -D -c $testdir)
25857         (( count == 0 )) ||
25858                 error "$testdir default LMV count not zero: $count"
25859 }
25860
25861 test_413f() {
25862         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
25863
25864         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25865                 skip "Need server version at least 2.14.55"
25866
25867         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
25868                 error "dump $DIR default LMV failed"
25869         stack_trap "setfattr --restore=$TMP/dmv.ea"
25870
25871         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
25872                 error "set $DIR default LMV failed"
25873
25874         test_fs_dmv_inherit
25875 }
25876 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
25877
25878 test_413g() {
25879         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
25880
25881         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
25882         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
25883                 error "dump $DIR default LMV failed"
25884         stack_trap "setfattr --restore=$TMP/dmv.ea"
25885
25886         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
25887                 error "set $DIR default LMV failed"
25888
25889         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
25890                 error "mount $MOUNT2 failed"
25891         stack_trap "umount_client $MOUNT2"
25892
25893         local saved_DIR=$DIR
25894
25895         export DIR=$MOUNT2
25896
25897         stack_trap "export DIR=$saved_DIR"
25898
25899         # first check filesystem-wide default LMV inheritance
25900         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
25901
25902         # then check subdirs are spread to all MDTs
25903         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
25904
25905         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
25906
25907         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
25908 }
25909 run_test 413g "enforce ROOT default LMV on subdir mount"
25910
25911 test_413z() {
25912         local pids=""
25913         local subdir
25914         local pid
25915
25916         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
25917                 unlinkmany $subdir/f. 1000 &
25918                 pids="$pids $!"
25919         done
25920
25921         for pid in $pids; do
25922                 wait $pid
25923         done
25924 }
25925 run_test 413z "413 test cleanup"
25926
25927 test_414() {
25928 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
25929         $LCTL set_param fail_loc=0x80000521
25930         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25931         rm -f $DIR/$tfile
25932 }
25933 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
25934
25935 test_415() {
25936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25937         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25938                 skip "Need server version at least 2.11.52"
25939
25940         # LU-11102
25941         local total
25942         local setattr_pid
25943         local start_time
25944         local end_time
25945         local duration
25946
25947         total=500
25948         # this test may be slow on ZFS
25949         [ "$mds1_FSTYPE" == "zfs" ] && total=50
25950
25951         # though this test is designed for striped directory, let's test normal
25952         # directory too since lock is always saved as CoS lock.
25953         test_mkdir $DIR/$tdir || error "mkdir $tdir"
25954         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
25955
25956         (
25957                 while true; do
25958                         touch $DIR/$tdir
25959                 done
25960         ) &
25961         setattr_pid=$!
25962
25963         start_time=$(date +%s)
25964         for i in $(seq $total); do
25965                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
25966                         > /dev/null
25967         done
25968         end_time=$(date +%s)
25969         duration=$((end_time - start_time))
25970
25971         kill -9 $setattr_pid
25972
25973         echo "rename $total files took $duration sec"
25974         [ $duration -lt 100 ] || error "rename took $duration sec"
25975 }
25976 run_test 415 "lock revoke is not missing"
25977
25978 test_416() {
25979         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25980                 skip "Need server version at least 2.11.55"
25981
25982         # define OBD_FAIL_OSD_TXN_START    0x19a
25983         do_facet mds1 lctl set_param fail_loc=0x19a
25984
25985         lfs mkdir -c $MDSCOUNT $DIR/$tdir
25986
25987         true
25988 }
25989 run_test 416 "transaction start failure won't cause system hung"
25990
25991 cleanup_417() {
25992         trap 0
25993         do_nodes $(comma_list $(mdts_nodes)) \
25994                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
25995         do_nodes $(comma_list $(mdts_nodes)) \
25996                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
25997         do_nodes $(comma_list $(mdts_nodes)) \
25998                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
25999 }
26000
26001 test_417() {
26002         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26003         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
26004                 skip "Need MDS version at least 2.11.56"
26005
26006         trap cleanup_417 RETURN EXIT
26007
26008         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
26009         do_nodes $(comma_list $(mdts_nodes)) \
26010                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
26011         $LFS migrate -m 0 $DIR/$tdir.1 &&
26012                 error "migrate dir $tdir.1 should fail"
26013
26014         do_nodes $(comma_list $(mdts_nodes)) \
26015                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
26016         $LFS mkdir -i 1 $DIR/$tdir.2 &&
26017                 error "create remote dir $tdir.2 should fail"
26018
26019         do_nodes $(comma_list $(mdts_nodes)) \
26020                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
26021         $LFS mkdir -c 2 $DIR/$tdir.3 &&
26022                 error "create striped dir $tdir.3 should fail"
26023         true
26024 }
26025 run_test 417 "disable remote dir, striped dir and dir migration"
26026
26027 # Checks that the outputs of df [-i] and lfs df [-i] match
26028 #
26029 # usage: check_lfs_df <blocks | inodes> <mountpoint>
26030 check_lfs_df() {
26031         local dir=$2
26032         local inodes
26033         local df_out
26034         local lfs_df_out
26035         local count
26036         local passed=false
26037
26038         # blocks or inodes
26039         [ "$1" == "blocks" ] && inodes= || inodes="-i"
26040
26041         for count in {1..100}; do
26042                 do_nodes "$CLIENTS" \
26043                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26044                 sync; sleep 0.2
26045
26046                 # read the lines of interest
26047                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
26048                         error "df $inodes $dir | tail -n +2 failed"
26049                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
26050                         error "lfs df $inodes $dir | grep summary: failed"
26051
26052                 # skip first substrings of each output as they are different
26053                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
26054                 # compare the two outputs
26055                 passed=true
26056                 #  skip "available" on MDT until LU-13997 is fixed.
26057                 #for i in {1..5}; do
26058                 for i in 1 2 4 5; do
26059                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
26060                 done
26061                 $passed && break
26062         done
26063
26064         if ! $passed; then
26065                 df -P $inodes $dir
26066                 echo
26067                 lfs df $inodes $dir
26068                 error "df and lfs df $1 output mismatch: "      \
26069                       "df ${inodes}: ${df_out[*]}, "            \
26070                       "lfs df ${inodes}: ${lfs_df_out[*]}"
26071         fi
26072 }
26073
26074 test_418() {
26075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26076
26077         local dir=$DIR/$tdir
26078         local numfiles=$((RANDOM % 4096 + 2))
26079         local numblocks=$((RANDOM % 256 + 1))
26080
26081         wait_delete_completed
26082         test_mkdir $dir
26083
26084         # check block output
26085         check_lfs_df blocks $dir
26086         # check inode output
26087         check_lfs_df inodes $dir
26088
26089         # create a single file and retest
26090         echo "Creating a single file and testing"
26091         createmany -o $dir/$tfile- 1 &>/dev/null ||
26092                 error "creating 1 file in $dir failed"
26093         check_lfs_df blocks $dir
26094         check_lfs_df inodes $dir
26095
26096         # create a random number of files
26097         echo "Creating $((numfiles - 1)) files and testing"
26098         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
26099                 error "creating $((numfiles - 1)) files in $dir failed"
26100
26101         # write a random number of blocks to the first test file
26102         echo "Writing $numblocks 4K blocks and testing"
26103         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26104                 count=$numblocks &>/dev/null ||
26105                 error "dd to $dir/${tfile}-0 failed"
26106
26107         # retest
26108         check_lfs_df blocks $dir
26109         check_lfs_df inodes $dir
26110
26111         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
26112                 error "unlinking $numfiles files in $dir failed"
26113 }
26114 run_test 418 "df and lfs df outputs match"
26115
26116 test_419()
26117 {
26118         local dir=$DIR/$tdir
26119
26120         mkdir -p $dir
26121         touch $dir/file
26122
26123         cancel_lru_locks mdc
26124
26125         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26126         $LCTL set_param fail_loc=0x1410
26127         cat $dir/file
26128         $LCTL set_param fail_loc=0
26129         rm -rf $dir
26130 }
26131 run_test 419 "Verify open file by name doesn't crash kernel"
26132
26133 test_420()
26134 {
26135         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26136                 skip "Need MDS version at least 2.12.53"
26137
26138         local SAVE_UMASK=$(umask)
26139         local dir=$DIR/$tdir
26140         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26141
26142         mkdir -p $dir
26143         umask 0000
26144         mkdir -m03777 $dir/testdir
26145         ls -dn $dir/testdir
26146         # Need to remove trailing '.' when SELinux is enabled
26147         local dirperms=$(ls -dn $dir/testdir |
26148                          awk '{ sub(/\.$/, "", $1); print $1}')
26149         [ $dirperms == "drwxrwsrwt" ] ||
26150                 error "incorrect perms on $dir/testdir"
26151
26152         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26153                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26154         ls -n $dir/testdir/testfile
26155         local fileperms=$(ls -n $dir/testdir/testfile |
26156                           awk '{ sub(/\.$/, "", $1); print $1}')
26157         [ $fileperms == "-rwxr-xr-x" ] ||
26158                 error "incorrect perms on $dir/testdir/testfile"
26159
26160         umask $SAVE_UMASK
26161 }
26162 run_test 420 "clear SGID bit on non-directories for non-members"
26163
26164 test_421a() {
26165         local cnt
26166         local fid1
26167         local fid2
26168
26169         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26170                 skip "Need MDS version at least 2.12.54"
26171
26172         test_mkdir $DIR/$tdir
26173         createmany -o $DIR/$tdir/f 3
26174         cnt=$(ls -1 $DIR/$tdir | wc -l)
26175         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26176
26177         fid1=$(lfs path2fid $DIR/$tdir/f1)
26178         fid2=$(lfs path2fid $DIR/$tdir/f2)
26179         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26180
26181         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26182         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26183
26184         cnt=$(ls -1 $DIR/$tdir | wc -l)
26185         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26186
26187         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26188         createmany -o $DIR/$tdir/f 3
26189         cnt=$(ls -1 $DIR/$tdir | wc -l)
26190         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26191
26192         fid1=$(lfs path2fid $DIR/$tdir/f1)
26193         fid2=$(lfs path2fid $DIR/$tdir/f2)
26194         echo "remove using fsname $FSNAME"
26195         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26196
26197         cnt=$(ls -1 $DIR/$tdir | wc -l)
26198         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26199 }
26200 run_test 421a "simple rm by fid"
26201
26202 test_421b() {
26203         local cnt
26204         local FID1
26205         local FID2
26206
26207         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26208                 skip "Need MDS version at least 2.12.54"
26209
26210         test_mkdir $DIR/$tdir
26211         createmany -o $DIR/$tdir/f 3
26212         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26213         MULTIPID=$!
26214
26215         FID1=$(lfs path2fid $DIR/$tdir/f1)
26216         FID2=$(lfs path2fid $DIR/$tdir/f2)
26217         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26218
26219         kill -USR1 $MULTIPID
26220         wait
26221
26222         cnt=$(ls $DIR/$tdir | wc -l)
26223         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26224 }
26225 run_test 421b "rm by fid on open file"
26226
26227 test_421c() {
26228         local cnt
26229         local FIDS
26230
26231         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26232                 skip "Need MDS version at least 2.12.54"
26233
26234         test_mkdir $DIR/$tdir
26235         createmany -o $DIR/$tdir/f 3
26236         touch $DIR/$tdir/$tfile
26237         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26238         cnt=$(ls -1 $DIR/$tdir | wc -l)
26239         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26240
26241         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26242         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26243
26244         cnt=$(ls $DIR/$tdir | wc -l)
26245         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26246 }
26247 run_test 421c "rm by fid against hardlinked files"
26248
26249 test_421d() {
26250         local cnt
26251         local FIDS
26252
26253         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26254                 skip "Need MDS version at least 2.12.54"
26255
26256         test_mkdir $DIR/$tdir
26257         createmany -o $DIR/$tdir/f 4097
26258         cnt=$(ls -1 $DIR/$tdir | wc -l)
26259         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26260
26261         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26262         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26263
26264         cnt=$(ls $DIR/$tdir | wc -l)
26265         rm -rf $DIR/$tdir
26266         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26267 }
26268 run_test 421d "rmfid en masse"
26269
26270 test_421e() {
26271         local cnt
26272         local FID
26273
26274         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26275         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26276                 skip "Need MDS version at least 2.12.54"
26277
26278         mkdir -p $DIR/$tdir
26279         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26280         createmany -o $DIR/$tdir/striped_dir/f 512
26281         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26282         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26283
26284         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26285                 sed "s/[/][^:]*://g")
26286         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26287
26288         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26289         rm -rf $DIR/$tdir
26290         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26291 }
26292 run_test 421e "rmfid in DNE"
26293
26294 test_421f() {
26295         local cnt
26296         local FID
26297
26298         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26299                 skip "Need MDS version at least 2.12.54"
26300
26301         test_mkdir $DIR/$tdir
26302         touch $DIR/$tdir/f
26303         cnt=$(ls -1 $DIR/$tdir | wc -l)
26304         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26305
26306         FID=$(lfs path2fid $DIR/$tdir/f)
26307         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26308         # rmfid should fail
26309         cnt=$(ls -1 $DIR/$tdir | wc -l)
26310         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26311
26312         chmod a+rw $DIR/$tdir
26313         ls -la $DIR/$tdir
26314         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26315         # rmfid should fail
26316         cnt=$(ls -1 $DIR/$tdir | wc -l)
26317         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26318
26319         rm -f $DIR/$tdir/f
26320         $RUNAS touch $DIR/$tdir/f
26321         FID=$(lfs path2fid $DIR/$tdir/f)
26322         echo "rmfid as root"
26323         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26324         cnt=$(ls -1 $DIR/$tdir | wc -l)
26325         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26326
26327         rm -f $DIR/$tdir/f
26328         $RUNAS touch $DIR/$tdir/f
26329         cnt=$(ls -1 $DIR/$tdir | wc -l)
26330         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26331         FID=$(lfs path2fid $DIR/$tdir/f)
26332         # rmfid w/o user_fid2path mount option should fail
26333         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26334         cnt=$(ls -1 $DIR/$tdir | wc -l)
26335         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26336
26337         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26338         stack_trap "rmdir $tmpdir"
26339         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26340                 error "failed to mount client'"
26341         stack_trap "umount_client $tmpdir"
26342
26343         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26344         # rmfid should succeed
26345         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26346         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26347
26348         # rmfid shouldn't allow to remove files due to dir's permission
26349         chmod a+rwx $tmpdir/$tdir
26350         touch $tmpdir/$tdir/f
26351         ls -la $tmpdir/$tdir
26352         FID=$(lfs path2fid $tmpdir/$tdir/f)
26353         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26354         return 0
26355 }
26356 run_test 421f "rmfid checks permissions"
26357
26358 test_421g() {
26359         local cnt
26360         local FIDS
26361
26362         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26363         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26364                 skip "Need MDS version at least 2.12.54"
26365
26366         mkdir -p $DIR/$tdir
26367         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26368         createmany -o $DIR/$tdir/striped_dir/f 512
26369         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26370         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26371
26372         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26373                 sed "s/[/][^:]*://g")
26374
26375         rm -f $DIR/$tdir/striped_dir/f1*
26376         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26377         removed=$((512 - cnt))
26378
26379         # few files have been just removed, so we expect
26380         # rmfid to fail on their fids
26381         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26382         [ $removed != $errors ] && error "$errors != $removed"
26383
26384         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26385         rm -rf $DIR/$tdir
26386         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26387 }
26388 run_test 421g "rmfid to return errors properly"
26389
26390 test_422() {
26391         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26392         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26393         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26394         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26395         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26396
26397         local amc=$(at_max_get client)
26398         local amo=$(at_max_get mds1)
26399         local timeout=`lctl get_param -n timeout`
26400
26401         at_max_set 0 client
26402         at_max_set 0 mds1
26403
26404 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26405         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26406                         fail_val=$(((2*timeout + 10)*1000))
26407         touch $DIR/$tdir/d3/file &
26408         sleep 2
26409 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26410         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26411                         fail_val=$((2*timeout + 5))
26412         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26413         local pid=$!
26414         sleep 1
26415         kill -9 $pid
26416         sleep $((2 * timeout))
26417         echo kill $pid
26418         kill -9 $pid
26419         lctl mark touch
26420         touch $DIR/$tdir/d2/file3
26421         touch $DIR/$tdir/d2/file4
26422         touch $DIR/$tdir/d2/file5
26423
26424         wait
26425         at_max_set $amc client
26426         at_max_set $amo mds1
26427
26428         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26429         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26430                 error "Watchdog is always throttled"
26431 }
26432 run_test 422 "kill a process with RPC in progress"
26433
26434 stat_test() {
26435     df -h $MOUNT &
26436     df -h $MOUNT &
26437     df -h $MOUNT &
26438     df -h $MOUNT &
26439     df -h $MOUNT &
26440     df -h $MOUNT &
26441 }
26442
26443 test_423() {
26444     local _stats
26445     # ensure statfs cache is expired
26446     sleep 2;
26447
26448     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26449     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26450
26451     return 0
26452 }
26453 run_test 423 "statfs should return a right data"
26454
26455 test_424() {
26456 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26457         $LCTL set_param fail_loc=0x80000522
26458         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26459         rm -f $DIR/$tfile
26460 }
26461 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26462
26463 test_425() {
26464         test_mkdir -c -1 $DIR/$tdir
26465         $LFS setstripe -c -1 $DIR/$tdir
26466
26467         lru_resize_disable "" 100
26468         stack_trap "lru_resize_enable" EXIT
26469
26470         sleep 5
26471
26472         for i in $(seq $((MDSCOUNT * 125))); do
26473                 local t=$DIR/$tdir/$tfile_$i
26474
26475                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26476                         error_noexit "Create file $t"
26477         done
26478         stack_trap "rm -rf $DIR/$tdir" EXIT
26479
26480         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26481                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26482                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26483
26484                 [ $lock_count -le $lru_size ] ||
26485                         error "osc lock count $lock_count > lru size $lru_size"
26486         done
26487
26488         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26489                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26490                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26491
26492                 [ $lock_count -le $lru_size ] ||
26493                         error "mdc lock count $lock_count > lru size $lru_size"
26494         done
26495 }
26496 run_test 425 "lock count should not exceed lru size"
26497
26498 test_426() {
26499         splice-test -r $DIR/$tfile
26500         splice-test -rd $DIR/$tfile
26501         splice-test $DIR/$tfile
26502         splice-test -d $DIR/$tfile
26503 }
26504 run_test 426 "splice test on Lustre"
26505
26506 test_427() {
26507         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26508         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26509                 skip "Need MDS version at least 2.12.4"
26510         local log
26511
26512         mkdir $DIR/$tdir
26513         mkdir $DIR/$tdir/1
26514         mkdir $DIR/$tdir/2
26515         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26516         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26517
26518         $LFS getdirstripe $DIR/$tdir/1/dir
26519
26520         #first setfattr for creating updatelog
26521         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26522
26523 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26524         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26525         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26526         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26527
26528         sleep 2
26529         fail mds2
26530         wait_recovery_complete mds2 $((2*TIMEOUT))
26531
26532         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26533         echo $log | grep "get update log failed" &&
26534                 error "update log corruption is detected" || true
26535 }
26536 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26537
26538 test_428() {
26539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26540         local cache_limit=$CACHE_MAX
26541
26542         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26543         $LCTL set_param -n llite.*.max_cached_mb=64
26544
26545         mkdir $DIR/$tdir
26546         $LFS setstripe -c 1 $DIR/$tdir
26547         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26548         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26549         #test write
26550         for f in $(seq 4); do
26551                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26552         done
26553         wait
26554
26555         cancel_lru_locks osc
26556         # Test read
26557         for f in $(seq 4); do
26558                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26559         done
26560         wait
26561 }
26562 run_test 428 "large block size IO should not hang"
26563
26564 test_429() { # LU-7915 / LU-10948
26565         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26566         local testfile=$DIR/$tfile
26567         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26568         local new_flag=1
26569         local first_rpc
26570         local second_rpc
26571         local third_rpc
26572
26573         $LCTL get_param $ll_opencache_threshold_count ||
26574                 skip "client does not have opencache parameter"
26575
26576         set_opencache $new_flag
26577         stack_trap "restore_opencache"
26578         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26579                 error "enable opencache failed"
26580         touch $testfile
26581         # drop MDC DLM locks
26582         cancel_lru_locks mdc
26583         # clear MDC RPC stats counters
26584         $LCTL set_param $mdc_rpcstats=clear
26585
26586         # According to the current implementation, we need to run 3 times
26587         # open & close file to verify if opencache is enabled correctly.
26588         # 1st, RPCs are sent for lookup/open and open handle is released on
26589         #      close finally.
26590         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26591         #      so open handle won't be released thereafter.
26592         # 3rd, No RPC is sent out.
26593         $MULTIOP $testfile oc || error "multiop failed"
26594         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26595         echo "1st: $first_rpc RPCs in flight"
26596
26597         $MULTIOP $testfile oc || error "multiop failed"
26598         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26599         echo "2nd: $second_rpc RPCs in flight"
26600
26601         $MULTIOP $testfile oc || error "multiop failed"
26602         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26603         echo "3rd: $third_rpc RPCs in flight"
26604
26605         #verify no MDC RPC is sent
26606         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26607 }
26608 run_test 429 "verify if opencache flag on client side does work"
26609
26610 lseek_test_430() {
26611         local offset
26612         local file=$1
26613
26614         # data at [200K, 400K)
26615         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26616                 error "256K->512K dd fails"
26617         # data at [2M, 3M)
26618         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26619                 error "2M->3M dd fails"
26620         # data at [4M, 5M)
26621         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26622                 error "4M->5M dd fails"
26623         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26624         # start at first component hole #1
26625         printf "Seeking hole from 1000 ... "
26626         offset=$(lseek_test -l 1000 $file)
26627         echo $offset
26628         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26629         printf "Seeking data from 1000 ... "
26630         offset=$(lseek_test -d 1000 $file)
26631         echo $offset
26632         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26633
26634         # start at first component data block
26635         printf "Seeking hole from 300000 ... "
26636         offset=$(lseek_test -l 300000 $file)
26637         echo $offset
26638         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26639         printf "Seeking data from 300000 ... "
26640         offset=$(lseek_test -d 300000 $file)
26641         echo $offset
26642         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26643
26644         # start at the first component but beyond end of object size
26645         printf "Seeking hole from 1000000 ... "
26646         offset=$(lseek_test -l 1000000 $file)
26647         echo $offset
26648         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26649         printf "Seeking data from 1000000 ... "
26650         offset=$(lseek_test -d 1000000 $file)
26651         echo $offset
26652         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26653
26654         # start at second component stripe 2 (empty file)
26655         printf "Seeking hole from 1500000 ... "
26656         offset=$(lseek_test -l 1500000 $file)
26657         echo $offset
26658         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26659         printf "Seeking data from 1500000 ... "
26660         offset=$(lseek_test -d 1500000 $file)
26661         echo $offset
26662         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26663
26664         # start at second component stripe 1 (all data)
26665         printf "Seeking hole from 3000000 ... "
26666         offset=$(lseek_test -l 3000000 $file)
26667         echo $offset
26668         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26669         printf "Seeking data from 3000000 ... "
26670         offset=$(lseek_test -d 3000000 $file)
26671         echo $offset
26672         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26673
26674         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26675                 error "2nd dd fails"
26676         echo "Add data block at 640K...1280K"
26677
26678         # start at before new data block, in hole
26679         printf "Seeking hole from 600000 ... "
26680         offset=$(lseek_test -l 600000 $file)
26681         echo $offset
26682         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26683         printf "Seeking data from 600000 ... "
26684         offset=$(lseek_test -d 600000 $file)
26685         echo $offset
26686         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26687
26688         # start at the first component new data block
26689         printf "Seeking hole from 1000000 ... "
26690         offset=$(lseek_test -l 1000000 $file)
26691         echo $offset
26692         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26693         printf "Seeking data from 1000000 ... "
26694         offset=$(lseek_test -d 1000000 $file)
26695         echo $offset
26696         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26697
26698         # start at second component stripe 2, new data
26699         printf "Seeking hole from 1200000 ... "
26700         offset=$(lseek_test -l 1200000 $file)
26701         echo $offset
26702         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26703         printf "Seeking data from 1200000 ... "
26704         offset=$(lseek_test -d 1200000 $file)
26705         echo $offset
26706         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
26707
26708         # start beyond file end
26709         printf "Using offset > filesize ... "
26710         lseek_test -l 4000000 $file && error "lseek should fail"
26711         printf "Using offset > filesize ... "
26712         lseek_test -d 4000000 $file && error "lseek should fail"
26713
26714         printf "Done\n\n"
26715 }
26716
26717 test_430a() {
26718         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
26719                 skip "MDT does not support SEEK_HOLE"
26720
26721         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26722                 skip "OST does not support SEEK_HOLE"
26723
26724         local file=$DIR/$tdir/$tfile
26725
26726         mkdir -p $DIR/$tdir
26727
26728         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
26729         # OST stripe #1 will have continuous data at [1M, 3M)
26730         # OST stripe #2 is empty
26731         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
26732         lseek_test_430 $file
26733         rm $file
26734         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
26735         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
26736         lseek_test_430 $file
26737         rm $file
26738         $LFS setstripe -c2 -S 512K $file
26739         echo "Two stripes, stripe size 512K"
26740         lseek_test_430 $file
26741         rm $file
26742         # FLR with stale mirror
26743         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
26744                        -N -c2 -S 1M $file
26745         echo "Mirrored file:"
26746         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
26747         echo "Plain 2 stripes 1M"
26748         lseek_test_430 $file
26749         rm $file
26750 }
26751 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
26752
26753 test_430b() {
26754         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26755                 skip "OST does not support SEEK_HOLE"
26756
26757         local offset
26758         local file=$DIR/$tdir/$tfile
26759
26760         mkdir -p $DIR/$tdir
26761         # Empty layout lseek should fail
26762         $MCREATE $file
26763         # seek from 0
26764         printf "Seeking hole from 0 ... "
26765         lseek_test -l 0 $file && error "lseek should fail"
26766         printf "Seeking data from 0 ... "
26767         lseek_test -d 0 $file && error "lseek should fail"
26768         rm $file
26769
26770         # 1M-hole file
26771         $LFS setstripe -E 1M -c2 -E eof $file
26772         $TRUNCATE $file 1048576
26773         printf "Seeking hole from 1000000 ... "
26774         offset=$(lseek_test -l 1000000 $file)
26775         echo $offset
26776         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26777         printf "Seeking data from 1000000 ... "
26778         lseek_test -d 1000000 $file && error "lseek should fail"
26779         rm $file
26780
26781         # full component followed by non-inited one
26782         $LFS setstripe -E 1M -c2 -E eof $file
26783         dd if=/dev/urandom of=$file bs=1M count=1
26784         printf "Seeking hole from 1000000 ... "
26785         offset=$(lseek_test -l 1000000 $file)
26786         echo $offset
26787         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26788         printf "Seeking hole from 1048576 ... "
26789         lseek_test -l 1048576 $file && error "lseek should fail"
26790         # init second component and truncate back
26791         echo "123" >> $file
26792         $TRUNCATE $file 1048576
26793         printf "Seeking hole from 1000000 ... "
26794         offset=$(lseek_test -l 1000000 $file)
26795         echo $offset
26796         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26797         printf "Seeking hole from 1048576 ... "
26798         lseek_test -l 1048576 $file && error "lseek should fail"
26799         # boundary checks for big values
26800         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
26801         offset=$(lseek_test -d 0 $file.10g)
26802         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
26803         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
26804         offset=$(lseek_test -d 0 $file.100g)
26805         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
26806         return 0
26807 }
26808 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
26809
26810 test_430c() {
26811         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26812                 skip "OST does not support SEEK_HOLE"
26813
26814         local file=$DIR/$tdir/$tfile
26815         local start
26816
26817         mkdir -p $DIR/$tdir
26818         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
26819
26820         # cp version 8.33+ prefers lseek over fiemap
26821         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
26822                 start=$SECONDS
26823                 time cp $file /dev/null
26824                 (( SECONDS - start < 5 )) ||
26825                         error "cp: too long runtime $((SECONDS - start))"
26826
26827         fi
26828         # tar version 1.29+ supports SEEK_HOLE/DATA
26829         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
26830                 start=$SECONDS
26831                 time tar cS $file - | cat > /dev/null
26832                 (( SECONDS - start < 5 )) ||
26833                         error "tar: too long runtime $((SECONDS - start))"
26834         fi
26835 }
26836 run_test 430c "lseek: external tools check"
26837
26838 test_431() { # LU-14187
26839         local file=$DIR/$tdir/$tfile
26840
26841         mkdir -p $DIR/$tdir
26842         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
26843         dd if=/dev/urandom of=$file bs=4k count=1
26844         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
26845         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
26846         #define OBD_FAIL_OST_RESTART_IO 0x251
26847         do_facet ost1 "$LCTL set_param fail_loc=0x251"
26848         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
26849         cp $file $file.0
26850         cancel_lru_locks
26851         sync_all_data
26852         echo 3 > /proc/sys/vm/drop_caches
26853         diff  $file $file.0 || error "data diff"
26854 }
26855 run_test 431 "Restart transaction for IO"
26856
26857 cleanup_test_432() {
26858         do_facet mgs $LCTL nodemap_activate 0
26859         wait_nm_sync active
26860 }
26861
26862 test_432() {
26863         local tmpdir=$TMP/dir432
26864
26865         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
26866                 skip "Need MDS version at least 2.14.52"
26867
26868         stack_trap cleanup_test_432 EXIT
26869         mkdir $DIR/$tdir
26870         mkdir $tmpdir
26871
26872         do_facet mgs $LCTL nodemap_activate 1
26873         wait_nm_sync active
26874         do_facet mgs $LCTL nodemap_modify --name default \
26875                 --property admin --value 1
26876         do_facet mgs $LCTL nodemap_modify --name default \
26877                 --property trusted --value 1
26878         cancel_lru_locks mdc
26879         wait_nm_sync default admin_nodemap
26880         wait_nm_sync default trusted_nodemap
26881
26882         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
26883                grep -ci "Operation not permitted") -ne 0 ]; then
26884                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
26885         fi
26886 }
26887 run_test 432 "mv dir from outside Lustre"
26888
26889 test_433() {
26890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26891
26892         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
26893                 skip "inode cache not supported"
26894
26895         $LCTL set_param llite.*.inode_cache=0
26896         stack_trap "$LCTL set_param llite.*.inode_cache=1"
26897
26898         local count=256
26899         local before
26900         local after
26901
26902         cancel_lru_locks mdc
26903         test_mkdir $DIR/$tdir || error "mkdir $tdir"
26904         createmany -m $DIR/$tdir/f $count
26905         createmany -d $DIR/$tdir/d $count
26906         ls -l $DIR/$tdir > /dev/null
26907         stack_trap "rm -rf $DIR/$tdir"
26908
26909         before=$(num_objects)
26910         cancel_lru_locks mdc
26911         after=$(num_objects)
26912
26913         # sometimes even @before is less than 2 * count
26914         while (( before - after < count )); do
26915                 sleep 1
26916                 after=$(num_objects)
26917                 wait=$((wait + 1))
26918                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
26919                 if (( wait > 60 )); then
26920                         error "inode slab grew from $before to $after"
26921                 fi
26922         done
26923
26924         echo "lustre_inode_cache $before objs before lock cancel, $after after"
26925 }
26926 run_test 433 "ldlm lock cancel releases dentries and inodes"
26927
26928 prep_801() {
26929         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26930         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26931                 skip "Need server version at least 2.9.55"
26932
26933         start_full_debug_logging
26934 }
26935
26936 post_801() {
26937         stop_full_debug_logging
26938 }
26939
26940 barrier_stat() {
26941         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26942                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26943                            awk '/The barrier for/ { print $7 }')
26944                 echo $st
26945         else
26946                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
26947                 echo \'$st\'
26948         fi
26949 }
26950
26951 barrier_expired() {
26952         local expired
26953
26954         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26955                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26956                           awk '/will be expired/ { print $7 }')
26957         else
26958                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
26959         fi
26960
26961         echo $expired
26962 }
26963
26964 test_801a() {
26965         prep_801
26966
26967         echo "Start barrier_freeze at: $(date)"
26968         #define OBD_FAIL_BARRIER_DELAY          0x2202
26969         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26970         # Do not reduce barrier time - See LU-11873
26971         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
26972
26973         sleep 2
26974         local b_status=$(barrier_stat)
26975         echo "Got barrier status at: $(date)"
26976         [ "$b_status" = "'freezing_p1'" ] ||
26977                 error "(1) unexpected barrier status $b_status"
26978
26979         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26980         wait
26981         b_status=$(barrier_stat)
26982         [ "$b_status" = "'frozen'" ] ||
26983                 error "(2) unexpected barrier status $b_status"
26984
26985         local expired=$(barrier_expired)
26986         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
26987         sleep $((expired + 3))
26988
26989         b_status=$(barrier_stat)
26990         [ "$b_status" = "'expired'" ] ||
26991                 error "(3) unexpected barrier status $b_status"
26992
26993         # Do not reduce barrier time - See LU-11873
26994         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
26995                 error "(4) fail to freeze barrier"
26996
26997         b_status=$(barrier_stat)
26998         [ "$b_status" = "'frozen'" ] ||
26999                 error "(5) unexpected barrier status $b_status"
27000
27001         echo "Start barrier_thaw at: $(date)"
27002         #define OBD_FAIL_BARRIER_DELAY          0x2202
27003         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27004         do_facet mgs $LCTL barrier_thaw $FSNAME &
27005
27006         sleep 2
27007         b_status=$(barrier_stat)
27008         echo "Got barrier status at: $(date)"
27009         [ "$b_status" = "'thawing'" ] ||
27010                 error "(6) unexpected barrier status $b_status"
27011
27012         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27013         wait
27014         b_status=$(barrier_stat)
27015         [ "$b_status" = "'thawed'" ] ||
27016                 error "(7) unexpected barrier status $b_status"
27017
27018         #define OBD_FAIL_BARRIER_FAILURE        0x2203
27019         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
27020         do_facet mgs $LCTL barrier_freeze $FSNAME
27021
27022         b_status=$(barrier_stat)
27023         [ "$b_status" = "'failed'" ] ||
27024                 error "(8) unexpected barrier status $b_status"
27025
27026         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
27027         do_facet mgs $LCTL barrier_thaw $FSNAME
27028
27029         post_801
27030 }
27031 run_test 801a "write barrier user interfaces and stat machine"
27032
27033 test_801b() {
27034         prep_801
27035
27036         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27037         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
27038         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
27039         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
27040         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
27041
27042         cancel_lru_locks mdc
27043
27044         # 180 seconds should be long enough
27045         do_facet mgs $LCTL barrier_freeze $FSNAME 180
27046
27047         local b_status=$(barrier_stat)
27048         [ "$b_status" = "'frozen'" ] ||
27049                 error "(6) unexpected barrier status $b_status"
27050
27051         mkdir $DIR/$tdir/d0/d10 &
27052         mkdir_pid=$!
27053
27054         touch $DIR/$tdir/d1/f13 &
27055         touch_pid=$!
27056
27057         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
27058         ln_pid=$!
27059
27060         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
27061         mv_pid=$!
27062
27063         rm -f $DIR/$tdir/d4/f12 &
27064         rm_pid=$!
27065
27066         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
27067
27068         # To guarantee taht the 'stat' is not blocked
27069         b_status=$(barrier_stat)
27070         [ "$b_status" = "'frozen'" ] ||
27071                 error "(8) unexpected barrier status $b_status"
27072
27073         # let above commands to run at background
27074         sleep 5
27075
27076         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
27077         ps -p $touch_pid || error "(10) touch should be blocked"
27078         ps -p $ln_pid || error "(11) link should be blocked"
27079         ps -p $mv_pid || error "(12) rename should be blocked"
27080         ps -p $rm_pid || error "(13) unlink should be blocked"
27081
27082         b_status=$(barrier_stat)
27083         [ "$b_status" = "'frozen'" ] ||
27084                 error "(14) unexpected barrier status $b_status"
27085
27086         do_facet mgs $LCTL barrier_thaw $FSNAME
27087         b_status=$(barrier_stat)
27088         [ "$b_status" = "'thawed'" ] ||
27089                 error "(15) unexpected barrier status $b_status"
27090
27091         wait $mkdir_pid || error "(16) mkdir should succeed"
27092         wait $touch_pid || error "(17) touch should succeed"
27093         wait $ln_pid || error "(18) link should succeed"
27094         wait $mv_pid || error "(19) rename should succeed"
27095         wait $rm_pid || error "(20) unlink should succeed"
27096
27097         post_801
27098 }
27099 run_test 801b "modification will be blocked by write barrier"
27100
27101 test_801c() {
27102         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27103
27104         prep_801
27105
27106         stop mds2 || error "(1) Fail to stop mds2"
27107
27108         do_facet mgs $LCTL barrier_freeze $FSNAME 30
27109
27110         local b_status=$(barrier_stat)
27111         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
27112                 do_facet mgs $LCTL barrier_thaw $FSNAME
27113                 error "(2) unexpected barrier status $b_status"
27114         }
27115
27116         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27117                 error "(3) Fail to rescan barrier bitmap"
27118
27119         # Do not reduce barrier time - See LU-11873
27120         do_facet mgs $LCTL barrier_freeze $FSNAME 20
27121
27122         b_status=$(barrier_stat)
27123         [ "$b_status" = "'frozen'" ] ||
27124                 error "(4) unexpected barrier status $b_status"
27125
27126         do_facet mgs $LCTL barrier_thaw $FSNAME
27127         b_status=$(barrier_stat)
27128         [ "$b_status" = "'thawed'" ] ||
27129                 error "(5) unexpected barrier status $b_status"
27130
27131         local devname=$(mdsdevname 2)
27132
27133         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
27134
27135         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27136                 error "(7) Fail to rescan barrier bitmap"
27137
27138         post_801
27139 }
27140 run_test 801c "rescan barrier bitmap"
27141
27142 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
27143 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
27144 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
27145 saved_MOUNT_OPTS=$MOUNT_OPTS
27146
27147 cleanup_802a() {
27148         trap 0
27149
27150         stopall
27151         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
27152         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
27153         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
27154         MOUNT_OPTS=$saved_MOUNT_OPTS
27155         setupall
27156 }
27157
27158 test_802a() {
27159         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
27160         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27161         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27162                 skip "Need server version at least 2.9.55"
27163
27164         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
27165
27166         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27167
27168         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27169                 error "(2) Fail to copy"
27170
27171         trap cleanup_802a EXIT
27172
27173         # sync by force before remount as readonly
27174         sync; sync_all_data; sleep 3; sync_all_data
27175
27176         stopall
27177
27178         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
27179         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
27180         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
27181
27182         echo "Mount the server as read only"
27183         setupall server_only || error "(3) Fail to start servers"
27184
27185         echo "Mount client without ro should fail"
27186         mount_client $MOUNT &&
27187                 error "(4) Mount client without 'ro' should fail"
27188
27189         echo "Mount client with ro should succeed"
27190         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
27191         mount_client $MOUNT ||
27192                 error "(5) Mount client with 'ro' should succeed"
27193
27194         echo "Modify should be refused"
27195         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27196
27197         echo "Read should be allowed"
27198         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27199                 error "(7) Read should succeed under ro mode"
27200
27201         cleanup_802a
27202 }
27203 run_test 802a "simulate readonly device"
27204
27205 test_802b() {
27206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27207         remote_mds_nodsh && skip "remote MDS with nodsh"
27208
27209         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27210                 skip "readonly option not available"
27211
27212         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27213
27214         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27215                 error "(2) Fail to copy"
27216
27217         # write back all cached data before setting MDT to readonly
27218         cancel_lru_locks
27219         sync_all_data
27220
27221         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27222         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27223
27224         echo "Modify should be refused"
27225         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27226
27227         echo "Read should be allowed"
27228         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27229                 error "(7) Read should succeed under ro mode"
27230
27231         # disable readonly
27232         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27233 }
27234 run_test 802b "be able to set MDTs to readonly"
27235
27236 test_803a() {
27237         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27238         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27239                 skip "MDS needs to be newer than 2.10.54"
27240
27241         mkdir_on_mdt0 $DIR/$tdir
27242         # Create some objects on all MDTs to trigger related logs objects
27243         for idx in $(seq $MDSCOUNT); do
27244                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27245                         $DIR/$tdir/dir${idx} ||
27246                         error "Fail to create $DIR/$tdir/dir${idx}"
27247         done
27248
27249         sync; sleep 3
27250         wait_delete_completed # ensure old test cleanups are finished
27251         echo "before create:"
27252         $LFS df -i $MOUNT
27253         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27254
27255         for i in {1..10}; do
27256                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27257                         error "Fail to create $DIR/$tdir/foo$i"
27258         done
27259
27260         sync; sleep 3
27261         echo "after create:"
27262         $LFS df -i $MOUNT
27263         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27264
27265         # allow for an llog to be cleaned up during the test
27266         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27267                 error "before ($before_used) + 10 > after ($after_used)"
27268
27269         for i in {1..10}; do
27270                 rm -rf $DIR/$tdir/foo$i ||
27271                         error "Fail to remove $DIR/$tdir/foo$i"
27272         done
27273
27274         sleep 3 # avoid MDT return cached statfs
27275         wait_delete_completed
27276         echo "after unlink:"
27277         $LFS df -i $MOUNT
27278         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27279
27280         # allow for an llog to be created during the test
27281         [ $after_used -le $((before_used + 1)) ] ||
27282                 error "after ($after_used) > before ($before_used) + 1"
27283 }
27284 run_test 803a "verify agent object for remote object"
27285
27286 test_803b() {
27287         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27288         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27289                 skip "MDS needs to be newer than 2.13.56"
27290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27291
27292         for i in $(seq 0 $((MDSCOUNT - 1))); do
27293                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27294         done
27295
27296         local before=0
27297         local after=0
27298
27299         local tmp
27300
27301         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27302         for i in $(seq 0 $((MDSCOUNT - 1))); do
27303                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27304                         awk '/getattr/ { print $2 }')
27305                 before=$((before + tmp))
27306         done
27307         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27308         for i in $(seq 0 $((MDSCOUNT - 1))); do
27309                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27310                         awk '/getattr/ { print $2 }')
27311                 after=$((after + tmp))
27312         done
27313
27314         [ $before -eq $after ] || error "getattr count $before != $after"
27315 }
27316 run_test 803b "remote object can getattr from cache"
27317
27318 test_804() {
27319         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27320         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27321                 skip "MDS needs to be newer than 2.10.54"
27322         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27323
27324         mkdir -p $DIR/$tdir
27325         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27326                 error "Fail to create $DIR/$tdir/dir0"
27327
27328         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27329         local dev=$(mdsdevname 2)
27330
27331         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27332                 grep ${fid} || error "NOT found agent entry for dir0"
27333
27334         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27335                 error "Fail to create $DIR/$tdir/dir1"
27336
27337         touch $DIR/$tdir/dir1/foo0 ||
27338                 error "Fail to create $DIR/$tdir/dir1/foo0"
27339         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27340         local rc=0
27341
27342         for idx in $(seq $MDSCOUNT); do
27343                 dev=$(mdsdevname $idx)
27344                 do_facet mds${idx} \
27345                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27346                         grep ${fid} && rc=$idx
27347         done
27348
27349         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27350                 error "Fail to rename foo0 to foo1"
27351         if [ $rc -eq 0 ]; then
27352                 for idx in $(seq $MDSCOUNT); do
27353                         dev=$(mdsdevname $idx)
27354                         do_facet mds${idx} \
27355                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27356                         grep ${fid} && rc=$idx
27357                 done
27358         fi
27359
27360         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27361                 error "Fail to rename foo1 to foo2"
27362         if [ $rc -eq 0 ]; then
27363                 for idx in $(seq $MDSCOUNT); do
27364                         dev=$(mdsdevname $idx)
27365                         do_facet mds${idx} \
27366                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27367                         grep ${fid} && rc=$idx
27368                 done
27369         fi
27370
27371         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27372
27373         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27374                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27375         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27376                 error "Fail to rename foo2 to foo0"
27377         unlink $DIR/$tdir/dir1/foo0 ||
27378                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27379         rm -rf $DIR/$tdir/dir0 ||
27380                 error "Fail to rm $DIR/$tdir/dir0"
27381
27382         for idx in $(seq $MDSCOUNT); do
27383                 rc=0
27384
27385                 stop mds${idx}
27386                 dev=$(mdsdevname $idx)
27387                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27388                         rc=$?
27389                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27390                         error "mount mds$idx failed"
27391                 df $MOUNT > /dev/null 2>&1
27392
27393                 # e2fsck should not return error
27394                 [ $rc -eq 0 ] ||
27395                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27396         done
27397 }
27398 run_test 804 "verify agent entry for remote entry"
27399
27400 cleanup_805() {
27401         do_facet $SINGLEMDS zfs set quota=$old $fsset
27402         unlinkmany $DIR/$tdir/f- 1000000
27403         trap 0
27404 }
27405
27406 test_805() {
27407         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
27408         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
27409         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
27410                 skip "netfree not implemented before 0.7"
27411         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
27412                 skip "Need MDS version at least 2.10.57"
27413
27414         local fsset
27415         local freekb
27416         local usedkb
27417         local old
27418         local quota
27419         local pref="osd-zfs.$FSNAME-MDT0000."
27420
27421         # limit available space on MDS dataset to meet nospace issue
27422         # quickly. then ZFS 0.7.2 can use reserved space if asked
27423         # properly (using netfree flag in osd_declare_destroy()
27424         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
27425         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
27426                 gawk '{print $3}')
27427         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
27428         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
27429         let "usedkb=usedkb-freekb"
27430         let "freekb=freekb/2"
27431         if let "freekb > 5000"; then
27432                 let "freekb=5000"
27433         fi
27434         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
27435         trap cleanup_805 EXIT
27436         mkdir_on_mdt0 $DIR/$tdir
27437         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
27438                 error "Can't set PFL layout"
27439         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27440         rm -rf $DIR/$tdir || error "not able to remove"
27441         do_facet $SINGLEMDS zfs set quota=$old $fsset
27442         trap 0
27443 }
27444 run_test 805 "ZFS can remove from full fs"
27445
27446 # Size-on-MDS test
27447 check_lsom_data()
27448 {
27449         local file=$1
27450         local expect=$(stat -c %s $file)
27451
27452         check_lsom_size $1 $expect
27453
27454         local blocks=$($LFS getsom -b $file)
27455         expect=$(stat -c %b $file)
27456         [[ $blocks == $expect ]] ||
27457                 error "$file expected blocks: $expect, got: $blocks"
27458 }
27459
27460 check_lsom_size()
27461 {
27462         local size
27463         local expect=$2
27464
27465         cancel_lru_locks mdc
27466
27467         size=$($LFS getsom -s $1)
27468         [[ $size == $expect ]] ||
27469                 error "$file expected size: $expect, got: $size"
27470 }
27471
27472 test_806() {
27473         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27474                 skip "Need MDS version at least 2.11.52"
27475
27476         local bs=1048576
27477
27478         touch $DIR/$tfile || error "touch $tfile failed"
27479
27480         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27481         save_lustre_params client "llite.*.xattr_cache" > $save
27482         lctl set_param llite.*.xattr_cache=0
27483         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27484
27485         # single-threaded write
27486         echo "Test SOM for single-threaded write"
27487         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27488                 error "write $tfile failed"
27489         check_lsom_size $DIR/$tfile $bs
27490
27491         local num=32
27492         local size=$(($num * $bs))
27493         local offset=0
27494         local i
27495
27496         echo "Test SOM for single client multi-threaded($num) write"
27497         $TRUNCATE $DIR/$tfile 0
27498         for ((i = 0; i < $num; i++)); do
27499                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27500                 local pids[$i]=$!
27501                 offset=$((offset + $bs))
27502         done
27503         for (( i=0; i < $num; i++ )); do
27504                 wait ${pids[$i]}
27505         done
27506         check_lsom_size $DIR/$tfile $size
27507
27508         $TRUNCATE $DIR/$tfile 0
27509         for ((i = 0; i < $num; i++)); do
27510                 offset=$((offset - $bs))
27511                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27512                 local pids[$i]=$!
27513         done
27514         for (( i=0; i < $num; i++ )); do
27515                 wait ${pids[$i]}
27516         done
27517         check_lsom_size $DIR/$tfile $size
27518
27519         # multi-client writes
27520         num=$(get_node_count ${CLIENTS//,/ })
27521         size=$(($num * $bs))
27522         offset=0
27523         i=0
27524
27525         echo "Test SOM for multi-client ($num) writes"
27526         $TRUNCATE $DIR/$tfile 0
27527         for client in ${CLIENTS//,/ }; do
27528                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27529                 local pids[$i]=$!
27530                 i=$((i + 1))
27531                 offset=$((offset + $bs))
27532         done
27533         for (( i=0; i < $num; i++ )); do
27534                 wait ${pids[$i]}
27535         done
27536         check_lsom_size $DIR/$tfile $offset
27537
27538         i=0
27539         $TRUNCATE $DIR/$tfile 0
27540         for client in ${CLIENTS//,/ }; do
27541                 offset=$((offset - $bs))
27542                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27543                 local pids[$i]=$!
27544                 i=$((i + 1))
27545         done
27546         for (( i=0; i < $num; i++ )); do
27547                 wait ${pids[$i]}
27548         done
27549         check_lsom_size $DIR/$tfile $size
27550
27551         # verify truncate
27552         echo "Test SOM for truncate"
27553         $TRUNCATE $DIR/$tfile 1048576
27554         check_lsom_size $DIR/$tfile 1048576
27555         $TRUNCATE $DIR/$tfile 1234
27556         check_lsom_size $DIR/$tfile 1234
27557
27558         # verify SOM blocks count
27559         echo "Verify SOM block count"
27560         $TRUNCATE $DIR/$tfile 0
27561         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27562                 error "failed to write file $tfile"
27563         check_lsom_data $DIR/$tfile
27564 }
27565 run_test 806 "Verify Lazy Size on MDS"
27566
27567 test_807() {
27568         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27569         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27570                 skip "Need MDS version at least 2.11.52"
27571
27572         # Registration step
27573         changelog_register || error "changelog_register failed"
27574         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27575         changelog_users $SINGLEMDS | grep -q $cl_user ||
27576                 error "User $cl_user not found in changelog_users"
27577
27578         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27579         save_lustre_params client "llite.*.xattr_cache" > $save
27580         lctl set_param llite.*.xattr_cache=0
27581         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27582
27583         rm -rf $DIR/$tdir || error "rm $tdir failed"
27584         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27585         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27586         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27587         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27588                 error "truncate $tdir/trunc failed"
27589
27590         local bs=1048576
27591         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27592                 error "write $tfile failed"
27593
27594         # multi-client wirtes
27595         local num=$(get_node_count ${CLIENTS//,/ })
27596         local offset=0
27597         local i=0
27598
27599         echo "Test SOM for multi-client ($num) writes"
27600         touch $DIR/$tfile || error "touch $tfile failed"
27601         $TRUNCATE $DIR/$tfile 0
27602         for client in ${CLIENTS//,/ }; do
27603                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27604                 local pids[$i]=$!
27605                 i=$((i + 1))
27606                 offset=$((offset + $bs))
27607         done
27608         for (( i=0; i < $num; i++ )); do
27609                 wait ${pids[$i]}
27610         done
27611
27612         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27613         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27614         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27615         check_lsom_data $DIR/$tdir/trunc
27616         check_lsom_data $DIR/$tdir/single_dd
27617         check_lsom_data $DIR/$tfile
27618
27619         rm -rf $DIR/$tdir
27620         # Deregistration step
27621         changelog_deregister || error "changelog_deregister failed"
27622 }
27623 run_test 807 "verify LSOM syncing tool"
27624
27625 check_som_nologged()
27626 {
27627         local lines=$($LFS changelog $FSNAME-MDT0000 |
27628                 grep 'x=trusted.som' | wc -l)
27629         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27630 }
27631
27632 test_808() {
27633         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27634                 skip "Need MDS version at least 2.11.55"
27635
27636         # Registration step
27637         changelog_register || error "changelog_register failed"
27638
27639         touch $DIR/$tfile || error "touch $tfile failed"
27640         check_som_nologged
27641
27642         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27643                 error "write $tfile failed"
27644         check_som_nologged
27645
27646         $TRUNCATE $DIR/$tfile 1234
27647         check_som_nologged
27648
27649         $TRUNCATE $DIR/$tfile 1048576
27650         check_som_nologged
27651
27652         # Deregistration step
27653         changelog_deregister || error "changelog_deregister failed"
27654 }
27655 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27656
27657 check_som_nodata()
27658 {
27659         $LFS getsom $1
27660         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27661 }
27662
27663 test_809() {
27664         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27665                 skip "Need MDS version at least 2.11.56"
27666
27667         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27668                 error "failed to create DoM-only file $DIR/$tfile"
27669         touch $DIR/$tfile || error "touch $tfile failed"
27670         check_som_nodata $DIR/$tfile
27671
27672         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27673                 error "write $tfile failed"
27674         check_som_nodata $DIR/$tfile
27675
27676         $TRUNCATE $DIR/$tfile 1234
27677         check_som_nodata $DIR/$tfile
27678
27679         $TRUNCATE $DIR/$tfile 4097
27680         check_som_nodata $DIR/$file
27681 }
27682 run_test 809 "Verify no SOM xattr store for DoM-only files"
27683
27684 test_810() {
27685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27686         $GSS && skip_env "could not run with gss"
27687         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27688                 skip "OST < 2.12.58 doesn't align checksum"
27689
27690         set_checksums 1
27691         stack_trap "set_checksums $ORIG_CSUM" EXIT
27692         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27693
27694         local csum
27695         local before
27696         local after
27697         for csum in $CKSUM_TYPES; do
27698                 #define OBD_FAIL_OSC_NO_GRANT   0x411
27699                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
27700                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
27701                         eval set -- $i
27702                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
27703                         before=$(md5sum $DIR/$tfile)
27704                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
27705                         after=$(md5sum $DIR/$tfile)
27706                         [ "$before" == "$after" ] ||
27707                                 error "$csum: $before != $after bs=$1 seek=$2"
27708                 done
27709         done
27710 }
27711 run_test 810 "partial page writes on ZFS (LU-11663)"
27712
27713 test_812a() {
27714         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27715                 skip "OST < 2.12.51 doesn't support this fail_loc"
27716
27717         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27718         # ensure ost1 is connected
27719         stat $DIR/$tfile >/dev/null || error "can't stat"
27720         wait_osc_import_state client ost1 FULL
27721         # no locks, no reqs to let the connection idle
27722         cancel_lru_locks osc
27723
27724         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27725 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27726         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27727         wait_osc_import_state client ost1 CONNECTING
27728         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27729
27730         stat $DIR/$tfile >/dev/null || error "can't stat file"
27731 }
27732 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
27733
27734 test_812b() { # LU-12378
27735         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27736                 skip "OST < 2.12.51 doesn't support this fail_loc"
27737
27738         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
27739         # ensure ost1 is connected
27740         stat $DIR/$tfile >/dev/null || error "can't stat"
27741         wait_osc_import_state client ost1 FULL
27742         # no locks, no reqs to let the connection idle
27743         cancel_lru_locks osc
27744
27745         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27746 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27747         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27748         wait_osc_import_state client ost1 CONNECTING
27749         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27750
27751         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
27752         wait_osc_import_state client ost1 IDLE
27753 }
27754 run_test 812b "do not drop no resend request for idle connect"
27755
27756 test_812c() {
27757         local old
27758
27759         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
27760
27761         $LFS setstripe -c 1 -o 0 $DIR/$tfile
27762         $LFS getstripe $DIR/$tfile
27763         $LCTL set_param osc.*.idle_timeout=10
27764         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
27765         # ensure ost1 is connected
27766         stat $DIR/$tfile >/dev/null || error "can't stat"
27767         wait_osc_import_state client ost1 FULL
27768         # no locks, no reqs to let the connection idle
27769         cancel_lru_locks osc
27770
27771 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
27772         $LCTL set_param fail_loc=0x80000533
27773         sleep 15
27774         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
27775 }
27776 run_test 812c "idle import vs lock enqueue race"
27777
27778 test_813() {
27779         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
27780         [ -z "$file_heat_sav" ] && skip "no file heat support"
27781
27782         local readsample
27783         local writesample
27784         local readbyte
27785         local writebyte
27786         local readsample1
27787         local writesample1
27788         local readbyte1
27789         local writebyte1
27790
27791         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
27792         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
27793
27794         $LCTL set_param -n llite.*.file_heat=1
27795         echo "Turn on file heat"
27796         echo "Period second: $period_second, Decay percentage: $decay_pct"
27797
27798         echo "QQQQ" > $DIR/$tfile
27799         echo "QQQQ" > $DIR/$tfile
27800         echo "QQQQ" > $DIR/$tfile
27801         cat $DIR/$tfile > /dev/null
27802         cat $DIR/$tfile > /dev/null
27803         cat $DIR/$tfile > /dev/null
27804         cat $DIR/$tfile > /dev/null
27805
27806         local out=$($LFS heat_get $DIR/$tfile)
27807
27808         $LFS heat_get $DIR/$tfile
27809         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27810         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27811         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27812         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27813
27814         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
27815         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
27816         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
27817         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
27818
27819         sleep $((period_second + 3))
27820         echo "Sleep $((period_second + 3)) seconds..."
27821         # The recursion formula to calculate the heat of the file f is as
27822         # follow:
27823         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
27824         # Where Hi is the heat value in the period between time points i*I and
27825         # (i+1)*I; Ci is the access count in the period; the symbol P refers
27826         # to the weight of Ci.
27827         out=$($LFS heat_get $DIR/$tfile)
27828         $LFS heat_get $DIR/$tfile
27829         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27830         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27831         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27832         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27833
27834         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
27835                 error "read sample ($readsample) is wrong"
27836         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
27837                 error "write sample ($writesample) is wrong"
27838         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
27839                 error "read bytes ($readbyte) is wrong"
27840         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
27841                 error "write bytes ($writebyte) is wrong"
27842
27843         echo "QQQQ" > $DIR/$tfile
27844         echo "QQQQ" > $DIR/$tfile
27845         echo "QQQQ" > $DIR/$tfile
27846         cat $DIR/$tfile > /dev/null
27847         cat $DIR/$tfile > /dev/null
27848         cat $DIR/$tfile > /dev/null
27849         cat $DIR/$tfile > /dev/null
27850
27851         sleep $((period_second + 3))
27852         echo "Sleep $((period_second + 3)) seconds..."
27853
27854         out=$($LFS heat_get $DIR/$tfile)
27855         $LFS heat_get $DIR/$tfile
27856         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27857         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27858         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27859         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27860
27861         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
27862                 4 * $decay_pct) / 100") -eq 1 ] ||
27863                 error "read sample ($readsample1) is wrong"
27864         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
27865                 3 * $decay_pct) / 100") -eq 1 ] ||
27866                 error "write sample ($writesample1) is wrong"
27867         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
27868                 20 * $decay_pct) / 100") -eq 1 ] ||
27869                 error "read bytes ($readbyte1) is wrong"
27870         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
27871                 15 * $decay_pct) / 100") -eq 1 ] ||
27872                 error "write bytes ($writebyte1) is wrong"
27873
27874         echo "Turn off file heat for the file $DIR/$tfile"
27875         $LFS heat_set -o $DIR/$tfile
27876
27877         echo "QQQQ" > $DIR/$tfile
27878         echo "QQQQ" > $DIR/$tfile
27879         echo "QQQQ" > $DIR/$tfile
27880         cat $DIR/$tfile > /dev/null
27881         cat $DIR/$tfile > /dev/null
27882         cat $DIR/$tfile > /dev/null
27883         cat $DIR/$tfile > /dev/null
27884
27885         out=$($LFS heat_get $DIR/$tfile)
27886         $LFS heat_get $DIR/$tfile
27887         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27888         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27889         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27890         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27891
27892         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27893         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27894         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27895         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27896
27897         echo "Trun on file heat for the file $DIR/$tfile"
27898         $LFS heat_set -O $DIR/$tfile
27899
27900         echo "QQQQ" > $DIR/$tfile
27901         echo "QQQQ" > $DIR/$tfile
27902         echo "QQQQ" > $DIR/$tfile
27903         cat $DIR/$tfile > /dev/null
27904         cat $DIR/$tfile > /dev/null
27905         cat $DIR/$tfile > /dev/null
27906         cat $DIR/$tfile > /dev/null
27907
27908         out=$($LFS heat_get $DIR/$tfile)
27909         $LFS heat_get $DIR/$tfile
27910         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27911         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27912         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27913         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27914
27915         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
27916         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
27917         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
27918         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
27919
27920         $LFS heat_set -c $DIR/$tfile
27921         $LCTL set_param -n llite.*.file_heat=0
27922         echo "Turn off file heat support for the Lustre filesystem"
27923
27924         echo "QQQQ" > $DIR/$tfile
27925         echo "QQQQ" > $DIR/$tfile
27926         echo "QQQQ" > $DIR/$tfile
27927         cat $DIR/$tfile > /dev/null
27928         cat $DIR/$tfile > /dev/null
27929         cat $DIR/$tfile > /dev/null
27930         cat $DIR/$tfile > /dev/null
27931
27932         out=$($LFS heat_get $DIR/$tfile)
27933         $LFS heat_get $DIR/$tfile
27934         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27935         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27936         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27937         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27938
27939         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27940         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27941         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27942         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27943
27944         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
27945         rm -f $DIR/$tfile
27946 }
27947 run_test 813 "File heat verfication"
27948
27949 test_814()
27950 {
27951         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
27952         echo -n y >> $DIR/$tfile
27953         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
27954         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
27955 }
27956 run_test 814 "sparse cp works as expected (LU-12361)"
27957
27958 test_815()
27959 {
27960         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
27961         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
27962 }
27963 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
27964
27965 test_816() {
27966         local ost1_imp=$(get_osc_import_name client ost1)
27967         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27968                          cut -d'.' -f2)
27969
27970         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27971         # ensure ost1 is connected
27972
27973         stat $DIR/$tfile >/dev/null || error "can't stat"
27974         wait_osc_import_state client ost1 FULL
27975         # no locks, no reqs to let the connection idle
27976         cancel_lru_locks osc
27977         lru_resize_disable osc
27978         local before
27979         local now
27980         before=$($LCTL get_param -n \
27981                  ldlm.namespaces.$imp_name.lru_size)
27982
27983         wait_osc_import_state client ost1 IDLE
27984         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
27985         now=$($LCTL get_param -n \
27986               ldlm.namespaces.$imp_name.lru_size)
27987         [ $before == $now ] || error "lru_size changed $before != $now"
27988 }
27989 run_test 816 "do not reset lru_resize on idle reconnect"
27990
27991 cleanup_817() {
27992         umount $tmpdir
27993         exportfs -u localhost:$DIR/nfsexp
27994         rm -rf $DIR/nfsexp
27995 }
27996
27997 test_817() {
27998         systemctl restart nfs-server.service || skip "failed to restart nfsd"
27999
28000         mkdir -p $DIR/nfsexp
28001         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
28002                 error "failed to export nfs"
28003
28004         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
28005         stack_trap cleanup_817 EXIT
28006
28007         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
28008                 error "failed to mount nfs to $tmpdir"
28009
28010         cp /bin/true $tmpdir
28011         $DIR/nfsexp/true || error "failed to execute 'true' command"
28012 }
28013 run_test 817 "nfsd won't cache write lock for exec file"
28014
28015 test_818() {
28016         test_mkdir -i0 -c1 $DIR/$tdir
28017         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
28018         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
28019         stop $SINGLEMDS
28020
28021         # restore osp-syn threads
28022         stack_trap "fail $SINGLEMDS"
28023
28024         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
28025         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
28026         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
28027                 error "start $SINGLEMDS failed"
28028         rm -rf $DIR/$tdir
28029
28030         local testid=$(echo $TESTNAME | tr '_' ' ')
28031
28032         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
28033                 grep "run LFSCK" || error "run LFSCK is not suggested"
28034 }
28035 run_test 818 "unlink with failed llog"
28036
28037 test_819a() {
28038         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28039         cancel_lru_locks osc
28040         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28041         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28042         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
28043         rm -f $TDIR/$tfile
28044 }
28045 run_test 819a "too big niobuf in read"
28046
28047 test_819b() {
28048         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28049         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28050         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28051         cancel_lru_locks osc
28052         sleep 1
28053         rm -f $TDIR/$tfile
28054 }
28055 run_test 819b "too big niobuf in write"
28056
28057
28058 function test_820_start_ost() {
28059         sleep 5
28060
28061         for num in $(seq $OSTCOUNT); do
28062                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
28063         done
28064 }
28065
28066 test_820() {
28067         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28068
28069         mkdir $DIR/$tdir
28070         umount_client $MOUNT || error "umount failed"
28071         for num in $(seq $OSTCOUNT); do
28072                 stop ost$num
28073         done
28074
28075         # mount client with no active OSTs
28076         # so that the client can't initialize max LOV EA size
28077         # from OSC notifications
28078         mount_client $MOUNT || error "mount failed"
28079         # delay OST starting to keep this 0 max EA size for a while
28080         test_820_start_ost &
28081
28082         # create a directory on MDS2
28083         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
28084                 error "Failed to create directory"
28085         # open intent should update default EA size
28086         # see mdc_update_max_ea_from_body()
28087         # notice this is the very first RPC to MDS2
28088         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
28089         ret=$?
28090         echo $out
28091         # With SSK, this situation can lead to -EPERM being returned.
28092         # In that case, simply retry.
28093         if [ $ret -ne 0 ] && $SHARED_KEY; then
28094                 if echo "$out" | grep -q "not permitted"; then
28095                         cp /etc/services $DIR/$tdir/mds2
28096                         ret=$?
28097                 fi
28098         fi
28099         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
28100 }
28101 run_test 820 "update max EA from open intent"
28102
28103 test_822() {
28104         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28105
28106         save_lustre_params mds1 \
28107                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28108         do_facet $SINGLEMDS "$LCTL set_param -n \
28109                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
28110         do_facet $SINGLEMDS "$LCTL set_param -n \
28111                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
28112
28113         # wait for statfs update to clear OS_STATFS_NOPRECREATE
28114         local maxage=$(do_facet mds1 $LCTL get_param -n \
28115                        osp.$FSNAME-OST0000*MDT0000.maxage)
28116         sleep $((maxage + 1))
28117
28118         #define OBD_FAIL_NET_ERROR_RPC          0x532
28119         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
28120
28121         stack_trap "restore_lustre_params < $p; rm $p"
28122
28123         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
28124                       osp.$FSNAME-OST0000*MDT0000.create_count")
28125         for i in $(seq 1 $count); do
28126                 touch $DIR/$tfile.${i} || error "touch failed"
28127         done
28128 }
28129 run_test 822 "test precreate failure"
28130
28131 test_823() {
28132         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28133         local OST_MAX_PRECREATE=20000
28134
28135         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
28136                 skip "Need MDS version at least 2.14.56"
28137
28138         save_lustre_params mds1 \
28139                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28140         do_facet $SINGLEMDS "$LCTL set_param -n \
28141                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
28142         do_facet $SINGLEMDS "$LCTL set_param -n \
28143                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
28144
28145         stack_trap "restore_lustre_params < $p; rm $p"
28146
28147         do_facet $SINGLEMDS "$LCTL set_param -n \
28148                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
28149
28150         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28151                       osp.$FSNAME-OST0000*MDT0000.create_count")
28152         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28153                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
28154         local expect_count=$(((($max/2)/256) * 256))
28155
28156         log "setting create_count to 100200:"
28157         log " -result- count: $count with max: $max, expecting: $expect_count"
28158
28159         [[ $count -eq expect_count ]] ||
28160                 error "Create count not set to max precreate."
28161 }
28162 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28163
28164 test_831() {
28165         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
28166                 skip "Need MDS version 2.14.56"
28167
28168         local sync_changes=$(do_facet $SINGLEMDS \
28169                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28170
28171         [ "$sync_changes" -gt 100 ] &&
28172                 skip "Sync changes $sync_changes > 100 already"
28173
28174         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28175
28176         $LFS mkdir -i 0 $DIR/$tdir
28177         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28178
28179         save_lustre_params mds1 \
28180                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28181         save_lustre_params mds1 \
28182                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28183
28184         do_facet mds1 "$LCTL set_param -n \
28185                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28186                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28187         stack_trap "restore_lustre_params < $p" EXIT
28188
28189         createmany -o $DIR/$tdir/f- 1000
28190         unlinkmany $DIR/$tdir/f- 1000 &
28191         local UNLINK_PID=$!
28192
28193         while sleep 1; do
28194                 sync_changes=$(do_facet mds1 \
28195                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28196                 # the check in the code is racy, fail the test
28197                 # if the value above the limit by 10.
28198                 [ $sync_changes -gt 110 ] && {
28199                         kill -2 $UNLINK_PID
28200                         wait
28201                         error "osp changes throttling failed, $sync_changes>110"
28202                 }
28203                 kill -0 $UNLINK_PID 2> /dev/null || break
28204         done
28205         wait
28206 }
28207 run_test 831 "throttling unlink/setattr queuing on OSP"
28208
28209 #
28210 # tests that do cleanup/setup should be run at the end
28211 #
28212
28213 test_900() {
28214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28215         local ls
28216
28217         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28218         $LCTL set_param fail_loc=0x903
28219
28220         cancel_lru_locks MGC
28221
28222         FAIL_ON_ERROR=true cleanup
28223         FAIL_ON_ERROR=true setup
28224 }
28225 run_test 900 "umount should not race with any mgc requeue thread"
28226
28227 # LUS-6253/LU-11185
28228 test_901() {
28229         local old
28230         local count
28231         local oldc
28232         local newc
28233         local olds
28234         local news
28235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28236
28237         # some get_param have a bug to handle dot in param name
28238         cancel_lru_locks MGC
28239         old=$(mount -t lustre | wc -l)
28240         # 1 config+sptlrpc
28241         # 2 params
28242         # 3 nodemap
28243         # 4 IR
28244         old=$((old * 4))
28245         oldc=0
28246         count=0
28247         while [ $old -ne $oldc ]; do
28248                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28249                 sleep 1
28250                 ((count++))
28251                 if [ $count -ge $TIMEOUT ]; then
28252                         error "too large timeout"
28253                 fi
28254         done
28255         umount_client $MOUNT || error "umount failed"
28256         mount_client $MOUNT || error "mount failed"
28257         cancel_lru_locks MGC
28258         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28259
28260         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28261
28262         return 0
28263 }
28264 run_test 901 "don't leak a mgc lock on client umount"
28265
28266 # LU-13377
28267 test_902() {
28268         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28269                 skip "client does not have LU-13377 fix"
28270         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28271         $LCTL set_param fail_loc=0x1415
28272         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28273         cancel_lru_locks osc
28274         rm -f $DIR/$tfile
28275 }
28276 run_test 902 "test short write doesn't hang lustre"
28277
28278 # LU-14711
28279 test_903() {
28280         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28281         echo "blah" > $DIR/${tfile}-2
28282         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28283         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28284         $LCTL set_param fail_loc=0x417 fail_val=20
28285
28286         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28287         sleep 1 # To start the destroy
28288         wait_destroy_complete 150 || error "Destroy taking too long"
28289         cat $DIR/$tfile > /dev/null || error "Evicted"
28290 }
28291 run_test 903 "Test long page discard does not cause evictions"
28292
28293 test_904() {
28294         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28295         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28296                 grep -q project || skip "skip project quota not supported"
28297
28298         local testfile="$DIR/$tdir/$tfile"
28299         local xattr="trusted.projid"
28300         local projid
28301         local mdts=$(comma_list $(mdts_nodes))
28302         local saved=$(do_facet mds1 $LCTL get_param -n \
28303                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
28304
28305         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
28306         stack_trap "do_nodes $mdts $LCTL set_param \
28307                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
28308
28309         mkdir -p $DIR/$tdir
28310         touch $testfile
28311         #hide projid xattr on server
28312         $LFS project -p 1 $testfile ||
28313                 error "set $testfile project id failed"
28314         getfattr -m - $testfile | grep $xattr &&
28315                 error "do not show trusted.projid when disabled on server"
28316         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
28317         #should be hidden when projid is 0
28318         $LFS project -p 0 $testfile ||
28319                 error "set $testfile project id failed"
28320         getfattr -m - $testfile | grep $xattr &&
28321                 error "do not show trusted.projid with project ID 0"
28322
28323         #still can getxattr explicitly
28324         projid=$(getfattr -n $xattr $testfile |
28325                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28326         [ $projid == "0" ] ||
28327                 error "projid expected 0 not $projid"
28328
28329         #set the projid via setxattr
28330         setfattr -n $xattr -v "1000" $testfile ||
28331                 error "setattr failed with $?"
28332         projid=($($LFS project $testfile))
28333         [ ${projid[0]} == "1000" ] ||
28334                 error "projid expected 1000 not $projid"
28335
28336         #check the new projid via getxattr
28337         $LFS project -p 1001 $testfile ||
28338                 error "set $testfile project id failed"
28339         getfattr -m - $testfile | grep $xattr ||
28340                 error "should show trusted.projid when project ID != 0"
28341         projid=$(getfattr -n $xattr $testfile |
28342                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28343         [ $projid == "1001" ] ||
28344                 error "projid expected 1001 not $projid"
28345
28346         #try to set invalid projid
28347         setfattr -n $xattr -v "4294967295" $testfile &&
28348                 error "set invalid projid should fail"
28349
28350         #remove the xattr means setting projid to 0
28351         setfattr -x $xattr $testfile ||
28352                 error "setfattr failed with $?"
28353         projid=($($LFS project $testfile))
28354         [ ${projid[0]} == "0" ] ||
28355                 error "projid expected 0 not $projid"
28356
28357         #should be hidden when parent has inherit flag and same projid
28358         $LFS project -srp 1002 $DIR/$tdir ||
28359                 error "set $tdir project id failed"
28360         getfattr -m - $testfile | grep $xattr &&
28361                 error "do not show trusted.projid with inherit flag"
28362
28363         #still can getxattr explicitly
28364         projid=$(getfattr -n $xattr $testfile |
28365                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28366         [ $projid == "1002" ] ||
28367                 error "projid expected 1002 not $projid"
28368 }
28369 run_test 904 "virtual project ID xattr"
28370
28371 complete $SECONDS
28372 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28373 check_and_cleanup_lustre
28374 if [ "$I_MOUNTED" != "yes" ]; then
28375         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28376 fi
28377 exit_status