Whamcloud - gitweb
9b9e87f4c74d997ada786291c0259f700c455fa2
[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 fi
50
51 # skip the grant tests for ARM until they are fixed
52 if [[ $(uname -m) = aarch64 ]]; then
53         always_except LU-11671 45
54         always_except LU-14067 400a 400b
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         local instance=$($LFS getname -i $DIR)
8970         local osc_tgt="$FSNAME-OST0000-osc-$instance"
8971         local num_exps=$(do_facet ost1 \
8972             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
8973         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8974         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
8975         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8976
8977         # 10MiB is for file to be written, max_brw_size * 16 *
8978         # num_exps is space reserve so that tgt_grant_shrink() decided
8979         # to not shrink
8980         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
8981         (( avail * 1024 < expect )) &&
8982                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
8983
8984         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
8985         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
8986         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
8987         $LCTL set_param osc.*OST0000*.grant_shrink=1
8988         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
8989
8990         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8991         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
8992
8993         # drop cache so that coming read would do rpc
8994         cancel_lru_locks osc
8995
8996         # shrink interval is set to 10, pause for 7 seconds so that
8997         # grant thread did not wake up yet but coming read entered
8998         # shrink mode for rpc (osc_should_shrink_grant())
8999         sleep 7
9000
9001         declare -a cur_grant_bytes
9002         declare -a tot_granted
9003         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9004         tot_granted[0]=$(do_facet ost1 \
9005             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9006
9007         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9008
9009         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9010         tot_granted[1]=$(do_facet ost1 \
9011             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9012
9013         # grant change should be equal on both sides
9014         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9015                 tot_granted[0] - tot_granted[1])) ||
9016                 error "grant change mismatch, "                                \
9017                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9018                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9019 }
9020 run_test 64h "grant shrink on read"
9021
9022 test_64i() {
9023         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
9024                 skip "need OST at least 2.14.55 to avoid grant shrink on replay"
9025
9026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9027         remote_ost_nodsh && skip "remote OSTs with nodsh"
9028
9029         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9030
9031         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9032
9033         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9034         local instance=$($LFS getname -i $DIR)
9035
9036         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9037         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9038
9039         # shrink grants and simulate rpc loss
9040         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9041         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9042         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9043
9044         fail ost1
9045
9046         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9047
9048         local testid=$(echo $TESTNAME | tr '_' ' ')
9049
9050         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9051                 grep "GRANT, real grant" &&
9052                 error "client has more grants then it owns" || true
9053 }
9054 run_test 64i "shrink on reconnect"
9055
9056 # bug 1414 - set/get directories' stripe info
9057 test_65a() {
9058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9059
9060         test_mkdir $DIR/$tdir
9061         touch $DIR/$tdir/f1
9062         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9063 }
9064 run_test 65a "directory with no stripe info"
9065
9066 test_65b() {
9067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9068
9069         test_mkdir $DIR/$tdir
9070         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9071
9072         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9073                                                 error "setstripe"
9074         touch $DIR/$tdir/f2
9075         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9076 }
9077 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9078
9079 test_65c() {
9080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9081         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9082
9083         test_mkdir $DIR/$tdir
9084         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9085
9086         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9087                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9088         touch $DIR/$tdir/f3
9089         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9090 }
9091 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9092
9093 test_65d() {
9094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9095
9096         test_mkdir $DIR/$tdir
9097         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9098         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9099
9100         if [[ $STRIPECOUNT -le 0 ]]; then
9101                 sc=1
9102         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9103                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9104                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9105         else
9106                 sc=$(($STRIPECOUNT - 1))
9107         fi
9108         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9109         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9110         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9111                 error "lverify failed"
9112 }
9113 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9114
9115 test_65e() {
9116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9117
9118         test_mkdir $DIR/$tdir
9119
9120         $LFS setstripe $DIR/$tdir || error "setstripe"
9121         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9122                                         error "no stripe info failed"
9123         touch $DIR/$tdir/f6
9124         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9125 }
9126 run_test 65e "directory setstripe defaults"
9127
9128 test_65f() {
9129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9130
9131         test_mkdir $DIR/${tdir}f
9132         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9133                 error "setstripe succeeded" || true
9134 }
9135 run_test 65f "dir setstripe permission (should return error) ==="
9136
9137 test_65g() {
9138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9139
9140         test_mkdir $DIR/$tdir
9141         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9142
9143         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9144                 error "setstripe -S failed"
9145         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9146         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9147                 error "delete default stripe failed"
9148 }
9149 run_test 65g "directory setstripe -d"
9150
9151 test_65h() {
9152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9153
9154         test_mkdir $DIR/$tdir
9155         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9156
9157         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9158                 error "setstripe -S failed"
9159         test_mkdir $DIR/$tdir/dd1
9160         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9161                 error "stripe info inherit failed"
9162 }
9163 run_test 65h "directory stripe info inherit ===================="
9164
9165 test_65i() {
9166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9167
9168         save_layout_restore_at_exit $MOUNT
9169
9170         # bug6367: set non-default striping on root directory
9171         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9172
9173         # bug12836: getstripe on -1 default directory striping
9174         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9175
9176         # bug12836: getstripe -v on -1 default directory striping
9177         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9178
9179         # bug12836: new find on -1 default directory striping
9180         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9181 }
9182 run_test 65i "various tests to set root directory striping"
9183
9184 test_65j() { # bug6367
9185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9186
9187         sync; sleep 1
9188
9189         # if we aren't already remounting for each test, do so for this test
9190         if [ "$I_MOUNTED" = "yes" ]; then
9191                 cleanup || error "failed to unmount"
9192                 setup
9193         fi
9194
9195         save_layout_restore_at_exit $MOUNT
9196
9197         $LFS setstripe -d $MOUNT || error "setstripe failed"
9198 }
9199 run_test 65j "set default striping on root directory (bug 6367)="
9200
9201 cleanup_65k() {
9202         rm -rf $DIR/$tdir
9203         wait_delete_completed
9204         do_facet $SINGLEMDS "lctl set_param -n \
9205                 osp.$ost*MDT0000.max_create_count=$max_count"
9206         do_facet $SINGLEMDS "lctl set_param -n \
9207                 osp.$ost*MDT0000.create_count=$count"
9208         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9209         echo $INACTIVE_OSC "is Activate"
9210
9211         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9212 }
9213
9214 test_65k() { # bug11679
9215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9216         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9217         remote_mds_nodsh && skip "remote MDS with nodsh"
9218
9219         local disable_precreate=true
9220         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9221                 disable_precreate=false
9222
9223         echo "Check OST status: "
9224         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9225                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9226
9227         for OSC in $MDS_OSCS; do
9228                 echo $OSC "is active"
9229                 do_facet $SINGLEMDS lctl --device %$OSC activate
9230         done
9231
9232         for INACTIVE_OSC in $MDS_OSCS; do
9233                 local ost=$(osc_to_ost $INACTIVE_OSC)
9234                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9235                                lov.*md*.target_obd |
9236                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9237
9238                 mkdir -p $DIR/$tdir
9239                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9240                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9241
9242                 echo "Deactivate: " $INACTIVE_OSC
9243                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9244
9245                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9246                               osp.$ost*MDT0000.create_count")
9247                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9248                                   osp.$ost*MDT0000.max_create_count")
9249                 $disable_precreate &&
9250                         do_facet $SINGLEMDS "lctl set_param -n \
9251                                 osp.$ost*MDT0000.max_create_count=0"
9252
9253                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9254                         [ -f $DIR/$tdir/$idx ] && continue
9255                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9256                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9257                                 { cleanup_65k;
9258                                   error "setstripe $idx should succeed"; }
9259                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9260                 done
9261                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9262                 rmdir $DIR/$tdir
9263
9264                 do_facet $SINGLEMDS "lctl set_param -n \
9265                         osp.$ost*MDT0000.max_create_count=$max_count"
9266                 do_facet $SINGLEMDS "lctl set_param -n \
9267                         osp.$ost*MDT0000.create_count=$count"
9268                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9269                 echo $INACTIVE_OSC "is Activate"
9270
9271                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9272         done
9273 }
9274 run_test 65k "validate manual striping works properly with deactivated OSCs"
9275
9276 test_65l() { # bug 12836
9277         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9278
9279         test_mkdir -p $DIR/$tdir/test_dir
9280         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9281         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9282 }
9283 run_test 65l "lfs find on -1 stripe dir ========================"
9284
9285 test_65m() {
9286         local layout=$(save_layout $MOUNT)
9287         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9288                 restore_layout $MOUNT $layout
9289                 error "setstripe should fail by non-root users"
9290         }
9291         true
9292 }
9293 run_test 65m "normal user can't set filesystem default stripe"
9294
9295 test_65n() {
9296         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9297         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9298                 skip "Need MDS version at least 2.12.50"
9299         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9300
9301         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9302         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9303         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9304
9305         save_layout_restore_at_exit $MOUNT
9306
9307         # new subdirectory under root directory should not inherit
9308         # the default layout from root
9309         local dir1=$MOUNT/$tdir-1
9310         mkdir $dir1 || error "mkdir $dir1 failed"
9311         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9312                 error "$dir1 shouldn't have LOV EA"
9313
9314         # delete the default layout on root directory
9315         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9316
9317         local dir2=$MOUNT/$tdir-2
9318         mkdir $dir2 || error "mkdir $dir2 failed"
9319         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9320                 error "$dir2 shouldn't have LOV EA"
9321
9322         # set a new striping pattern on root directory
9323         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9324         local new_def_stripe_size=$((def_stripe_size * 2))
9325         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9326                 error "set stripe size on $MOUNT failed"
9327
9328         # new file created in $dir2 should inherit the new stripe size from
9329         # the filesystem default
9330         local file2=$dir2/$tfile-2
9331         touch $file2 || error "touch $file2 failed"
9332
9333         local file2_stripe_size=$($LFS getstripe -S $file2)
9334         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9335         {
9336                 echo "file2_stripe_size: '$file2_stripe_size'"
9337                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9338                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9339         }
9340
9341         local dir3=$MOUNT/$tdir-3
9342         mkdir $dir3 || error "mkdir $dir3 failed"
9343         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9344         # the root layout, which is the actual default layout that will be used
9345         # when new files are created in $dir3.
9346         local dir3_layout=$(get_layout_param $dir3)
9347         local root_dir_layout=$(get_layout_param $MOUNT)
9348         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9349         {
9350                 echo "dir3_layout: '$dir3_layout'"
9351                 echo "root_dir_layout: '$root_dir_layout'"
9352                 error "$dir3 should show the default layout from $MOUNT"
9353         }
9354
9355         # set OST pool on root directory
9356         local pool=$TESTNAME
9357         pool_add $pool || error "add $pool failed"
9358         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9359                 error "add targets to $pool failed"
9360
9361         $LFS setstripe -p $pool $MOUNT ||
9362                 error "set OST pool on $MOUNT failed"
9363
9364         # new file created in $dir3 should inherit the pool from
9365         # the filesystem default
9366         local file3=$dir3/$tfile-3
9367         touch $file3 || error "touch $file3 failed"
9368
9369         local file3_pool=$($LFS getstripe -p $file3)
9370         [[ "$file3_pool" = "$pool" ]] ||
9371                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9372
9373         local dir4=$MOUNT/$tdir-4
9374         mkdir $dir4 || error "mkdir $dir4 failed"
9375         local dir4_layout=$(get_layout_param $dir4)
9376         root_dir_layout=$(get_layout_param $MOUNT)
9377         echo "$LFS getstripe -d $dir4"
9378         $LFS getstripe -d $dir4
9379         echo "$LFS getstripe -d $MOUNT"
9380         $LFS getstripe -d $MOUNT
9381         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9382         {
9383                 echo "dir4_layout: '$dir4_layout'"
9384                 echo "root_dir_layout: '$root_dir_layout'"
9385                 error "$dir4 should show the default layout from $MOUNT"
9386         }
9387
9388         # new file created in $dir4 should inherit the pool from
9389         # the filesystem default
9390         local file4=$dir4/$tfile-4
9391         touch $file4 || error "touch $file4 failed"
9392
9393         local file4_pool=$($LFS getstripe -p $file4)
9394         [[ "$file4_pool" = "$pool" ]] ||
9395                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9396
9397         # new subdirectory under non-root directory should inherit
9398         # the default layout from its parent directory
9399         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9400                 error "set directory layout on $dir4 failed"
9401
9402         local dir5=$dir4/$tdir-5
9403         mkdir $dir5 || error "mkdir $dir5 failed"
9404
9405         dir4_layout=$(get_layout_param $dir4)
9406         local dir5_layout=$(get_layout_param $dir5)
9407         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9408         {
9409                 echo "dir4_layout: '$dir4_layout'"
9410                 echo "dir5_layout: '$dir5_layout'"
9411                 error "$dir5 should inherit the default layout from $dir4"
9412         }
9413
9414         # though subdir under ROOT doesn't inherit default layout, but
9415         # its sub dir/file should be created with default layout.
9416         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9417         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9418                 skip "Need MDS version at least 2.12.59"
9419
9420         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9421         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9422         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9423
9424         if [ $default_lmv_hash == "none" ]; then
9425                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9426         else
9427                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9428                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9429         fi
9430
9431         $LFS setdirstripe -D -c 2 $MOUNT ||
9432                 error "setdirstripe -D -c 2 failed"
9433         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9434         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9435         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9436
9437         # $dir4 layout includes pool
9438         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9439         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9440                 error "pool lost on setstripe"
9441         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9442         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9443                 error "pool lost on compound layout setstripe"
9444 }
9445 run_test 65n "don't inherit default layout from root for new subdirectories"
9446
9447 # bug 2543 - update blocks count on client
9448 test_66() {
9449         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9450
9451         COUNT=${COUNT:-8}
9452         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9453         sync; sync_all_data; sync; sync_all_data
9454         cancel_lru_locks osc
9455         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9456         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9457 }
9458 run_test 66 "update inode blocks count on client ==============="
9459
9460 meminfo() {
9461         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9462 }
9463
9464 swap_used() {
9465         swapon -s | awk '($1 == "'$1'") { print $4 }'
9466 }
9467
9468 # bug5265, obdfilter oa2dentry return -ENOENT
9469 # #define OBD_FAIL_SRV_ENOENT 0x217
9470 test_69() {
9471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9472         remote_ost_nodsh && skip "remote OST with nodsh"
9473
9474         f="$DIR/$tfile"
9475         $LFS setstripe -c 1 -i 0 $f
9476
9477         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9478
9479         do_facet ost1 lctl set_param fail_loc=0x217
9480         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9481         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9482
9483         do_facet ost1 lctl set_param fail_loc=0
9484         $DIRECTIO write $f 0 2 || error "write error"
9485
9486         cancel_lru_locks osc
9487         $DIRECTIO read $f 0 1 || error "read error"
9488
9489         do_facet ost1 lctl set_param fail_loc=0x217
9490         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9491
9492         do_facet ost1 lctl set_param fail_loc=0
9493         rm -f $f
9494 }
9495 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9496
9497 test_71() {
9498         test_mkdir $DIR/$tdir
9499         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9500         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9501 }
9502 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9503
9504 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9506         [ "$RUNAS_ID" = "$UID" ] &&
9507                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9508         # Check that testing environment is properly set up. Skip if not
9509         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9510                 skip_env "User $RUNAS_ID does not exist - skipping"
9511
9512         touch $DIR/$tfile
9513         chmod 777 $DIR/$tfile
9514         chmod ug+s $DIR/$tfile
9515         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9516                 error "$RUNAS dd $DIR/$tfile failed"
9517         # See if we are still setuid/sgid
9518         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9519                 error "S/gid is not dropped on write"
9520         # Now test that MDS is updated too
9521         cancel_lru_locks mdc
9522         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9523                 error "S/gid is not dropped on MDS"
9524         rm -f $DIR/$tfile
9525 }
9526 run_test 72a "Test that remove suid works properly (bug5695) ===="
9527
9528 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9529         local perm
9530
9531         [ "$RUNAS_ID" = "$UID" ] &&
9532                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9533         [ "$RUNAS_ID" -eq 0 ] &&
9534                 skip_env "RUNAS_ID = 0 -- skipping"
9535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9536         # Check that testing environment is properly set up. Skip if not
9537         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9538                 skip_env "User $RUNAS_ID does not exist - skipping"
9539
9540         touch $DIR/${tfile}-f{g,u}
9541         test_mkdir $DIR/${tfile}-dg
9542         test_mkdir $DIR/${tfile}-du
9543         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9544         chmod g+s $DIR/${tfile}-{f,d}g
9545         chmod u+s $DIR/${tfile}-{f,d}u
9546         for perm in 777 2777 4777; do
9547                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9548                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9549                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9550                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9551         done
9552         true
9553 }
9554 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9555
9556 # bug 3462 - multiple simultaneous MDC requests
9557 test_73() {
9558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9559
9560         test_mkdir $DIR/d73-1
9561         test_mkdir $DIR/d73-2
9562         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9563         pid1=$!
9564
9565         lctl set_param fail_loc=0x80000129
9566         $MULTIOP $DIR/d73-1/f73-2 Oc &
9567         sleep 1
9568         lctl set_param fail_loc=0
9569
9570         $MULTIOP $DIR/d73-2/f73-3 Oc &
9571         pid3=$!
9572
9573         kill -USR1 $pid1
9574         wait $pid1 || return 1
9575
9576         sleep 25
9577
9578         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9579         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9580         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9581
9582         rm -rf $DIR/d73-*
9583 }
9584 run_test 73 "multiple MDC requests (should not deadlock)"
9585
9586 test_74a() { # bug 6149, 6184
9587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9588
9589         touch $DIR/f74a
9590         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9591         #
9592         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9593         # will spin in a tight reconnection loop
9594         $LCTL set_param fail_loc=0x8000030e
9595         # get any lock that won't be difficult - lookup works.
9596         ls $DIR/f74a
9597         $LCTL set_param fail_loc=0
9598         rm -f $DIR/f74a
9599         true
9600 }
9601 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9602
9603 test_74b() { # bug 13310
9604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9605
9606         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9607         #
9608         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9609         # will spin in a tight reconnection loop
9610         $LCTL set_param fail_loc=0x8000030e
9611         # get a "difficult" lock
9612         touch $DIR/f74b
9613         $LCTL set_param fail_loc=0
9614         rm -f $DIR/f74b
9615         true
9616 }
9617 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9618
9619 test_74c() {
9620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9621
9622         #define OBD_FAIL_LDLM_NEW_LOCK
9623         $LCTL set_param fail_loc=0x319
9624         touch $DIR/$tfile && error "touch successful"
9625         $LCTL set_param fail_loc=0
9626         true
9627 }
9628 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9629
9630 slab_lic=/sys/kernel/slab/lustre_inode_cache
9631 num_objects() {
9632         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9633         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9634                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9635 }
9636
9637 test_76a() { # Now for b=20433, added originally in b=1443
9638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9639
9640         cancel_lru_locks osc
9641         # there may be some slab objects cached per core
9642         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9643         local before=$(num_objects)
9644         local count=$((512 * cpus))
9645         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9646         local margin=$((count / 10))
9647         if [[ -f $slab_lic/aliases ]]; then
9648                 local aliases=$(cat $slab_lic/aliases)
9649                 (( aliases > 0 )) && margin=$((margin * aliases))
9650         fi
9651
9652         echo "before slab objects: $before"
9653         for i in $(seq $count); do
9654                 touch $DIR/$tfile
9655                 rm -f $DIR/$tfile
9656         done
9657         cancel_lru_locks osc
9658         local after=$(num_objects)
9659         echo "created: $count, after slab objects: $after"
9660         # shared slab counts are not very accurate, allow significant margin
9661         # the main goal is that the cache growth is not permanently > $count
9662         while (( after > before + margin )); do
9663                 sleep 1
9664                 after=$(num_objects)
9665                 wait=$((wait + 1))
9666                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9667                 if (( wait > 60 )); then
9668                         error "inode slab grew from $before+$margin to $after"
9669                 fi
9670         done
9671 }
9672 run_test 76a "confirm clients recycle inodes properly ===="
9673
9674 test_76b() {
9675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9676         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9677
9678         local count=512
9679         local before=$(num_objects)
9680
9681         for i in $(seq $count); do
9682                 mkdir $DIR/$tdir
9683                 rmdir $DIR/$tdir
9684         done
9685
9686         local after=$(num_objects)
9687         local wait=0
9688
9689         while (( after > before )); do
9690                 sleep 1
9691                 after=$(num_objects)
9692                 wait=$((wait + 1))
9693                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9694                 if (( wait > 60 )); then
9695                         error "inode slab grew from $before to $after"
9696                 fi
9697         done
9698
9699         echo "slab objects before: $before, after: $after"
9700 }
9701 run_test 76b "confirm clients recycle directory inodes properly ===="
9702
9703 export ORIG_CSUM=""
9704 set_checksums()
9705 {
9706         # Note: in sptlrpc modes which enable its own bulk checksum, the
9707         # original crc32_le bulk checksum will be automatically disabled,
9708         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9709         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9710         # In this case set_checksums() will not be no-op, because sptlrpc
9711         # bulk checksum will be enabled all through the test.
9712
9713         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9714         lctl set_param -n osc.*.checksums $1
9715         return 0
9716 }
9717
9718 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9719                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9720 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9721                              tr -d [] | head -n1)}
9722 set_checksum_type()
9723 {
9724         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9725         rc=$?
9726         log "set checksum type to $1, rc = $rc"
9727         return $rc
9728 }
9729
9730 get_osc_checksum_type()
9731 {
9732         # arugment 1: OST name, like OST0000
9733         ost=$1
9734         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9735                         sed 's/.*\[\(.*\)\].*/\1/g')
9736         rc=$?
9737         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9738         echo $checksum_type
9739 }
9740
9741 F77_TMP=$TMP/f77-temp
9742 F77SZ=8
9743 setup_f77() {
9744         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9745                 error "error writing to $F77_TMP"
9746 }
9747
9748 test_77a() { # bug 10889
9749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9750         $GSS && skip_env "could not run with gss"
9751
9752         [ ! -f $F77_TMP ] && setup_f77
9753         set_checksums 1
9754         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9755         set_checksums 0
9756         rm -f $DIR/$tfile
9757 }
9758 run_test 77a "normal checksum read/write operation"
9759
9760 test_77b() { # bug 10889
9761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9762         $GSS && skip_env "could not run with gss"
9763
9764         [ ! -f $F77_TMP ] && setup_f77
9765         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9766         $LCTL set_param fail_loc=0x80000409
9767         set_checksums 1
9768
9769         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9770                 error "dd error: $?"
9771         $LCTL set_param fail_loc=0
9772
9773         for algo in $CKSUM_TYPES; do
9774                 cancel_lru_locks osc
9775                 set_checksum_type $algo
9776                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9777                 $LCTL set_param fail_loc=0x80000408
9778                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9779                 $LCTL set_param fail_loc=0
9780         done
9781         set_checksums 0
9782         set_checksum_type $ORIG_CSUM_TYPE
9783         rm -f $DIR/$tfile
9784 }
9785 run_test 77b "checksum error on client write, read"
9786
9787 cleanup_77c() {
9788         trap 0
9789         set_checksums 0
9790         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9791         $check_ost &&
9792                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9793         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9794         $check_ost && [ -n "$ost_file_prefix" ] &&
9795                 do_facet ost1 rm -f ${ost_file_prefix}\*
9796 }
9797
9798 test_77c() {
9799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9800         $GSS && skip_env "could not run with gss"
9801         remote_ost_nodsh && skip "remote OST with nodsh"
9802
9803         local bad1
9804         local osc_file_prefix
9805         local osc_file
9806         local check_ost=false
9807         local ost_file_prefix
9808         local ost_file
9809         local orig_cksum
9810         local dump_cksum
9811         local fid
9812
9813         # ensure corruption will occur on first OSS/OST
9814         $LFS setstripe -i 0 $DIR/$tfile
9815
9816         [ ! -f $F77_TMP ] && setup_f77
9817         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9818                 error "dd write error: $?"
9819         fid=$($LFS path2fid $DIR/$tfile)
9820
9821         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9822         then
9823                 check_ost=true
9824                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9825                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9826         else
9827                 echo "OSS do not support bulk pages dump upon error"
9828         fi
9829
9830         osc_file_prefix=$($LCTL get_param -n debug_path)
9831         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9832
9833         trap cleanup_77c EXIT
9834
9835         set_checksums 1
9836         # enable bulk pages dump upon error on Client
9837         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9838         # enable bulk pages dump upon error on OSS
9839         $check_ost &&
9840                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9841
9842         # flush Client cache to allow next read to reach OSS
9843         cancel_lru_locks osc
9844
9845         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9846         $LCTL set_param fail_loc=0x80000408
9847         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9848         $LCTL set_param fail_loc=0
9849
9850         rm -f $DIR/$tfile
9851
9852         # check cksum dump on Client
9853         osc_file=$(ls ${osc_file_prefix}*)
9854         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9855         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9856         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9857         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9858         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9859                      cksum)
9860         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9861         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9862                 error "dump content does not match on Client"
9863
9864         $check_ost || skip "No need to check cksum dump on OSS"
9865
9866         # check cksum dump on OSS
9867         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9868         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9869         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9870         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9871         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9872                 error "dump content does not match on OSS"
9873
9874         cleanup_77c
9875 }
9876 run_test 77c "checksum error on client read with debug"
9877
9878 test_77d() { # bug 10889
9879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9880         $GSS && skip_env "could not run with gss"
9881
9882         stack_trap "rm -f $DIR/$tfile"
9883         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9884         $LCTL set_param fail_loc=0x80000409
9885         set_checksums 1
9886         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9887                 error "direct write: rc=$?"
9888         $LCTL set_param fail_loc=0
9889         set_checksums 0
9890
9891         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9892         $LCTL set_param fail_loc=0x80000408
9893         set_checksums 1
9894         cancel_lru_locks osc
9895         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9896                 error "direct read: rc=$?"
9897         $LCTL set_param fail_loc=0
9898         set_checksums 0
9899 }
9900 run_test 77d "checksum error on OST direct write, read"
9901
9902 test_77f() { # bug 10889
9903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9904         $GSS && skip_env "could not run with gss"
9905
9906         set_checksums 1
9907         stack_trap "rm -f $DIR/$tfile"
9908         for algo in $CKSUM_TYPES; do
9909                 cancel_lru_locks osc
9910                 set_checksum_type $algo
9911                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9912                 $LCTL set_param fail_loc=0x409
9913                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9914                         error "direct write succeeded"
9915                 $LCTL set_param fail_loc=0
9916         done
9917         set_checksum_type $ORIG_CSUM_TYPE
9918         set_checksums 0
9919 }
9920 run_test 77f "repeat checksum error on write (expect error)"
9921
9922 test_77g() { # bug 10889
9923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9924         $GSS && skip_env "could not run with gss"
9925         remote_ost_nodsh && skip "remote OST with nodsh"
9926
9927         [ ! -f $F77_TMP ] && setup_f77
9928
9929         local file=$DIR/$tfile
9930         stack_trap "rm -f $file" EXIT
9931
9932         $LFS setstripe -c 1 -i 0 $file
9933         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9934         do_facet ost1 lctl set_param fail_loc=0x8000021a
9935         set_checksums 1
9936         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9937                 error "write error: rc=$?"
9938         do_facet ost1 lctl set_param fail_loc=0
9939         set_checksums 0
9940
9941         cancel_lru_locks osc
9942         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9943         do_facet ost1 lctl set_param fail_loc=0x8000021b
9944         set_checksums 1
9945         cmp $F77_TMP $file || error "file compare failed"
9946         do_facet ost1 lctl set_param fail_loc=0
9947         set_checksums 0
9948 }
9949 run_test 77g "checksum error on OST write, read"
9950
9951 test_77k() { # LU-10906
9952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9953         $GSS && skip_env "could not run with gss"
9954
9955         local cksum_param="osc.$FSNAME*.checksums"
9956         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9957         local checksum
9958         local i
9959
9960         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9961         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9962         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9963
9964         for i in 0 1; do
9965                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9966                         error "failed to set checksum=$i on MGS"
9967                 wait_update $HOSTNAME "$get_checksum" $i
9968                 #remount
9969                 echo "remount client, checksum should be $i"
9970                 remount_client $MOUNT || error "failed to remount client"
9971                 checksum=$(eval $get_checksum)
9972                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9973         done
9974         # remove persistent param to avoid races with checksum mountopt below
9975         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9976                 error "failed to delete checksum on MGS"
9977
9978         for opt in "checksum" "nochecksum"; do
9979                 #remount with mount option
9980                 echo "remount client with option $opt, checksum should be $i"
9981                 umount_client $MOUNT || error "failed to umount client"
9982                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9983                         error "failed to mount client with option '$opt'"
9984                 checksum=$(eval $get_checksum)
9985                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9986                 i=$((i - 1))
9987         done
9988
9989         remount_client $MOUNT || error "failed to remount client"
9990 }
9991 run_test 77k "enable/disable checksum correctly"
9992
9993 test_77l() {
9994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9995         $GSS && skip_env "could not run with gss"
9996
9997         set_checksums 1
9998         stack_trap "set_checksums $ORIG_CSUM" EXIT
9999         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10000
10001         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10002
10003         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10004         for algo in $CKSUM_TYPES; do
10005                 set_checksum_type $algo || error "fail to set checksum type $algo"
10006                 osc_algo=$(get_osc_checksum_type OST0000)
10007                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10008
10009                 # no locks, no reqs to let the connection idle
10010                 cancel_lru_locks osc
10011                 lru_resize_disable osc
10012                 wait_osc_import_state client ost1 IDLE
10013
10014                 # ensure ost1 is connected
10015                 stat $DIR/$tfile >/dev/null || error "can't stat"
10016                 wait_osc_import_state client ost1 FULL
10017
10018                 osc_algo=$(get_osc_checksum_type OST0000)
10019                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10020         done
10021         return 0
10022 }
10023 run_test 77l "preferred checksum type is remembered after reconnected"
10024
10025 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10026 rm -f $F77_TMP
10027 unset F77_TMP
10028
10029 test_77m() {
10030         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10031                 skip "Need at least version 2.14.52"
10032         local param=checksum_speed
10033
10034         $LCTL get_param $param || error "reading $param failed"
10035
10036         csum_speeds=$($LCTL get_param -n $param)
10037
10038         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10039                 error "known checksum types are missing"
10040 }
10041 run_test 77m "Verify checksum_speed is correctly read"
10042
10043 check_filefrag_77n() {
10044         local nr_ext=0
10045         local starts=()
10046         local ends=()
10047
10048         while read extidx a b start end rest; do
10049                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10050                         nr_ext=$(( $nr_ext + 1 ))
10051                         starts+=( ${start%..} )
10052                         ends+=( ${end%:} )
10053                 fi
10054         done < <( filefrag -sv $1 )
10055
10056         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10057         return 1
10058 }
10059
10060 test_77n() {
10061         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10062
10063         touch $DIR/$tfile
10064         $TRUNCATE $DIR/$tfile 0
10065         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10066         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10067         check_filefrag_77n $DIR/$tfile ||
10068                 skip "$tfile blocks not contiguous around hole"
10069
10070         set_checksums 1
10071         stack_trap "set_checksums $ORIG_CSUM" EXIT
10072         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10073         stack_trap "rm -f $DIR/$tfile"
10074
10075         for algo in $CKSUM_TYPES; do
10076                 if [[ "$algo" =~ ^t10 ]]; then
10077                         set_checksum_type $algo ||
10078                                 error "fail to set checksum type $algo"
10079                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10080                                 error "fail to read $tfile with $algo"
10081                 fi
10082         done
10083         rm -f $DIR/$tfile
10084         return 0
10085 }
10086 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10087
10088 test_77o() {
10089         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10090                 skip "Need MDS version at least 2.14.55"
10091         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10092                 skip "Need OST version at least 2.14.55"
10093         local ofd=obdfilter
10094         local mdt=mdt
10095
10096         # print OST checksum_type
10097         echo "$ofd.$FSNAME-*.checksum_type:"
10098         do_nodes $(comma_list $(osts_nodes)) \
10099                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10100
10101         # print MDT checksum_type
10102         echo "$mdt.$FSNAME-*.checksum_type:"
10103         do_nodes $(comma_list $(mdts_nodes)) \
10104                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10105
10106         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10107                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10108
10109         (( $o_count == $OSTCOUNT )) ||
10110                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10111
10112         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10113                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10114
10115         (( $m_count == $MDSCOUNT )) ||
10116                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10117 }
10118 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10119
10120 cleanup_test_78() {
10121         trap 0
10122         rm -f $DIR/$tfile
10123 }
10124
10125 test_78() { # bug 10901
10126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10127         remote_ost || skip_env "local OST"
10128
10129         NSEQ=5
10130         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10131         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10132         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10133         echo "MemTotal: $MEMTOTAL"
10134
10135         # reserve 256MB of memory for the kernel and other running processes,
10136         # and then take 1/2 of the remaining memory for the read/write buffers.
10137         if [ $MEMTOTAL -gt 512 ] ;then
10138                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10139         else
10140                 # for those poor memory-starved high-end clusters...
10141                 MEMTOTAL=$((MEMTOTAL / 2))
10142         fi
10143         echo "Mem to use for directio: $MEMTOTAL"
10144
10145         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10146         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10147         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10148         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10149                 head -n1)
10150         echo "Smallest OST: $SMALLESTOST"
10151         [[ $SMALLESTOST -lt 10240 ]] &&
10152                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10153
10154         trap cleanup_test_78 EXIT
10155
10156         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10157                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10158
10159         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10160         echo "File size: $F78SIZE"
10161         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10162         for i in $(seq 1 $NSEQ); do
10163                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10164                 echo directIO rdwr round $i of $NSEQ
10165                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10166         done
10167
10168         cleanup_test_78
10169 }
10170 run_test 78 "handle large O_DIRECT writes correctly ============"
10171
10172 test_79() { # bug 12743
10173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10174
10175         wait_delete_completed
10176
10177         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10178         BKFREE=$(calc_osc_kbytes kbytesfree)
10179         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10180
10181         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10182         DFTOTAL=`echo $STRING | cut -d, -f1`
10183         DFUSED=`echo $STRING  | cut -d, -f2`
10184         DFAVAIL=`echo $STRING | cut -d, -f3`
10185         DFFREE=$(($DFTOTAL - $DFUSED))
10186
10187         ALLOWANCE=$((64 * $OSTCOUNT))
10188
10189         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10190            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10191                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10192         fi
10193         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10194            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10195                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10196         fi
10197         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10198            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10199                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10200         fi
10201 }
10202 run_test 79 "df report consistency check ======================="
10203
10204 test_80() { # bug 10718
10205         remote_ost_nodsh && skip "remote OST with nodsh"
10206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10207
10208         # relax strong synchronous semantics for slow backends like ZFS
10209         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10210                 local soc="obdfilter.*.sync_lock_cancel"
10211                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10212
10213                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10214                 if [ -z "$save" ]; then
10215                         soc="obdfilter.*.sync_on_lock_cancel"
10216                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10217                 fi
10218
10219                 if [ "$save" != "never" ]; then
10220                         local hosts=$(comma_list $(osts_nodes))
10221
10222                         do_nodes $hosts $LCTL set_param $soc=never
10223                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10224                 fi
10225         fi
10226
10227         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10228         sync; sleep 1; sync
10229         local before=$(date +%s)
10230         cancel_lru_locks osc
10231         local after=$(date +%s)
10232         local diff=$((after - before))
10233         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10234
10235         rm -f $DIR/$tfile
10236 }
10237 run_test 80 "Page eviction is equally fast at high offsets too"
10238
10239 test_81a() { # LU-456
10240         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10241         remote_ost_nodsh && skip "remote OST with nodsh"
10242
10243         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10244         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10245         do_facet ost1 lctl set_param fail_loc=0x80000228
10246
10247         # write should trigger a retry and success
10248         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10249         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10250         RC=$?
10251         if [ $RC -ne 0 ] ; then
10252                 error "write should success, but failed for $RC"
10253         fi
10254 }
10255 run_test 81a "OST should retry write when get -ENOSPC ==============="
10256
10257 test_81b() { # LU-456
10258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10259         remote_ost_nodsh && skip "remote OST with nodsh"
10260
10261         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10262         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10263         do_facet ost1 lctl set_param fail_loc=0x228
10264
10265         # write should retry several times and return -ENOSPC finally
10266         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10267         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10268         RC=$?
10269         ENOSPC=28
10270         if [ $RC -ne $ENOSPC ] ; then
10271                 error "dd should fail for -ENOSPC, but succeed."
10272         fi
10273 }
10274 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10275
10276 test_99() {
10277         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10278
10279         test_mkdir $DIR/$tdir.cvsroot
10280         chown $RUNAS_ID $DIR/$tdir.cvsroot
10281
10282         cd $TMP
10283         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10284
10285         cd /etc/init.d
10286         # some versions of cvs import exit(1) when asked to import links or
10287         # files they can't read.  ignore those files.
10288         local toignore=$(find . -type l -printf '-I %f\n' -o \
10289                          ! -perm /4 -printf '-I %f\n')
10290         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10291                 $tdir.reposname vtag rtag
10292
10293         cd $DIR
10294         test_mkdir $DIR/$tdir.reposname
10295         chown $RUNAS_ID $DIR/$tdir.reposname
10296         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10297
10298         cd $DIR/$tdir.reposname
10299         $RUNAS touch foo99
10300         $RUNAS cvs add -m 'addmsg' foo99
10301         $RUNAS cvs update
10302         $RUNAS cvs commit -m 'nomsg' foo99
10303         rm -fr $DIR/$tdir.cvsroot
10304 }
10305 run_test 99 "cvs strange file/directory operations"
10306
10307 test_100() {
10308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10309         [[ "$NETTYPE" =~ tcp ]] ||
10310                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10311         remote_ost_nodsh && skip "remote OST with nodsh"
10312         remote_mds_nodsh && skip "remote MDS with nodsh"
10313         remote_servers ||
10314                 skip "useless for local single node setup"
10315
10316         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10317                 [ "$PROT" != "tcp" ] && continue
10318                 RPORT=$(echo $REMOTE | cut -d: -f2)
10319                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10320
10321                 rc=0
10322                 LPORT=`echo $LOCAL | cut -d: -f2`
10323                 if [ $LPORT -ge 1024 ]; then
10324                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10325                         netstat -tna
10326                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10327                 fi
10328         done
10329         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10330 }
10331 run_test 100 "check local port using privileged port ==========="
10332
10333 function get_named_value()
10334 {
10335     local tag=$1
10336
10337     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10338 }
10339
10340 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10341                    awk '/^max_cached_mb/ { print $2 }')
10342
10343 cleanup_101a() {
10344         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10345         trap 0
10346 }
10347
10348 test_101a() {
10349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10350
10351         local s
10352         local discard
10353         local nreads=10000
10354         local cache_limit=32
10355
10356         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10357         trap cleanup_101a EXIT
10358         $LCTL set_param -n llite.*.read_ahead_stats=0
10359         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10360
10361         #
10362         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10363         #
10364         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10365         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10366
10367         discard=0
10368         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10369                    get_named_value 'read.but.discarded'); do
10370                         discard=$(($discard + $s))
10371         done
10372         cleanup_101a
10373
10374         $LCTL get_param osc.*-osc*.rpc_stats
10375         $LCTL get_param llite.*.read_ahead_stats
10376
10377         # Discard is generally zero, but sometimes a few random reads line up
10378         # and trigger larger readahead, which is wasted & leads to discards.
10379         if [[ $(($discard)) -gt $nreads ]]; then
10380                 error "too many ($discard) discarded pages"
10381         fi
10382         rm -f $DIR/$tfile || true
10383 }
10384 run_test 101a "check read-ahead for random reads"
10385
10386 setup_test101bc() {
10387         test_mkdir $DIR/$tdir
10388         local ssize=$1
10389         local FILE_LENGTH=$2
10390         STRIPE_OFFSET=0
10391
10392         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10393
10394         local list=$(comma_list $(osts_nodes))
10395         set_osd_param $list '' read_cache_enable 0
10396         set_osd_param $list '' writethrough_cache_enable 0
10397
10398         trap cleanup_test101bc EXIT
10399         # prepare the read-ahead file
10400         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10401
10402         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10403                                 count=$FILE_SIZE_MB 2> /dev/null
10404
10405 }
10406
10407 cleanup_test101bc() {
10408         trap 0
10409         rm -rf $DIR/$tdir
10410         rm -f $DIR/$tfile
10411
10412         local list=$(comma_list $(osts_nodes))
10413         set_osd_param $list '' read_cache_enable 1
10414         set_osd_param $list '' writethrough_cache_enable 1
10415 }
10416
10417 calc_total() {
10418         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10419 }
10420
10421 ra_check_101() {
10422         local read_size=$1
10423         local stripe_size=$2
10424         local stride_length=$((stripe_size / read_size))
10425         local stride_width=$((stride_length * OSTCOUNT))
10426         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
10427                                 (stride_width - stride_length) ))
10428         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
10429                   get_named_value 'read.but.discarded' | calc_total)
10430
10431         if [[ $discard -gt $discard_limit ]]; then
10432                 $LCTL get_param llite.*.read_ahead_stats
10433                 error "($discard) discarded pages with size (${read_size})"
10434         else
10435                 echo "Read-ahead success for size ${read_size}"
10436         fi
10437 }
10438
10439 test_101b() {
10440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10441         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10442
10443         local STRIPE_SIZE=1048576
10444         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10445
10446         if [ $SLOW == "yes" ]; then
10447                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10448         else
10449                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10450         fi
10451
10452         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10453
10454         # prepare the read-ahead file
10455         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10456         cancel_lru_locks osc
10457         for BIDX in 2 4 8 16 32 64 128 256
10458         do
10459                 local BSIZE=$((BIDX*4096))
10460                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10461                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10462                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10463                 $LCTL set_param -n llite.*.read_ahead_stats=0
10464                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10465                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10466                 cancel_lru_locks osc
10467                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10468         done
10469         cleanup_test101bc
10470         true
10471 }
10472 run_test 101b "check stride-io mode read-ahead ================="
10473
10474 test_101c() {
10475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10476
10477         local STRIPE_SIZE=1048576
10478         local FILE_LENGTH=$((STRIPE_SIZE*100))
10479         local nreads=10000
10480         local rsize=65536
10481         local osc_rpc_stats
10482
10483         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10484
10485         cancel_lru_locks osc
10486         $LCTL set_param osc.*.rpc_stats=0
10487         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10488         $LCTL get_param osc.*.rpc_stats
10489         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10490                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10491                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10492                 local size
10493
10494                 if [ $lines -le 20 ]; then
10495                         echo "continue debug"
10496                         continue
10497                 fi
10498                 for size in 1 2 4 8; do
10499                         local rpc=$(echo "$stats" |
10500                                     awk '($1 == "'$size':") {print $2; exit; }')
10501                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10502                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10503                 done
10504                 echo "$osc_rpc_stats check passed!"
10505         done
10506         cleanup_test101bc
10507         true
10508 }
10509 run_test 101c "check stripe_size aligned read-ahead"
10510
10511 test_101d() {
10512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10513
10514         local file=$DIR/$tfile
10515         local sz_MB=${FILESIZE_101d:-80}
10516         local ra_MB=${READAHEAD_MB:-40}
10517
10518         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10519         [ $free_MB -lt $sz_MB ] &&
10520                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10521
10522         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10523         $LFS setstripe -c -1 $file || error "setstripe failed"
10524
10525         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10526         echo Cancel LRU locks on lustre client to flush the client cache
10527         cancel_lru_locks osc
10528
10529         echo Disable read-ahead
10530         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10531         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10532         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10533         $LCTL get_param -n llite.*.max_read_ahead_mb
10534
10535         echo "Reading the test file $file with read-ahead disabled"
10536         local sz_KB=$((sz_MB * 1024 / 4))
10537         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10538         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10539         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10540                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10541
10542         echo "Cancel LRU locks on lustre client to flush the client cache"
10543         cancel_lru_locks osc
10544         echo Enable read-ahead with ${ra_MB}MB
10545         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10546
10547         echo "Reading the test file $file with read-ahead enabled"
10548         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10549                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10550
10551         echo "read-ahead disabled time read $raOFF"
10552         echo "read-ahead enabled time read $raON"
10553
10554         rm -f $file
10555         wait_delete_completed
10556
10557         # use awk for this check instead of bash because it handles decimals
10558         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10559                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10560 }
10561 run_test 101d "file read with and without read-ahead enabled"
10562
10563 test_101e() {
10564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10565
10566         local file=$DIR/$tfile
10567         local size_KB=500  #KB
10568         local count=100
10569         local bsize=1024
10570
10571         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10572         local need_KB=$((count * size_KB))
10573         [[ $free_KB -le $need_KB ]] &&
10574                 skip_env "Need free space $need_KB, have $free_KB"
10575
10576         echo "Creating $count ${size_KB}K test files"
10577         for ((i = 0; i < $count; i++)); do
10578                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10579         done
10580
10581         echo "Cancel LRU locks on lustre client to flush the client cache"
10582         cancel_lru_locks $OSC
10583
10584         echo "Reset readahead stats"
10585         $LCTL set_param -n llite.*.read_ahead_stats=0
10586
10587         for ((i = 0; i < $count; i++)); do
10588                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10589         done
10590
10591         $LCTL get_param llite.*.max_cached_mb
10592         $LCTL get_param llite.*.read_ahead_stats
10593         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10594                      get_named_value 'misses' | calc_total)
10595
10596         for ((i = 0; i < $count; i++)); do
10597                 rm -rf $file.$i 2>/dev/null
10598         done
10599
10600         #10000 means 20% reads are missing in readahead
10601         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10602 }
10603 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10604
10605 test_101f() {
10606         which iozone || skip_env "no iozone installed"
10607
10608         local old_debug=$($LCTL get_param debug)
10609         old_debug=${old_debug#*=}
10610         $LCTL set_param debug="reada mmap"
10611
10612         # create a test file
10613         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10614
10615         echo Cancel LRU locks on lustre client to flush the client cache
10616         cancel_lru_locks osc
10617
10618         echo Reset readahead stats
10619         $LCTL set_param -n llite.*.read_ahead_stats=0
10620
10621         echo mmap read the file with small block size
10622         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10623                 > /dev/null 2>&1
10624
10625         echo checking missing pages
10626         $LCTL get_param llite.*.read_ahead_stats
10627         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10628                         get_named_value 'misses' | calc_total)
10629
10630         $LCTL set_param debug="$old_debug"
10631         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10632         rm -f $DIR/$tfile
10633 }
10634 run_test 101f "check mmap read performance"
10635
10636 test_101g_brw_size_test() {
10637         local mb=$1
10638         local pages=$((mb * 1048576 / PAGE_SIZE))
10639         local file=$DIR/$tfile
10640
10641         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10642                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10643         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10644                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10645                         return 2
10646         done
10647
10648         stack_trap "rm -f $file" EXIT
10649         $LCTL set_param -n osc.*.rpc_stats=0
10650
10651         # 10 RPCs should be enough for the test
10652         local count=10
10653         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10654                 { error "dd write ${mb} MB blocks failed"; return 3; }
10655         cancel_lru_locks osc
10656         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10657                 { error "dd write ${mb} MB blocks failed"; return 4; }
10658
10659         # calculate number of full-sized read and write RPCs
10660         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10661                 sed -n '/pages per rpc/,/^$/p' |
10662                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10663                 END { print reads,writes }'))
10664         # allow one extra full-sized read RPC for async readahead
10665         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10666                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10667         [[ ${rpcs[1]} == $count ]] ||
10668                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10669 }
10670
10671 test_101g() {
10672         remote_ost_nodsh && skip "remote OST with nodsh"
10673
10674         local rpcs
10675         local osts=$(get_facets OST)
10676         local list=$(comma_list $(osts_nodes))
10677         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10678         local brw_size="obdfilter.*.brw_size"
10679
10680         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10681
10682         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10683
10684         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10685                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10686                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10687            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10688                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10689                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10690
10691                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10692                         suffix="M"
10693
10694                 if [[ $orig_mb -lt 16 ]]; then
10695                         save_lustre_params $osts "$brw_size" > $p
10696                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10697                                 error "set 16MB RPC size failed"
10698
10699                         echo "remount client to enable new RPC size"
10700                         remount_client $MOUNT || error "remount_client failed"
10701                 fi
10702
10703                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10704                 # should be able to set brw_size=12, but no rpc_stats for that
10705                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10706         fi
10707
10708         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10709
10710         if [[ $orig_mb -lt 16 ]]; then
10711                 restore_lustre_params < $p
10712                 remount_client $MOUNT || error "remount_client restore failed"
10713         fi
10714
10715         rm -f $p $DIR/$tfile
10716 }
10717 run_test 101g "Big bulk(4/16 MiB) readahead"
10718
10719 test_101h() {
10720         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10721
10722         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10723                 error "dd 70M file failed"
10724         echo Cancel LRU locks on lustre client to flush the client cache
10725         cancel_lru_locks osc
10726
10727         echo "Reset readahead stats"
10728         $LCTL set_param -n llite.*.read_ahead_stats 0
10729
10730         echo "Read 10M of data but cross 64M bundary"
10731         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10732         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10733                      get_named_value 'misses' | calc_total)
10734         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10735         rm -f $p $DIR/$tfile
10736 }
10737 run_test 101h "Readahead should cover current read window"
10738
10739 test_101i() {
10740         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10741                 error "dd 10M file failed"
10742
10743         local max_per_file_mb=$($LCTL get_param -n \
10744                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10745         cancel_lru_locks osc
10746         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10747         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10748                 error "set max_read_ahead_per_file_mb to 1 failed"
10749
10750         echo "Reset readahead stats"
10751         $LCTL set_param llite.*.read_ahead_stats=0
10752
10753         dd if=$DIR/$tfile of=/dev/null bs=2M
10754
10755         $LCTL get_param llite.*.read_ahead_stats
10756         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10757                      awk '/misses/ { print $2 }')
10758         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10759         rm -f $DIR/$tfile
10760 }
10761 run_test 101i "allow current readahead to exceed reservation"
10762
10763 test_101j() {
10764         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10765                 error "setstripe $DIR/$tfile failed"
10766         local file_size=$((1048576 * 16))
10767         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10768         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10769
10770         echo Disable read-ahead
10771         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10772
10773         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10774         for blk in $PAGE_SIZE 1048576 $file_size; do
10775                 cancel_lru_locks osc
10776                 echo "Reset readahead stats"
10777                 $LCTL set_param -n llite.*.read_ahead_stats=0
10778                 local count=$(($file_size / $blk))
10779                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10780                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10781                              get_named_value 'failed.to.fast.read' | calc_total)
10782                 $LCTL get_param -n llite.*.read_ahead_stats
10783                 [ $miss -eq $count ] || error "expected $count got $miss"
10784         done
10785
10786         rm -f $p $DIR/$tfile
10787 }
10788 run_test 101j "A complete read block should be submitted when no RA"
10789
10790 setup_test102() {
10791         test_mkdir $DIR/$tdir
10792         chown $RUNAS_ID $DIR/$tdir
10793         STRIPE_SIZE=65536
10794         STRIPE_OFFSET=1
10795         STRIPE_COUNT=$OSTCOUNT
10796         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10797
10798         trap cleanup_test102 EXIT
10799         cd $DIR
10800         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10801         cd $DIR/$tdir
10802         for num in 1 2 3 4; do
10803                 for count in $(seq 1 $STRIPE_COUNT); do
10804                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10805                                 local size=`expr $STRIPE_SIZE \* $num`
10806                                 local file=file"$num-$idx-$count"
10807                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10808                         done
10809                 done
10810         done
10811
10812         cd $DIR
10813         $1 tar cf $TMP/f102.tar $tdir --xattrs
10814 }
10815
10816 cleanup_test102() {
10817         trap 0
10818         rm -f $TMP/f102.tar
10819         rm -rf $DIR/d0.sanity/d102
10820 }
10821
10822 test_102a() {
10823         [ "$UID" != 0 ] && skip "must run as root"
10824         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10825                 skip_env "must have user_xattr"
10826
10827         [ -z "$(which setfattr 2>/dev/null)" ] &&
10828                 skip_env "could not find setfattr"
10829
10830         local testfile=$DIR/$tfile
10831
10832         touch $testfile
10833         echo "set/get xattr..."
10834         setfattr -n trusted.name1 -v value1 $testfile ||
10835                 error "setfattr -n trusted.name1=value1 $testfile failed"
10836         getfattr -n trusted.name1 $testfile 2> /dev/null |
10837           grep "trusted.name1=.value1" ||
10838                 error "$testfile missing trusted.name1=value1"
10839
10840         setfattr -n user.author1 -v author1 $testfile ||
10841                 error "setfattr -n user.author1=author1 $testfile failed"
10842         getfattr -n user.author1 $testfile 2> /dev/null |
10843           grep "user.author1=.author1" ||
10844                 error "$testfile missing trusted.author1=author1"
10845
10846         echo "listxattr..."
10847         setfattr -n trusted.name2 -v value2 $testfile ||
10848                 error "$testfile unable to set trusted.name2"
10849         setfattr -n trusted.name3 -v value3 $testfile ||
10850                 error "$testfile unable to set trusted.name3"
10851         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10852             grep "trusted.name" | wc -l) -eq 3 ] ||
10853                 error "$testfile missing 3 trusted.name xattrs"
10854
10855         setfattr -n user.author2 -v author2 $testfile ||
10856                 error "$testfile unable to set user.author2"
10857         setfattr -n user.author3 -v author3 $testfile ||
10858                 error "$testfile unable to set user.author3"
10859         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10860             grep "user.author" | wc -l) -eq 3 ] ||
10861                 error "$testfile missing 3 user.author xattrs"
10862
10863         echo "remove xattr..."
10864         setfattr -x trusted.name1 $testfile ||
10865                 error "$testfile error deleting trusted.name1"
10866         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10867                 error "$testfile did not delete trusted.name1 xattr"
10868
10869         setfattr -x user.author1 $testfile ||
10870                 error "$testfile error deleting user.author1"
10871         echo "set lustre special xattr ..."
10872         $LFS setstripe -c1 $testfile
10873         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10874                 awk -F "=" '/trusted.lov/ { print $2 }' )
10875         setfattr -n "trusted.lov" -v $lovea $testfile ||
10876                 error "$testfile doesn't ignore setting trusted.lov again"
10877         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10878                 error "$testfile allow setting invalid trusted.lov"
10879         rm -f $testfile
10880 }
10881 run_test 102a "user xattr test =================================="
10882
10883 check_102b_layout() {
10884         local layout="$*"
10885         local testfile=$DIR/$tfile
10886
10887         echo "test layout '$layout'"
10888         $LFS setstripe $layout $testfile || error "setstripe failed"
10889         $LFS getstripe -y $testfile
10890
10891         echo "get/set/list trusted.lov xattr ..." # b=10930
10892         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10893         [[ "$value" =~ "trusted.lov" ]] ||
10894                 error "can't get trusted.lov from $testfile"
10895         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10896                 error "getstripe failed"
10897
10898         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10899
10900         value=$(cut -d= -f2 <<<$value)
10901         # LU-13168: truncated xattr should fail if short lov_user_md header
10902         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10903                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10904         for len in $lens; do
10905                 echo "setfattr $len $testfile.2"
10906                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10907                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10908         done
10909         local stripe_size=$($LFS getstripe -S $testfile.2)
10910         local stripe_count=$($LFS getstripe -c $testfile.2)
10911         [[ $stripe_size -eq 65536 ]] ||
10912                 error "stripe size $stripe_size != 65536"
10913         [[ $stripe_count -eq $stripe_count_orig ]] ||
10914                 error "stripe count $stripe_count != $stripe_count_orig"
10915         rm $testfile $testfile.2
10916 }
10917
10918 test_102b() {
10919         [ -z "$(which setfattr 2>/dev/null)" ] &&
10920                 skip_env "could not find setfattr"
10921         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10922
10923         # check plain layout
10924         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10925
10926         # and also check composite layout
10927         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10928
10929 }
10930 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10931
10932 test_102c() {
10933         [ -z "$(which setfattr 2>/dev/null)" ] &&
10934                 skip_env "could not find setfattr"
10935         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10936
10937         # b10930: get/set/list lustre.lov xattr
10938         echo "get/set/list lustre.lov xattr ..."
10939         test_mkdir $DIR/$tdir
10940         chown $RUNAS_ID $DIR/$tdir
10941         local testfile=$DIR/$tdir/$tfile
10942         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10943                 error "setstripe failed"
10944         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10945                 error "getstripe failed"
10946         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10947         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10948
10949         local testfile2=${testfile}2
10950         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10951                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10952
10953         $RUNAS $MCREATE $testfile2
10954         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10955         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10956         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10957         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10958         [ $stripe_count -eq $STRIPECOUNT ] ||
10959                 error "stripe count $stripe_count != $STRIPECOUNT"
10960 }
10961 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10962
10963 compare_stripe_info1() {
10964         local stripe_index_all_zero=true
10965
10966         for num in 1 2 3 4; do
10967                 for count in $(seq 1 $STRIPE_COUNT); do
10968                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10969                                 local size=$((STRIPE_SIZE * num))
10970                                 local file=file"$num-$offset-$count"
10971                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10972                                 [[ $stripe_size -ne $size ]] &&
10973                                     error "$file: size $stripe_size != $size"
10974                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10975                                 # allow fewer stripes to be created, ORI-601
10976                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10977                                     error "$file: count $stripe_count != $count"
10978                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10979                                 [[ $stripe_index -ne 0 ]] &&
10980                                         stripe_index_all_zero=false
10981                         done
10982                 done
10983         done
10984         $stripe_index_all_zero &&
10985                 error "all files are being extracted starting from OST index 0"
10986         return 0
10987 }
10988
10989 have_xattrs_include() {
10990         tar --help | grep -q xattrs-include &&
10991                 echo --xattrs-include="lustre.*"
10992 }
10993
10994 test_102d() {
10995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10996         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10997
10998         XINC=$(have_xattrs_include)
10999         setup_test102
11000         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11001         cd $DIR/$tdir/$tdir
11002         compare_stripe_info1
11003 }
11004 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11005
11006 test_102f() {
11007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11008         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11009
11010         XINC=$(have_xattrs_include)
11011         setup_test102
11012         test_mkdir $DIR/$tdir.restore
11013         cd $DIR
11014         tar cf - --xattrs $tdir | tar xf - \
11015                 -C $DIR/$tdir.restore --xattrs $XINC
11016         cd $DIR/$tdir.restore/$tdir
11017         compare_stripe_info1
11018 }
11019 run_test 102f "tar copy files, not keep osts"
11020
11021 grow_xattr() {
11022         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11023                 skip "must have user_xattr"
11024         [ -z "$(which setfattr 2>/dev/null)" ] &&
11025                 skip_env "could not find setfattr"
11026         [ -z "$(which getfattr 2>/dev/null)" ] &&
11027                 skip_env "could not find getfattr"
11028
11029         local xsize=${1:-1024}  # in bytes
11030         local file=$DIR/$tfile
11031         local value="$(generate_string $xsize)"
11032         local xbig=trusted.big
11033         local toobig=$2
11034
11035         touch $file
11036         log "save $xbig on $file"
11037         if [ -z "$toobig" ]
11038         then
11039                 setfattr -n $xbig -v $value $file ||
11040                         error "saving $xbig on $file failed"
11041         else
11042                 setfattr -n $xbig -v $value $file &&
11043                         error "saving $xbig on $file succeeded"
11044                 return 0
11045         fi
11046
11047         local orig=$(get_xattr_value $xbig $file)
11048         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11049
11050         local xsml=trusted.sml
11051         log "save $xsml on $file"
11052         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11053
11054         local new=$(get_xattr_value $xbig $file)
11055         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11056
11057         log "grow $xsml on $file"
11058         setfattr -n $xsml -v "$value" $file ||
11059                 error "growing $xsml on $file failed"
11060
11061         new=$(get_xattr_value $xbig $file)
11062         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11063         log "$xbig still valid after growing $xsml"
11064
11065         rm -f $file
11066 }
11067
11068 test_102h() { # bug 15777
11069         grow_xattr 1024
11070 }
11071 run_test 102h "grow xattr from inside inode to external block"
11072
11073 test_102ha() {
11074         large_xattr_enabled || skip_env "ea_inode feature disabled"
11075
11076         echo "setting xattr of max xattr size: $(max_xattr_size)"
11077         grow_xattr $(max_xattr_size)
11078
11079         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11080         echo "This should fail:"
11081         grow_xattr $(($(max_xattr_size) + 10)) 1
11082 }
11083 run_test 102ha "grow xattr from inside inode to external inode"
11084
11085 test_102i() { # bug 17038
11086         [ -z "$(which getfattr 2>/dev/null)" ] &&
11087                 skip "could not find getfattr"
11088
11089         touch $DIR/$tfile
11090         ln -s $DIR/$tfile $DIR/${tfile}link
11091         getfattr -n trusted.lov $DIR/$tfile ||
11092                 error "lgetxattr on $DIR/$tfile failed"
11093         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11094                 grep -i "no such attr" ||
11095                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11096         rm -f $DIR/$tfile $DIR/${tfile}link
11097 }
11098 run_test 102i "lgetxattr test on symbolic link ============"
11099
11100 test_102j() {
11101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11102         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11103
11104         XINC=$(have_xattrs_include)
11105         setup_test102 "$RUNAS"
11106         chown $RUNAS_ID $DIR/$tdir
11107         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11108         cd $DIR/$tdir/$tdir
11109         compare_stripe_info1 "$RUNAS"
11110 }
11111 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11112
11113 test_102k() {
11114         [ -z "$(which setfattr 2>/dev/null)" ] &&
11115                 skip "could not find setfattr"
11116
11117         touch $DIR/$tfile
11118         # b22187 just check that does not crash for regular file.
11119         setfattr -n trusted.lov $DIR/$tfile
11120         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11121         local test_kdir=$DIR/$tdir
11122         test_mkdir $test_kdir
11123         local default_size=$($LFS getstripe -S $test_kdir)
11124         local default_count=$($LFS getstripe -c $test_kdir)
11125         local default_offset=$($LFS getstripe -i $test_kdir)
11126         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11127                 error 'dir setstripe failed'
11128         setfattr -n trusted.lov $test_kdir
11129         local stripe_size=$($LFS getstripe -S $test_kdir)
11130         local stripe_count=$($LFS getstripe -c $test_kdir)
11131         local stripe_offset=$($LFS getstripe -i $test_kdir)
11132         [ $stripe_size -eq $default_size ] ||
11133                 error "stripe size $stripe_size != $default_size"
11134         [ $stripe_count -eq $default_count ] ||
11135                 error "stripe count $stripe_count != $default_count"
11136         [ $stripe_offset -eq $default_offset ] ||
11137                 error "stripe offset $stripe_offset != $default_offset"
11138         rm -rf $DIR/$tfile $test_kdir
11139 }
11140 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11141
11142 test_102l() {
11143         [ -z "$(which getfattr 2>/dev/null)" ] &&
11144                 skip "could not find getfattr"
11145
11146         # LU-532 trusted. xattr is invisible to non-root
11147         local testfile=$DIR/$tfile
11148
11149         touch $testfile
11150
11151         echo "listxattr as user..."
11152         chown $RUNAS_ID $testfile
11153         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11154             grep -q "trusted" &&
11155                 error "$testfile trusted xattrs are user visible"
11156
11157         return 0;
11158 }
11159 run_test 102l "listxattr size test =================================="
11160
11161 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11162         local path=$DIR/$tfile
11163         touch $path
11164
11165         listxattr_size_check $path || error "listattr_size_check $path failed"
11166 }
11167 run_test 102m "Ensure listxattr fails on small bufffer ========"
11168
11169 cleanup_test102
11170
11171 getxattr() { # getxattr path name
11172         # Return the base64 encoding of the value of xattr name on path.
11173         local path=$1
11174         local name=$2
11175
11176         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11177         # file: $path
11178         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11179         #
11180         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11181
11182         getfattr --absolute-names --encoding=base64 --name=$name $path |
11183                 awk -F= -v name=$name '$1 == name {
11184                         print substr($0, index($0, "=") + 1);
11185         }'
11186 }
11187
11188 test_102n() { # LU-4101 mdt: protect internal xattrs
11189         [ -z "$(which setfattr 2>/dev/null)" ] &&
11190                 skip "could not find setfattr"
11191         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11192         then
11193                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11194         fi
11195
11196         local file0=$DIR/$tfile.0
11197         local file1=$DIR/$tfile.1
11198         local xattr0=$TMP/$tfile.0
11199         local xattr1=$TMP/$tfile.1
11200         local namelist="lov lma lmv link fid version som hsm"
11201         local name
11202         local value
11203
11204         rm -rf $file0 $file1 $xattr0 $xattr1
11205         touch $file0 $file1
11206
11207         # Get 'before' xattrs of $file1.
11208         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11209
11210         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11211                 namelist+=" lfsck_namespace"
11212         for name in $namelist; do
11213                 # Try to copy xattr from $file0 to $file1.
11214                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11215
11216                 setfattr --name=trusted.$name --value="$value" $file1 ||
11217                         error "setxattr 'trusted.$name' failed"
11218
11219                 # Try to set a garbage xattr.
11220                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11221
11222                 if [[ x$name == "xlov" ]]; then
11223                         setfattr --name=trusted.lov --value="$value" $file1 &&
11224                         error "setxattr invalid 'trusted.lov' success"
11225                 else
11226                         setfattr --name=trusted.$name --value="$value" $file1 ||
11227                                 error "setxattr invalid 'trusted.$name' failed"
11228                 fi
11229
11230                 # Try to remove the xattr from $file1. We don't care if this
11231                 # appears to succeed or fail, we just don't want there to be
11232                 # any changes or crashes.
11233                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11234         done
11235
11236         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11237         then
11238                 name="lfsck_ns"
11239                 # Try to copy xattr from $file0 to $file1.
11240                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11241
11242                 setfattr --name=trusted.$name --value="$value" $file1 ||
11243                         error "setxattr 'trusted.$name' failed"
11244
11245                 # Try to set a garbage xattr.
11246                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11247
11248                 setfattr --name=trusted.$name --value="$value" $file1 ||
11249                         error "setxattr 'trusted.$name' failed"
11250
11251                 # Try to remove the xattr from $file1. We don't care if this
11252                 # appears to succeed or fail, we just don't want there to be
11253                 # any changes or crashes.
11254                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11255         fi
11256
11257         # Get 'after' xattrs of file1.
11258         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11259
11260         if ! diff $xattr0 $xattr1; then
11261                 error "before and after xattrs of '$file1' differ"
11262         fi
11263
11264         rm -rf $file0 $file1 $xattr0 $xattr1
11265
11266         return 0
11267 }
11268 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11269
11270 test_102p() { # LU-4703 setxattr did not check ownership
11271         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11272                 skip "MDS needs to be at least 2.5.56"
11273
11274         local testfile=$DIR/$tfile
11275
11276         touch $testfile
11277
11278         echo "setfacl as user..."
11279         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11280         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11281
11282         echo "setfattr as user..."
11283         setfacl -m "u:$RUNAS_ID:---" $testfile
11284         $RUNAS setfattr -x system.posix_acl_access $testfile
11285         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11286 }
11287 run_test 102p "check setxattr(2) correctly fails without permission"
11288
11289 test_102q() {
11290         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11291                 skip "MDS needs to be at least 2.6.92"
11292
11293         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11294 }
11295 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11296
11297 test_102r() {
11298         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11299                 skip "MDS needs to be at least 2.6.93"
11300
11301         touch $DIR/$tfile || error "touch"
11302         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11303         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11304         rm $DIR/$tfile || error "rm"
11305
11306         #normal directory
11307         mkdir -p $DIR/$tdir || error "mkdir"
11308         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11309         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11310         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11311                 error "$testfile error deleting user.author1"
11312         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11313                 grep "user.$(basename $tdir)" &&
11314                 error "$tdir did not delete user.$(basename $tdir)"
11315         rmdir $DIR/$tdir || error "rmdir"
11316
11317         #striped directory
11318         test_mkdir $DIR/$tdir
11319         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11320         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11321         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11322                 error "$testfile error deleting user.author1"
11323         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11324                 grep "user.$(basename $tdir)" &&
11325                 error "$tdir did not delete user.$(basename $tdir)"
11326         rmdir $DIR/$tdir || error "rm striped dir"
11327 }
11328 run_test 102r "set EAs with empty values"
11329
11330 test_102s() {
11331         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11332                 skip "MDS needs to be at least 2.11.52"
11333
11334         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11335
11336         save_lustre_params client "llite.*.xattr_cache" > $save
11337
11338         for cache in 0 1; do
11339                 lctl set_param llite.*.xattr_cache=$cache
11340
11341                 rm -f $DIR/$tfile
11342                 touch $DIR/$tfile || error "touch"
11343                 for prefix in lustre security system trusted user; do
11344                         # Note getxattr() may fail with 'Operation not
11345                         # supported' or 'No such attribute' depending
11346                         # on prefix and cache.
11347                         getfattr -n $prefix.n102s $DIR/$tfile &&
11348                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11349                 done
11350         done
11351
11352         restore_lustre_params < $save
11353 }
11354 run_test 102s "getting nonexistent xattrs should fail"
11355
11356 test_102t() {
11357         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11358                 skip "MDS needs to be at least 2.11.52"
11359
11360         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11361
11362         save_lustre_params client "llite.*.xattr_cache" > $save
11363
11364         for cache in 0 1; do
11365                 lctl set_param llite.*.xattr_cache=$cache
11366
11367                 for buf_size in 0 256; do
11368                         rm -f $DIR/$tfile
11369                         touch $DIR/$tfile || error "touch"
11370                         setfattr -n user.multiop $DIR/$tfile
11371                         $MULTIOP $DIR/$tfile oa$buf_size ||
11372                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11373                 done
11374         done
11375
11376         restore_lustre_params < $save
11377 }
11378 run_test 102t "zero length xattr values handled correctly"
11379
11380 run_acl_subtest()
11381 {
11382     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11383     return $?
11384 }
11385
11386 test_103a() {
11387         [ "$UID" != 0 ] && skip "must run as root"
11388         $GSS && skip_env "could not run under gss"
11389         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11390                 skip_env "must have acl enabled"
11391         [ -z "$(which setfacl 2>/dev/null)" ] &&
11392                 skip_env "could not find setfacl"
11393         remote_mds_nodsh && skip "remote MDS with nodsh"
11394
11395         gpasswd -a daemon bin                           # LU-5641
11396         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11397
11398         declare -a identity_old
11399
11400         for num in $(seq $MDSCOUNT); do
11401                 switch_identity $num true || identity_old[$num]=$?
11402         done
11403
11404         SAVE_UMASK=$(umask)
11405         umask 0022
11406         mkdir -p $DIR/$tdir
11407         cd $DIR/$tdir
11408
11409         echo "performing cp ..."
11410         run_acl_subtest cp || error "run_acl_subtest cp failed"
11411         echo "performing getfacl-noacl..."
11412         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11413         echo "performing misc..."
11414         run_acl_subtest misc || error  "misc test failed"
11415         echo "performing permissions..."
11416         run_acl_subtest permissions || error "permissions failed"
11417         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11418         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11419                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11420                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11421         then
11422                 echo "performing permissions xattr..."
11423                 run_acl_subtest permissions_xattr ||
11424                         error "permissions_xattr failed"
11425         fi
11426         echo "performing setfacl..."
11427         run_acl_subtest setfacl || error  "setfacl test failed"
11428
11429         # inheritance test got from HP
11430         echo "performing inheritance..."
11431         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11432         chmod +x make-tree || error "chmod +x failed"
11433         run_acl_subtest inheritance || error "inheritance test failed"
11434         rm -f make-tree
11435
11436         echo "LU-974 ignore umask when acl is enabled..."
11437         run_acl_subtest 974 || error "LU-974 umask test failed"
11438         if [ $MDSCOUNT -ge 2 ]; then
11439                 run_acl_subtest 974_remote ||
11440                         error "LU-974 umask test failed under remote dir"
11441         fi
11442
11443         echo "LU-2561 newly created file is same size as directory..."
11444         if [ "$mds1_FSTYPE" != "zfs" ]; then
11445                 run_acl_subtest 2561 || error "LU-2561 test failed"
11446         else
11447                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11448         fi
11449
11450         run_acl_subtest 4924 || error "LU-4924 test failed"
11451
11452         cd $SAVE_PWD
11453         umask $SAVE_UMASK
11454
11455         for num in $(seq $MDSCOUNT); do
11456                 if [ "${identity_old[$num]}" = 1 ]; then
11457                         switch_identity $num false || identity_old[$num]=$?
11458                 fi
11459         done
11460 }
11461 run_test 103a "acl test"
11462
11463 test_103b() {
11464         declare -a pids
11465         local U
11466
11467         for U in {0..511}; do
11468                 {
11469                 local O=$(printf "%04o" $U)
11470
11471                 umask $(printf "%04o" $((511 ^ $O)))
11472                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11473                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11474
11475                 (( $S == ($O & 0666) )) ||
11476                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11477
11478                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11479                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11480                 (( $S == ($O & 0666) )) ||
11481                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11482
11483                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11484                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11485                 (( $S == ($O & 0666) )) ||
11486                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11487                 rm -f $DIR/$tfile.[smp]$0
11488                 } &
11489                 local pid=$!
11490
11491                 # limit the concurrently running threads to 64. LU-11878
11492                 local idx=$((U % 64))
11493                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11494                 pids[idx]=$pid
11495         done
11496         wait
11497 }
11498 run_test 103b "umask lfs setstripe"
11499
11500 test_103c() {
11501         mkdir -p $DIR/$tdir
11502         cp -rp $DIR/$tdir $DIR/$tdir.bak
11503
11504         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11505                 error "$DIR/$tdir shouldn't contain default ACL"
11506         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11507                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11508         true
11509 }
11510 run_test 103c "'cp -rp' won't set empty acl"
11511
11512 test_103e() {
11513         local numacl
11514         local fileacl
11515         local saved_debug=$($LCTL get_param -n debug)
11516
11517         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
11518                 skip "MDS needs to be at least 2.14.52"
11519
11520         large_xattr_enabled || skip_env "ea_inode feature disabled"
11521
11522         mkdir -p $DIR/$tdir
11523         # add big LOV EA to cause reply buffer overflow earlier
11524         $LFS setstripe -C 1000 $DIR/$tdir
11525         lctl set_param mdc.*-mdc*.stats=clear
11526
11527         $LCTL set_param debug=0
11528         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11529         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11530
11531         # add a large number of default ACLs (expect 8000+ for 2.13+)
11532         for U in {2..7000}; do
11533                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11534                         error "Able to add just $U default ACLs"
11535         done
11536         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11537         echo "$numacl default ACLs created"
11538
11539         stat $DIR/$tdir || error "Cannot stat directory"
11540         # check file creation
11541         touch $DIR/$tdir/$tfile ||
11542                 error "failed to create $tfile with $numacl default ACLs"
11543         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11544         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11545         echo "$fileacl ACLs were inherited"
11546         (( $fileacl == $numacl )) ||
11547                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11548         # check that new ACLs creation adds new ACLs to inherited ACLs
11549         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11550                 error "Cannot set new ACL"
11551         numacl=$((numacl + 1))
11552         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11553         (( $fileacl == $numacl )) ||
11554                 error "failed to add new ACL: $fileacl != $numacl as expected"
11555         # adds more ACLs to a file to reach their maximum at 8000+
11556         numacl=0
11557         for U in {20000..25000}; do
11558                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11559                 numacl=$((numacl + 1))
11560         done
11561         echo "Added $numacl more ACLs to the file"
11562         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11563         echo "Total $fileacl ACLs in file"
11564         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11565         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11566         rmdir $DIR/$tdir || error "Cannot remove directory"
11567 }
11568 run_test 103e "inheritance of big amount of default ACLs"
11569
11570 test_103f() {
11571         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11572                 skip "MDS needs to be at least 2.14.51"
11573
11574         large_xattr_enabled || skip_env "ea_inode feature disabled"
11575
11576         # enable changelog to consume more internal MDD buffers
11577         changelog_register
11578
11579         mkdir -p $DIR/$tdir
11580         # add big LOV EA
11581         $LFS setstripe -C 1000 $DIR/$tdir
11582         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11583         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11584         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11585         rmdir $DIR/$tdir || error "Cannot remove directory"
11586 }
11587 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11588
11589 test_104a() {
11590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11591
11592         touch $DIR/$tfile
11593         lfs df || error "lfs df failed"
11594         lfs df -ih || error "lfs df -ih failed"
11595         lfs df -h $DIR || error "lfs df -h $DIR failed"
11596         lfs df -i $DIR || error "lfs df -i $DIR failed"
11597         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11598         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11599
11600         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11601         lctl --device %$OSC deactivate
11602         lfs df || error "lfs df with deactivated OSC failed"
11603         lctl --device %$OSC activate
11604         # wait the osc back to normal
11605         wait_osc_import_ready client ost
11606
11607         lfs df || error "lfs df with reactivated OSC failed"
11608         rm -f $DIR/$tfile
11609 }
11610 run_test 104a "lfs df [-ih] [path] test ========================="
11611
11612 test_104b() {
11613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11614         [ $RUNAS_ID -eq $UID ] &&
11615                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11616
11617         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11618                         grep "Permission denied" | wc -l)))
11619         if [ $denied_cnt -ne 0 ]; then
11620                 error "lfs check servers test failed"
11621         fi
11622 }
11623 run_test 104b "$RUNAS lfs check servers test ===================="
11624
11625 #
11626 # Verify $1 is within range of $2.
11627 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11628 # $1 is <= 2% of $2. Else Fail.
11629 #
11630 value_in_range() {
11631         # Strip all units (M, G, T)
11632         actual=$(echo $1 | tr -d A-Z)
11633         expect=$(echo $2 | tr -d A-Z)
11634
11635         expect_lo=$(($expect * 98 / 100)) # 2% below
11636         expect_hi=$(($expect * 102 / 100)) # 2% above
11637
11638         # permit 2% drift above and below
11639         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11640 }
11641
11642 test_104c() {
11643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11644         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11645
11646         local ost_param="osd-zfs.$FSNAME-OST0000."
11647         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11648         local ofacets=$(get_facets OST)
11649         local mfacets=$(get_facets MDS)
11650         local saved_ost_blocks=
11651         local saved_mdt_blocks=
11652
11653         echo "Before recordsize change"
11654         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11655         df=($(df -h | grep "/mnt/lustre"$))
11656
11657         # For checking.
11658         echo "lfs output : ${lfs_df[*]}"
11659         echo "df  output : ${df[*]}"
11660
11661         for facet in ${ofacets//,/ }; do
11662                 if [ -z $saved_ost_blocks ]; then
11663                         saved_ost_blocks=$(do_facet $facet \
11664                                 lctl get_param -n $ost_param.blocksize)
11665                         echo "OST Blocksize: $saved_ost_blocks"
11666                 fi
11667                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11668                 do_facet $facet zfs set recordsize=32768 $ost
11669         done
11670
11671         # BS too small. Sufficient for functional testing.
11672         for facet in ${mfacets//,/ }; do
11673                 if [ -z $saved_mdt_blocks ]; then
11674                         saved_mdt_blocks=$(do_facet $facet \
11675                                 lctl get_param -n $mdt_param.blocksize)
11676                         echo "MDT Blocksize: $saved_mdt_blocks"
11677                 fi
11678                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11679                 do_facet $facet zfs set recordsize=32768 $mdt
11680         done
11681
11682         # Give new values chance to reflect change
11683         sleep 2
11684
11685         echo "After recordsize change"
11686         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11687         df_after=($(df -h | grep "/mnt/lustre"$))
11688
11689         # For checking.
11690         echo "lfs output : ${lfs_df_after[*]}"
11691         echo "df  output : ${df_after[*]}"
11692
11693         # Verify lfs df
11694         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11695                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11696         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11697                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11698         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11699                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11700
11701         # Verify df
11702         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11703                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11704         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11705                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11706         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11707                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11708
11709         # Restore MDT recordize back to original
11710         for facet in ${mfacets//,/ }; do
11711                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11712                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11713         done
11714
11715         # Restore OST recordize back to original
11716         for facet in ${ofacets//,/ }; do
11717                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11718                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11719         done
11720
11721         return 0
11722 }
11723 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11724
11725 test_105a() {
11726         # doesn't work on 2.4 kernels
11727         touch $DIR/$tfile
11728         if $(flock_is_enabled); then
11729                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11730         else
11731                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11732         fi
11733         rm -f $DIR/$tfile
11734 }
11735 run_test 105a "flock when mounted without -o flock test ========"
11736
11737 test_105b() {
11738         touch $DIR/$tfile
11739         if $(flock_is_enabled); then
11740                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11741         else
11742                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11743         fi
11744         rm -f $DIR/$tfile
11745 }
11746 run_test 105b "fcntl when mounted without -o flock test ========"
11747
11748 test_105c() {
11749         touch $DIR/$tfile
11750         if $(flock_is_enabled); then
11751                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11752         else
11753                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11754         fi
11755         rm -f $DIR/$tfile
11756 }
11757 run_test 105c "lockf when mounted without -o flock test"
11758
11759 test_105d() { # bug 15924
11760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11761
11762         test_mkdir $DIR/$tdir
11763         flock_is_enabled || skip_env "mount w/o flock enabled"
11764         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11765         $LCTL set_param fail_loc=0x80000315
11766         flocks_test 2 $DIR/$tdir
11767 }
11768 run_test 105d "flock race (should not freeze) ========"
11769
11770 test_105e() { # bug 22660 && 22040
11771         flock_is_enabled || skip_env "mount w/o flock enabled"
11772
11773         touch $DIR/$tfile
11774         flocks_test 3 $DIR/$tfile
11775 }
11776 run_test 105e "Two conflicting flocks from same process"
11777
11778 test_106() { #bug 10921
11779         test_mkdir $DIR/$tdir
11780         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11781         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11782 }
11783 run_test 106 "attempt exec of dir followed by chown of that dir"
11784
11785 test_107() {
11786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11787
11788         CDIR=`pwd`
11789         local file=core
11790
11791         cd $DIR
11792         rm -f $file
11793
11794         local save_pattern=$(sysctl -n kernel.core_pattern)
11795         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11796         sysctl -w kernel.core_pattern=$file
11797         sysctl -w kernel.core_uses_pid=0
11798
11799         ulimit -c unlimited
11800         sleep 60 &
11801         SLEEPPID=$!
11802
11803         sleep 1
11804
11805         kill -s 11 $SLEEPPID
11806         wait $SLEEPPID
11807         if [ -e $file ]; then
11808                 size=`stat -c%s $file`
11809                 [ $size -eq 0 ] && error "Fail to create core file $file"
11810         else
11811                 error "Fail to create core file $file"
11812         fi
11813         rm -f $file
11814         sysctl -w kernel.core_pattern=$save_pattern
11815         sysctl -w kernel.core_uses_pid=$save_uses_pid
11816         cd $CDIR
11817 }
11818 run_test 107 "Coredump on SIG"
11819
11820 test_110() {
11821         test_mkdir $DIR/$tdir
11822         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11823         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11824                 error "mkdir with 256 char should fail, but did not"
11825         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11826                 error "create with 255 char failed"
11827         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11828                 error "create with 256 char should fail, but did not"
11829
11830         ls -l $DIR/$tdir
11831         rm -rf $DIR/$tdir
11832 }
11833 run_test 110 "filename length checking"
11834
11835 #
11836 # Purpose: To verify dynamic thread (OSS) creation.
11837 #
11838 test_115() {
11839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11840         remote_ost_nodsh && skip "remote OST with nodsh"
11841
11842         # Lustre does not stop service threads once they are started.
11843         # Reset number of running threads to default.
11844         stopall
11845         setupall
11846
11847         local OSTIO_pre
11848         local save_params="$TMP/sanity-$TESTNAME.parameters"
11849
11850         # Get ll_ost_io count before I/O
11851         OSTIO_pre=$(do_facet ost1 \
11852                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11853         # Exit if lustre is not running (ll_ost_io not running).
11854         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11855
11856         echo "Starting with $OSTIO_pre threads"
11857         local thread_max=$((OSTIO_pre * 2))
11858         local rpc_in_flight=$((thread_max * 2))
11859         # this is limited to OSC_MAX_RIF_MAX (256)
11860         [ $rpc_in_flight -gt 256 ] && rpc_in_flight=256
11861         thread_max=$((rpc_in_flight / 2))
11862         [ $thread_max -le $OSTIO_pre ] && skip "Too many ost_io threads" &&
11863                 return
11864
11865         # Number of I/O Process proposed to be started.
11866         local nfiles
11867         local facets=$(get_facets OST)
11868
11869         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11870         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11871
11872         # Set in_flight to $rpc_in_flight
11873         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11874                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11875         nfiles=${rpc_in_flight}
11876         # Set ost thread_max to $thread_max
11877         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11878
11879         # 5 Minutes should be sufficient for max number of OSS
11880         # threads(thread_max) to be created.
11881         local timeout=300
11882
11883         # Start I/O.
11884         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11885         test_mkdir $DIR/$tdir
11886         for i in $(seq $nfiles); do
11887                 local file=$DIR/$tdir/${tfile}-$i
11888                 $LFS setstripe -c -1 -i 0 $file
11889                 ($WTL $file $timeout)&
11890         done
11891
11892         # I/O Started - Wait for thread_started to reach thread_max or report
11893         # error if thread_started is more than thread_max.
11894         echo "Waiting for thread_started to reach thread_max"
11895         local thread_started=0
11896         local end_time=$((SECONDS + timeout))
11897
11898         while [ $SECONDS -le $end_time ] ; do
11899                 echo -n "."
11900                 # Get ost i/o thread_started count.
11901                 thread_started=$(do_facet ost1 \
11902                         "$LCTL get_param \
11903                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11904                 # Break out if thread_started is equal/greater than thread_max
11905                 if [[ $thread_started -ge $thread_max ]]; then
11906                         echo ll_ost_io thread_started $thread_started, \
11907                                 equal/greater than thread_max $thread_max
11908                         break
11909                 fi
11910                 sleep 1
11911         done
11912
11913         # Cleanup - We have the numbers, Kill i/o jobs if running.
11914         jobcount=($(jobs -p))
11915         for i in $(seq 0 $((${#jobcount[@]}-1)))
11916         do
11917                 kill -9 ${jobcount[$i]}
11918                 if [ $? -ne 0 ] ; then
11919                         echo Warning: \
11920                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11921                 fi
11922         done
11923
11924         # Cleanup files left by WTL binary.
11925         for i in $(seq $nfiles); do
11926                 local file=$DIR/$tdir/${tfile}-$i
11927                 rm -rf $file
11928                 if [ $? -ne 0 ] ; then
11929                         echo "Warning: Failed to delete file $file"
11930                 fi
11931         done
11932
11933         restore_lustre_params <$save_params
11934         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11935
11936         # Error out if no new thread has started or Thread started is greater
11937         # than thread max.
11938         if [[ $thread_started -le $OSTIO_pre ||
11939                         $thread_started -gt $thread_max ]]; then
11940                 error "ll_ost_io: thread_started $thread_started" \
11941                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11942                       "No new thread started or thread started greater " \
11943                       "than thread_max."
11944         fi
11945 }
11946 run_test 115 "verify dynamic thread creation===================="
11947
11948 test_116a() { # was previously test_116()
11949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11950         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11951         remote_mds_nodsh && skip "remote MDS with nodsh"
11952
11953         echo -n "Free space priority "
11954         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11955                 head -n1
11956         declare -a AVAIL
11957         free_min_max
11958
11959         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11960         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11961         stack_trap simple_cleanup_common
11962
11963         # Check if we need to generate uneven OSTs
11964         test_mkdir -p $DIR/$tdir/OST${MINI}
11965         local FILL=$((MINV / 4))
11966         local DIFF=$((MAXV - MINV))
11967         local DIFF2=$((DIFF * 100 / MINV))
11968
11969         local threshold=$(do_facet $SINGLEMDS \
11970                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11971         threshold=${threshold%%%}
11972         echo -n "Check for uneven OSTs: "
11973         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11974
11975         if [[ $DIFF2 -gt $threshold ]]; then
11976                 echo "ok"
11977                 echo "Don't need to fill OST$MINI"
11978         else
11979                 # generate uneven OSTs. Write 2% over the QOS threshold value
11980                 echo "no"
11981                 DIFF=$((threshold - DIFF2 + 2))
11982                 DIFF2=$((MINV * DIFF / 100))
11983                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11984                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11985                         error "setstripe failed"
11986                 DIFF=$((DIFF2 / 2048))
11987                 i=0
11988                 while [ $i -lt $DIFF ]; do
11989                         i=$((i + 1))
11990                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11991                                 bs=2M count=1 2>/dev/null
11992                         echo -n .
11993                 done
11994                 echo .
11995                 sync
11996                 sleep_maxage
11997                 free_min_max
11998         fi
11999
12000         DIFF=$((MAXV - MINV))
12001         DIFF2=$((DIFF * 100 / MINV))
12002         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12003         if [ $DIFF2 -gt $threshold ]; then
12004                 echo "ok"
12005         else
12006                 skip "QOS imbalance criteria not met"
12007         fi
12008
12009         MINI1=$MINI
12010         MINV1=$MINV
12011         MAXI1=$MAXI
12012         MAXV1=$MAXV
12013
12014         # now fill using QOS
12015         $LFS setstripe -c 1 $DIR/$tdir
12016         FILL=$((FILL / 200))
12017         if [ $FILL -gt 600 ]; then
12018                 FILL=600
12019         fi
12020         echo "writing $FILL files to QOS-assigned OSTs"
12021         i=0
12022         while [ $i -lt $FILL ]; do
12023                 i=$((i + 1))
12024                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12025                         count=1 2>/dev/null
12026                 echo -n .
12027         done
12028         echo "wrote $i 200k files"
12029         sync
12030         sleep_maxage
12031
12032         echo "Note: free space may not be updated, so measurements might be off"
12033         free_min_max
12034         DIFF2=$((MAXV - MINV))
12035         echo "free space delta: orig $DIFF final $DIFF2"
12036         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12037         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12038         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12039         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12040         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12041         if [[ $DIFF -gt 0 ]]; then
12042                 FILL=$((DIFF2 * 100 / DIFF - 100))
12043                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12044         fi
12045
12046         # Figure out which files were written where
12047         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12048                awk '/'$MINI1': / {print $2; exit}')
12049         echo $UUID
12050         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12051         echo "$MINC files created on smaller OST $MINI1"
12052         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12053                awk '/'$MAXI1': / {print $2; exit}')
12054         echo $UUID
12055         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12056         echo "$MAXC files created on larger OST $MAXI1"
12057         if [[ $MINC -gt 0 ]]; then
12058                 FILL=$((MAXC * 100 / MINC - 100))
12059                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12060         fi
12061         [[ $MAXC -gt $MINC ]] ||
12062                 error_ignore LU-9 "stripe QOS didn't balance free space"
12063 }
12064 run_test 116a "stripe QOS: free space balance ==================="
12065
12066 test_116b() { # LU-2093
12067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12068         remote_mds_nodsh && skip "remote MDS with nodsh"
12069
12070 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12071         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12072                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12073         [ -z "$old_rr" ] && skip "no QOS"
12074         do_facet $SINGLEMDS lctl set_param \
12075                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12076         mkdir -p $DIR/$tdir
12077         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12078         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12079         do_facet $SINGLEMDS lctl set_param fail_loc=0
12080         rm -rf $DIR/$tdir
12081         do_facet $SINGLEMDS lctl set_param \
12082                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12083 }
12084 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12085
12086 test_117() # bug 10891
12087 {
12088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12089
12090         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12091         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12092         lctl set_param fail_loc=0x21e
12093         > $DIR/$tfile || error "truncate failed"
12094         lctl set_param fail_loc=0
12095         echo "Truncate succeeded."
12096         rm -f $DIR/$tfile
12097 }
12098 run_test 117 "verify osd extend =========="
12099
12100 NO_SLOW_RESENDCOUNT=4
12101 export OLD_RESENDCOUNT=""
12102 set_resend_count () {
12103         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12104         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12105         lctl set_param -n $PROC_RESENDCOUNT $1
12106         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12107 }
12108
12109 # for reduce test_118* time (b=14842)
12110 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12111
12112 # Reset async IO behavior after error case
12113 reset_async() {
12114         FILE=$DIR/reset_async
12115
12116         # Ensure all OSCs are cleared
12117         $LFS setstripe -c -1 $FILE
12118         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12119         sync
12120         rm $FILE
12121 }
12122
12123 test_118a() #bug 11710
12124 {
12125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12126
12127         reset_async
12128
12129         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12130         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12131         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12132
12133         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12134                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12135                 return 1;
12136         fi
12137         rm -f $DIR/$tfile
12138 }
12139 run_test 118a "verify O_SYNC works =========="
12140
12141 test_118b()
12142 {
12143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12144         remote_ost_nodsh && skip "remote OST with nodsh"
12145
12146         reset_async
12147
12148         #define OBD_FAIL_SRV_ENOENT 0x217
12149         set_nodes_failloc "$(osts_nodes)" 0x217
12150         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12151         RC=$?
12152         set_nodes_failloc "$(osts_nodes)" 0
12153         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12154         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12155                     grep -c writeback)
12156
12157         if [[ $RC -eq 0 ]]; then
12158                 error "Must return error due to dropped pages, rc=$RC"
12159                 return 1;
12160         fi
12161
12162         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12163                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12164                 return 1;
12165         fi
12166
12167         echo "Dirty pages not leaked on ENOENT"
12168
12169         # Due to the above error the OSC will issue all RPCs syncronously
12170         # until a subsequent RPC completes successfully without error.
12171         $MULTIOP $DIR/$tfile Ow4096yc
12172         rm -f $DIR/$tfile
12173
12174         return 0
12175 }
12176 run_test 118b "Reclaim dirty pages on fatal error =========="
12177
12178 test_118c()
12179 {
12180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12181
12182         # for 118c, restore the original resend count, LU-1940
12183         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12184                                 set_resend_count $OLD_RESENDCOUNT
12185         remote_ost_nodsh && skip "remote OST with nodsh"
12186
12187         reset_async
12188
12189         #define OBD_FAIL_OST_EROFS               0x216
12190         set_nodes_failloc "$(osts_nodes)" 0x216
12191
12192         # multiop should block due to fsync until pages are written
12193         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12194         MULTIPID=$!
12195         sleep 1
12196
12197         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12198                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12199         fi
12200
12201         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12202                     grep -c writeback)
12203         if [[ $WRITEBACK -eq 0 ]]; then
12204                 error "No page in writeback, writeback=$WRITEBACK"
12205         fi
12206
12207         set_nodes_failloc "$(osts_nodes)" 0
12208         wait $MULTIPID
12209         RC=$?
12210         if [[ $RC -ne 0 ]]; then
12211                 error "Multiop fsync failed, rc=$RC"
12212         fi
12213
12214         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12215         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12216                     grep -c writeback)
12217         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12218                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12219         fi
12220
12221         rm -f $DIR/$tfile
12222         echo "Dirty pages flushed via fsync on EROFS"
12223         return 0
12224 }
12225 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12226
12227 # continue to use small resend count to reduce test_118* time (b=14842)
12228 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12229
12230 test_118d()
12231 {
12232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12233         remote_ost_nodsh && skip "remote OST with nodsh"
12234
12235         reset_async
12236
12237         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12238         set_nodes_failloc "$(osts_nodes)" 0x214
12239         # multiop should block due to fsync until pages are written
12240         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12241         MULTIPID=$!
12242         sleep 1
12243
12244         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12245                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12246         fi
12247
12248         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12249                     grep -c writeback)
12250         if [[ $WRITEBACK -eq 0 ]]; then
12251                 error "No page in writeback, writeback=$WRITEBACK"
12252         fi
12253
12254         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12255         set_nodes_failloc "$(osts_nodes)" 0
12256
12257         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12258         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12259                     grep -c writeback)
12260         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12261                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12262         fi
12263
12264         rm -f $DIR/$tfile
12265         echo "Dirty pages gaurenteed flushed via fsync"
12266         return 0
12267 }
12268 run_test 118d "Fsync validation inject a delay of the bulk =========="
12269
12270 test_118f() {
12271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12272
12273         reset_async
12274
12275         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12276         lctl set_param fail_loc=0x8000040a
12277
12278         # Should simulate EINVAL error which is fatal
12279         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12280         RC=$?
12281         if [[ $RC -eq 0 ]]; then
12282                 error "Must return error due to dropped pages, rc=$RC"
12283         fi
12284
12285         lctl set_param fail_loc=0x0
12286
12287         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12288         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12289         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12290                     grep -c writeback)
12291         if [[ $LOCKED -ne 0 ]]; then
12292                 error "Locked pages remain in cache, locked=$LOCKED"
12293         fi
12294
12295         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12296                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12297         fi
12298
12299         rm -f $DIR/$tfile
12300         echo "No pages locked after fsync"
12301
12302         reset_async
12303         return 0
12304 }
12305 run_test 118f "Simulate unrecoverable OSC side error =========="
12306
12307 test_118g() {
12308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12309
12310         reset_async
12311
12312         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12313         lctl set_param fail_loc=0x406
12314
12315         # simulate local -ENOMEM
12316         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12317         RC=$?
12318
12319         lctl set_param fail_loc=0
12320         if [[ $RC -eq 0 ]]; then
12321                 error "Must return error due to dropped pages, rc=$RC"
12322         fi
12323
12324         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12325         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12326         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12327                         grep -c writeback)
12328         if [[ $LOCKED -ne 0 ]]; then
12329                 error "Locked pages remain in cache, locked=$LOCKED"
12330         fi
12331
12332         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12333                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12334         fi
12335
12336         rm -f $DIR/$tfile
12337         echo "No pages locked after fsync"
12338
12339         reset_async
12340         return 0
12341 }
12342 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12343
12344 test_118h() {
12345         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12346         remote_ost_nodsh && skip "remote OST with nodsh"
12347
12348         reset_async
12349
12350         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12351         set_nodes_failloc "$(osts_nodes)" 0x20e
12352         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12353         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12354         RC=$?
12355
12356         set_nodes_failloc "$(osts_nodes)" 0
12357         if [[ $RC -eq 0 ]]; then
12358                 error "Must return error due to dropped pages, rc=$RC"
12359         fi
12360
12361         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12362         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12363         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12364                     grep -c writeback)
12365         if [[ $LOCKED -ne 0 ]]; then
12366                 error "Locked pages remain in cache, locked=$LOCKED"
12367         fi
12368
12369         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12370                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12371         fi
12372
12373         rm -f $DIR/$tfile
12374         echo "No pages locked after fsync"
12375
12376         return 0
12377 }
12378 run_test 118h "Verify timeout in handling recoverables errors  =========="
12379
12380 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12381
12382 test_118i() {
12383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12384         remote_ost_nodsh && skip "remote OST with nodsh"
12385
12386         reset_async
12387
12388         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12389         set_nodes_failloc "$(osts_nodes)" 0x20e
12390
12391         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12392         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12393         PID=$!
12394         sleep 5
12395         set_nodes_failloc "$(osts_nodes)" 0
12396
12397         wait $PID
12398         RC=$?
12399         if [[ $RC -ne 0 ]]; then
12400                 error "got error, but should be not, rc=$RC"
12401         fi
12402
12403         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12404         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12405         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12406         if [[ $LOCKED -ne 0 ]]; then
12407                 error "Locked pages remain in cache, locked=$LOCKED"
12408         fi
12409
12410         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12411                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12412         fi
12413
12414         rm -f $DIR/$tfile
12415         echo "No pages locked after fsync"
12416
12417         return 0
12418 }
12419 run_test 118i "Fix error before timeout in recoverable error  =========="
12420
12421 [ "$SLOW" = "no" ] && set_resend_count 4
12422
12423 test_118j() {
12424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12425         remote_ost_nodsh && skip "remote OST with nodsh"
12426
12427         reset_async
12428
12429         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12430         set_nodes_failloc "$(osts_nodes)" 0x220
12431
12432         # return -EIO from OST
12433         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12434         RC=$?
12435         set_nodes_failloc "$(osts_nodes)" 0x0
12436         if [[ $RC -eq 0 ]]; then
12437                 error "Must return error due to dropped pages, rc=$RC"
12438         fi
12439
12440         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12441         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12442         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12443         if [[ $LOCKED -ne 0 ]]; then
12444                 error "Locked pages remain in cache, locked=$LOCKED"
12445         fi
12446
12447         # in recoverable error on OST we want resend and stay until it finished
12448         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12449                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12450         fi
12451
12452         rm -f $DIR/$tfile
12453         echo "No pages locked after fsync"
12454
12455         return 0
12456 }
12457 run_test 118j "Simulate unrecoverable OST side error =========="
12458
12459 test_118k()
12460 {
12461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12462         remote_ost_nodsh && skip "remote OSTs with nodsh"
12463
12464         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12465         set_nodes_failloc "$(osts_nodes)" 0x20e
12466         test_mkdir $DIR/$tdir
12467
12468         for ((i=0;i<10;i++)); do
12469                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12470                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12471                 SLEEPPID=$!
12472                 sleep 0.500s
12473                 kill $SLEEPPID
12474                 wait $SLEEPPID
12475         done
12476
12477         set_nodes_failloc "$(osts_nodes)" 0
12478         rm -rf $DIR/$tdir
12479 }
12480 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12481
12482 test_118l() # LU-646
12483 {
12484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12485
12486         test_mkdir $DIR/$tdir
12487         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12488         rm -rf $DIR/$tdir
12489 }
12490 run_test 118l "fsync dir"
12491
12492 test_118m() # LU-3066
12493 {
12494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12495
12496         test_mkdir $DIR/$tdir
12497         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12498         rm -rf $DIR/$tdir
12499 }
12500 run_test 118m "fdatasync dir ========="
12501
12502 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12503
12504 test_118n()
12505 {
12506         local begin
12507         local end
12508
12509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12510         remote_ost_nodsh && skip "remote OSTs with nodsh"
12511
12512         # Sleep to avoid a cached response.
12513         #define OBD_STATFS_CACHE_SECONDS 1
12514         sleep 2
12515
12516         # Inject a 10 second delay in the OST_STATFS handler.
12517         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12518         set_nodes_failloc "$(osts_nodes)" 0x242
12519
12520         begin=$SECONDS
12521         stat --file-system $MOUNT > /dev/null
12522         end=$SECONDS
12523
12524         set_nodes_failloc "$(osts_nodes)" 0
12525
12526         if ((end - begin > 20)); then
12527             error "statfs took $((end - begin)) seconds, expected 10"
12528         fi
12529 }
12530 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12531
12532 test_119a() # bug 11737
12533 {
12534         BSIZE=$((512 * 1024))
12535         directio write $DIR/$tfile 0 1 $BSIZE
12536         # We ask to read two blocks, which is more than a file size.
12537         # directio will indicate an error when requested and actual
12538         # sizes aren't equeal (a normal situation in this case) and
12539         # print actual read amount.
12540         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12541         if [ "$NOB" != "$BSIZE" ]; then
12542                 error "read $NOB bytes instead of $BSIZE"
12543         fi
12544         rm -f $DIR/$tfile
12545 }
12546 run_test 119a "Short directIO read must return actual read amount"
12547
12548 test_119b() # bug 11737
12549 {
12550         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12551
12552         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12553         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12554         sync
12555         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12556                 error "direct read failed"
12557         rm -f $DIR/$tfile
12558 }
12559 run_test 119b "Sparse directIO read must return actual read amount"
12560
12561 test_119c() # bug 13099
12562 {
12563         BSIZE=1048576
12564         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12565         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12566         rm -f $DIR/$tfile
12567 }
12568 run_test 119c "Testing for direct read hitting hole"
12569
12570 test_119d() # bug 15950
12571 {
12572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12573
12574         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12575         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12576         BSIZE=1048576
12577         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12578         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12579         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12580         lctl set_param fail_loc=0x40d
12581         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12582         pid_dio=$!
12583         sleep 1
12584         cat $DIR/$tfile > /dev/null &
12585         lctl set_param fail_loc=0
12586         pid_reads=$!
12587         wait $pid_dio
12588         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12589         sleep 2
12590         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12591         error "the read rpcs have not completed in 2s"
12592         rm -f $DIR/$tfile
12593         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12594 }
12595 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12596
12597 test_120a() {
12598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12599         remote_mds_nodsh && skip "remote MDS with nodsh"
12600         test_mkdir -i0 -c1 $DIR/$tdir
12601         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12602                 skip_env "no early lock cancel on server"
12603
12604         lru_resize_disable mdc
12605         lru_resize_disable osc
12606         cancel_lru_locks mdc
12607         # asynchronous object destroy at MDT could cause bl ast to client
12608         cancel_lru_locks osc
12609
12610         stat $DIR/$tdir > /dev/null
12611         can1=$(do_facet mds1 \
12612                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12613                awk '/ldlm_cancel/ {print $2}')
12614         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12615                awk '/ldlm_bl_callback/ {print $2}')
12616         test_mkdir -i0 -c1 $DIR/$tdir/d1
12617         can2=$(do_facet mds1 \
12618                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12619                awk '/ldlm_cancel/ {print $2}')
12620         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12621                awk '/ldlm_bl_callback/ {print $2}')
12622         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12623         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12624         lru_resize_enable mdc
12625         lru_resize_enable osc
12626 }
12627 run_test 120a "Early Lock Cancel: mkdir test"
12628
12629 test_120b() {
12630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12631         remote_mds_nodsh && skip "remote MDS with nodsh"
12632         test_mkdir $DIR/$tdir
12633         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12634                 skip_env "no early lock cancel on server"
12635
12636         lru_resize_disable mdc
12637         lru_resize_disable osc
12638         cancel_lru_locks mdc
12639         stat $DIR/$tdir > /dev/null
12640         can1=$(do_facet $SINGLEMDS \
12641                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12642                awk '/ldlm_cancel/ {print $2}')
12643         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12644                awk '/ldlm_bl_callback/ {print $2}')
12645         touch $DIR/$tdir/f1
12646         can2=$(do_facet $SINGLEMDS \
12647                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12648                awk '/ldlm_cancel/ {print $2}')
12649         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12650                awk '/ldlm_bl_callback/ {print $2}')
12651         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12652         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12653         lru_resize_enable mdc
12654         lru_resize_enable osc
12655 }
12656 run_test 120b "Early Lock Cancel: create test"
12657
12658 test_120c() {
12659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12660         remote_mds_nodsh && skip "remote MDS with nodsh"
12661         test_mkdir -i0 -c1 $DIR/$tdir
12662         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12663                 skip "no early lock cancel on server"
12664
12665         lru_resize_disable mdc
12666         lru_resize_disable osc
12667         test_mkdir -i0 -c1 $DIR/$tdir/d1
12668         test_mkdir -i0 -c1 $DIR/$tdir/d2
12669         touch $DIR/$tdir/d1/f1
12670         cancel_lru_locks mdc
12671         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12672         can1=$(do_facet mds1 \
12673                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12674                awk '/ldlm_cancel/ {print $2}')
12675         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12676                awk '/ldlm_bl_callback/ {print $2}')
12677         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12678         can2=$(do_facet mds1 \
12679                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12680                awk '/ldlm_cancel/ {print $2}')
12681         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12682                awk '/ldlm_bl_callback/ {print $2}')
12683         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12684         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12685         lru_resize_enable mdc
12686         lru_resize_enable osc
12687 }
12688 run_test 120c "Early Lock Cancel: link test"
12689
12690 test_120d() {
12691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12692         remote_mds_nodsh && skip "remote MDS with nodsh"
12693         test_mkdir -i0 -c1 $DIR/$tdir
12694         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12695                 skip_env "no early lock cancel on server"
12696
12697         lru_resize_disable mdc
12698         lru_resize_disable osc
12699         touch $DIR/$tdir
12700         cancel_lru_locks mdc
12701         stat $DIR/$tdir > /dev/null
12702         can1=$(do_facet mds1 \
12703                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12704                awk '/ldlm_cancel/ {print $2}')
12705         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12706                awk '/ldlm_bl_callback/ {print $2}')
12707         chmod a+x $DIR/$tdir
12708         can2=$(do_facet mds1 \
12709                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12710                awk '/ldlm_cancel/ {print $2}')
12711         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12712                awk '/ldlm_bl_callback/ {print $2}')
12713         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12714         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12715         lru_resize_enable mdc
12716         lru_resize_enable osc
12717 }
12718 run_test 120d "Early Lock Cancel: setattr test"
12719
12720 test_120e() {
12721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12722         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12723                 skip_env "no early lock cancel on server"
12724         remote_mds_nodsh && skip "remote MDS with nodsh"
12725
12726         local dlmtrace_set=false
12727
12728         test_mkdir -i0 -c1 $DIR/$tdir
12729         lru_resize_disable mdc
12730         lru_resize_disable osc
12731         ! $LCTL get_param debug | grep -q dlmtrace &&
12732                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12733         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12734         cancel_lru_locks mdc
12735         cancel_lru_locks osc
12736         dd if=$DIR/$tdir/f1 of=/dev/null
12737         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12738         # XXX client can not do early lock cancel of OST lock
12739         # during unlink (LU-4206), so cancel osc lock now.
12740         sleep 2
12741         cancel_lru_locks osc
12742         can1=$(do_facet mds1 \
12743                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12744                awk '/ldlm_cancel/ {print $2}')
12745         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12746                awk '/ldlm_bl_callback/ {print $2}')
12747         unlink $DIR/$tdir/f1
12748         sleep 5
12749         can2=$(do_facet mds1 \
12750                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12751                awk '/ldlm_cancel/ {print $2}')
12752         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12753                awk '/ldlm_bl_callback/ {print $2}')
12754         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12755                 $LCTL dk $TMP/cancel.debug.txt
12756         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12757                 $LCTL dk $TMP/blocking.debug.txt
12758         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12759         lru_resize_enable mdc
12760         lru_resize_enable osc
12761 }
12762 run_test 120e "Early Lock Cancel: unlink test"
12763
12764 test_120f() {
12765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12766         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12767                 skip_env "no early lock cancel on server"
12768         remote_mds_nodsh && skip "remote MDS with nodsh"
12769
12770         test_mkdir -i0 -c1 $DIR/$tdir
12771         lru_resize_disable mdc
12772         lru_resize_disable osc
12773         test_mkdir -i0 -c1 $DIR/$tdir/d1
12774         test_mkdir -i0 -c1 $DIR/$tdir/d2
12775         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12776         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12777         cancel_lru_locks mdc
12778         cancel_lru_locks osc
12779         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12780         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12781         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12782         # XXX client can not do early lock cancel of OST lock
12783         # during rename (LU-4206), so cancel osc lock now.
12784         sleep 2
12785         cancel_lru_locks osc
12786         can1=$(do_facet mds1 \
12787                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12788                awk '/ldlm_cancel/ {print $2}')
12789         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12790                awk '/ldlm_bl_callback/ {print $2}')
12791         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12792         sleep 5
12793         can2=$(do_facet mds1 \
12794                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12795                awk '/ldlm_cancel/ {print $2}')
12796         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12797                awk '/ldlm_bl_callback/ {print $2}')
12798         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12799         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12800         lru_resize_enable mdc
12801         lru_resize_enable osc
12802 }
12803 run_test 120f "Early Lock Cancel: rename test"
12804
12805 test_120g() {
12806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12807         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12808                 skip_env "no early lock cancel on server"
12809         remote_mds_nodsh && skip "remote MDS with nodsh"
12810
12811         lru_resize_disable mdc
12812         lru_resize_disable osc
12813         count=10000
12814         echo create $count files
12815         test_mkdir $DIR/$tdir
12816         cancel_lru_locks mdc
12817         cancel_lru_locks osc
12818         t0=$(date +%s)
12819
12820         can0=$(do_facet $SINGLEMDS \
12821                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12822                awk '/ldlm_cancel/ {print $2}')
12823         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12824                awk '/ldlm_bl_callback/ {print $2}')
12825         createmany -o $DIR/$tdir/f $count
12826         sync
12827         can1=$(do_facet $SINGLEMDS \
12828                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12829                awk '/ldlm_cancel/ {print $2}')
12830         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12831                awk '/ldlm_bl_callback/ {print $2}')
12832         t1=$(date +%s)
12833         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12834         echo rm $count files
12835         rm -r $DIR/$tdir
12836         sync
12837         can2=$(do_facet $SINGLEMDS \
12838                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12839                awk '/ldlm_cancel/ {print $2}')
12840         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12841                awk '/ldlm_bl_callback/ {print $2}')
12842         t2=$(date +%s)
12843         echo total: $count removes in $((t2-t1))
12844         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12845         sleep 2
12846         # wait for commitment of removal
12847         lru_resize_enable mdc
12848         lru_resize_enable osc
12849 }
12850 run_test 120g "Early Lock Cancel: performance test"
12851
12852 test_121() { #bug #10589
12853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12854
12855         rm -rf $DIR/$tfile
12856         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12857 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12858         lctl set_param fail_loc=0x310
12859         cancel_lru_locks osc > /dev/null
12860         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12861         lctl set_param fail_loc=0
12862         [[ $reads -eq $writes ]] ||
12863                 error "read $reads blocks, must be $writes blocks"
12864 }
12865 run_test 121 "read cancel race ========="
12866
12867 test_123a_base() { # was test 123, statahead(bug 11401)
12868         local lsx="$1"
12869
12870         SLOWOK=0
12871         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12872                 log "testing UP system. Performance may be lower than expected."
12873                 SLOWOK=1
12874         fi
12875
12876         rm -rf $DIR/$tdir
12877         test_mkdir $DIR/$tdir
12878         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12879         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12880         MULT=10
12881         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12882                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12883
12884                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12885                 lctl set_param -n llite.*.statahead_max 0
12886                 lctl get_param llite.*.statahead_max
12887                 cancel_lru_locks mdc
12888                 cancel_lru_locks osc
12889                 stime=$(date +%s)
12890                 time $lsx $DIR/$tdir | wc -l
12891                 etime=$(date +%s)
12892                 delta=$((etime - stime))
12893                 log "$lsx $i files without statahead: $delta sec"
12894                 lctl set_param llite.*.statahead_max=$max
12895
12896                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12897                         grep "statahead wrong:" | awk '{print $3}')
12898                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12899                 cancel_lru_locks mdc
12900                 cancel_lru_locks osc
12901                 stime=$(date +%s)
12902                 time $lsx $DIR/$tdir | wc -l
12903                 etime=$(date +%s)
12904                 delta_sa=$((etime - stime))
12905                 log "$lsx $i files with statahead: $delta_sa sec"
12906                 lctl get_param -n llite.*.statahead_stats
12907                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12908                         grep "statahead wrong:" | awk '{print $3}')
12909
12910                 [[ $swrong -lt $ewrong ]] &&
12911                         log "statahead was stopped, maybe too many locks held!"
12912                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12913
12914                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12915                         max=$(lctl get_param -n llite.*.statahead_max |
12916                                 head -n 1)
12917                         lctl set_param -n llite.*.statahead_max 0
12918                         lctl get_param llite.*.statahead_max
12919                         cancel_lru_locks mdc
12920                         cancel_lru_locks osc
12921                         stime=$(date +%s)
12922                         time $lsx $DIR/$tdir | wc -l
12923                         etime=$(date +%s)
12924                         delta=$((etime - stime))
12925                         log "$lsx $i files again without statahead: $delta sec"
12926                         lctl set_param llite.*.statahead_max=$max
12927                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12928                                 if [  $SLOWOK -eq 0 ]; then
12929                                         error "$lsx $i files is slower with statahead!"
12930                                 else
12931                                         log "$lsx $i files is slower with statahead!"
12932                                 fi
12933                                 break
12934                         fi
12935                 fi
12936
12937                 [ $delta -gt 20 ] && break
12938                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12939                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12940         done
12941         log "$lsx done"
12942
12943         stime=$(date +%s)
12944         rm -r $DIR/$tdir
12945         sync
12946         etime=$(date +%s)
12947         delta=$((etime - stime))
12948         log "rm -r $DIR/$tdir/: $delta seconds"
12949         log "rm done"
12950         lctl get_param -n llite.*.statahead_stats
12951 }
12952
12953 test_123aa() {
12954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12955
12956         test_123a_base "ls -l"
12957 }
12958 run_test 123aa "verify statahead work"
12959
12960 test_123ab() {
12961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12962
12963         statx_supported || skip_env "Test must be statx() syscall supported"
12964
12965         test_123a_base "$STATX -l"
12966 }
12967 run_test 123ab "verify statahead work by using statx"
12968
12969 test_123ac() {
12970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12971
12972         statx_supported || skip_env "Test must be statx() syscall supported"
12973
12974         local rpcs_before
12975         local rpcs_after
12976         local agl_before
12977         local agl_after
12978
12979         cancel_lru_locks $OSC
12980         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12981         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12982                 awk '/agl.total:/ {print $3}')
12983         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12984         test_123a_base "$STATX --cached=always -D"
12985         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12986                 awk '/agl.total:/ {print $3}')
12987         [ $agl_before -eq $agl_after ] ||
12988                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12989         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12990         [ $rpcs_after -eq $rpcs_before ] ||
12991                 error "$STATX should not send glimpse RPCs to $OSC"
12992 }
12993 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12994
12995 test_123b () { # statahead(bug 15027)
12996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12997
12998         test_mkdir $DIR/$tdir
12999         createmany -o $DIR/$tdir/$tfile-%d 1000
13000
13001         cancel_lru_locks mdc
13002         cancel_lru_locks osc
13003
13004 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13005         lctl set_param fail_loc=0x80000803
13006         ls -lR $DIR/$tdir > /dev/null
13007         log "ls done"
13008         lctl set_param fail_loc=0x0
13009         lctl get_param -n llite.*.statahead_stats
13010         rm -r $DIR/$tdir
13011         sync
13012
13013 }
13014 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13015
13016 test_123c() {
13017         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13018
13019         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13020         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13021         touch $DIR/$tdir.1/{1..3}
13022         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13023
13024         remount_client $MOUNT
13025
13026         $MULTIOP $DIR/$tdir.0 Q
13027
13028         # let statahead to complete
13029         ls -l $DIR/$tdir.0 > /dev/null
13030
13031         testid=$(echo $TESTNAME | tr '_' ' ')
13032         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13033                 error "statahead warning" || true
13034 }
13035 run_test 123c "Can not initialize inode warning on DNE statahead"
13036
13037 test_124a() {
13038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13039         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13040                 skip_env "no lru resize on server"
13041
13042         local NR=2000
13043
13044         test_mkdir $DIR/$tdir
13045
13046         log "create $NR files at $DIR/$tdir"
13047         createmany -o $DIR/$tdir/f $NR ||
13048                 error "failed to create $NR files in $DIR/$tdir"
13049
13050         cancel_lru_locks mdc
13051         ls -l $DIR/$tdir > /dev/null
13052
13053         local NSDIR=""
13054         local LRU_SIZE=0
13055         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13056                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13057                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13058                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13059                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13060                         log "NSDIR=$NSDIR"
13061                         log "NS=$(basename $NSDIR)"
13062                         break
13063                 fi
13064         done
13065
13066         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13067                 skip "Not enough cached locks created!"
13068         fi
13069         log "LRU=$LRU_SIZE"
13070
13071         local SLEEP=30
13072
13073         # We know that lru resize allows one client to hold $LIMIT locks
13074         # for 10h. After that locks begin to be killed by client.
13075         local MAX_HRS=10
13076         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13077         log "LIMIT=$LIMIT"
13078         if [ $LIMIT -lt $LRU_SIZE ]; then
13079                 skip "Limit is too small $LIMIT"
13080         fi
13081
13082         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13083         # killing locks. Some time was spent for creating locks. This means
13084         # that up to the moment of sleep finish we must have killed some of
13085         # them (10-100 locks). This depends on how fast ther were created.
13086         # Many of them were touched in almost the same moment and thus will
13087         # be killed in groups.
13088         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13089
13090         # Use $LRU_SIZE_B here to take into account real number of locks
13091         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13092         local LRU_SIZE_B=$LRU_SIZE
13093         log "LVF=$LVF"
13094         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13095         log "OLD_LVF=$OLD_LVF"
13096         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13097
13098         # Let's make sure that we really have some margin. Client checks
13099         # cached locks every 10 sec.
13100         SLEEP=$((SLEEP+20))
13101         log "Sleep ${SLEEP} sec"
13102         local SEC=0
13103         while ((SEC<$SLEEP)); do
13104                 echo -n "..."
13105                 sleep 5
13106                 SEC=$((SEC+5))
13107                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13108                 echo -n "$LRU_SIZE"
13109         done
13110         echo ""
13111         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13112         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13113
13114         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13115                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13116                 unlinkmany $DIR/$tdir/f $NR
13117                 return
13118         }
13119
13120         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13121         log "unlink $NR files at $DIR/$tdir"
13122         unlinkmany $DIR/$tdir/f $NR
13123 }
13124 run_test 124a "lru resize ======================================="
13125
13126 get_max_pool_limit()
13127 {
13128         local limit=$($LCTL get_param \
13129                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13130         local max=0
13131         for l in $limit; do
13132                 if [[ $l -gt $max ]]; then
13133                         max=$l
13134                 fi
13135         done
13136         echo $max
13137 }
13138
13139 test_124b() {
13140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13141         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13142                 skip_env "no lru resize on server"
13143
13144         LIMIT=$(get_max_pool_limit)
13145
13146         NR=$(($(default_lru_size)*20))
13147         if [[ $NR -gt $LIMIT ]]; then
13148                 log "Limit lock number by $LIMIT locks"
13149                 NR=$LIMIT
13150         fi
13151
13152         IFree=$(mdsrate_inodes_available)
13153         if [ $IFree -lt $NR ]; then
13154                 log "Limit lock number by $IFree inodes"
13155                 NR=$IFree
13156         fi
13157
13158         lru_resize_disable mdc
13159         test_mkdir -p $DIR/$tdir/disable_lru_resize
13160
13161         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13162         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13163         cancel_lru_locks mdc
13164         stime=`date +%s`
13165         PID=""
13166         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13167         PID="$PID $!"
13168         sleep 2
13169         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13170         PID="$PID $!"
13171         sleep 2
13172         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13173         PID="$PID $!"
13174         wait $PID
13175         etime=`date +%s`
13176         nolruresize_delta=$((etime-stime))
13177         log "ls -la time: $nolruresize_delta seconds"
13178         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13179         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13180
13181         lru_resize_enable mdc
13182         test_mkdir -p $DIR/$tdir/enable_lru_resize
13183
13184         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13185         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13186         cancel_lru_locks mdc
13187         stime=`date +%s`
13188         PID=""
13189         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13190         PID="$PID $!"
13191         sleep 2
13192         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13193         PID="$PID $!"
13194         sleep 2
13195         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13196         PID="$PID $!"
13197         wait $PID
13198         etime=`date +%s`
13199         lruresize_delta=$((etime-stime))
13200         log "ls -la time: $lruresize_delta seconds"
13201         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13202
13203         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13204                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13205         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13206                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13207         else
13208                 log "lru resize performs the same with no lru resize"
13209         fi
13210         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13211 }
13212 run_test 124b "lru resize (performance test) ======================="
13213
13214 test_124c() {
13215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13216         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13217                 skip_env "no lru resize on server"
13218
13219         # cache ununsed locks on client
13220         local nr=100
13221         cancel_lru_locks mdc
13222         test_mkdir $DIR/$tdir
13223         createmany -o $DIR/$tdir/f $nr ||
13224                 error "failed to create $nr files in $DIR/$tdir"
13225         ls -l $DIR/$tdir > /dev/null
13226
13227         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13228         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13229         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13230         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13231         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13232
13233         # set lru_max_age to 1 sec
13234         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13235         echo "sleep $((recalc_p * 2)) seconds..."
13236         sleep $((recalc_p * 2))
13237
13238         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13239         # restore lru_max_age
13240         $LCTL set_param -n $nsdir.lru_max_age $max_age
13241         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13242         unlinkmany $DIR/$tdir/f $nr
13243 }
13244 run_test 124c "LRUR cancel very aged locks"
13245
13246 test_124d() {
13247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13248         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13249                 skip_env "no lru resize on server"
13250
13251         # cache ununsed locks on client
13252         local nr=100
13253
13254         lru_resize_disable mdc
13255         stack_trap "lru_resize_enable mdc" EXIT
13256
13257         cancel_lru_locks mdc
13258
13259         # asynchronous object destroy at MDT could cause bl ast to client
13260         test_mkdir $DIR/$tdir
13261         createmany -o $DIR/$tdir/f $nr ||
13262                 error "failed to create $nr files in $DIR/$tdir"
13263         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13264
13265         ls -l $DIR/$tdir > /dev/null
13266
13267         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13268         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13269         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13270         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13271
13272         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13273
13274         # set lru_max_age to 1 sec
13275         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13276         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13277
13278         echo "sleep $((recalc_p * 2)) seconds..."
13279         sleep $((recalc_p * 2))
13280
13281         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13282
13283         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13284 }
13285 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13286
13287 test_125() { # 13358
13288         $LCTL get_param -n llite.*.client_type | grep -q local ||
13289                 skip "must run as local client"
13290         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13291                 skip_env "must have acl enabled"
13292         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13293
13294         test_mkdir $DIR/$tdir
13295         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13296         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13297         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13298 }
13299 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13300
13301 test_126() { # bug 12829/13455
13302         $GSS && skip_env "must run as gss disabled"
13303         $LCTL get_param -n llite.*.client_type | grep -q local ||
13304                 skip "must run as local client"
13305         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13306
13307         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13308         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13309         rm -f $DIR/$tfile
13310         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13311 }
13312 run_test 126 "check that the fsgid provided by the client is taken into account"
13313
13314 test_127a() { # bug 15521
13315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13316         local name count samp unit min max sum sumsq
13317
13318         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13319         echo "stats before reset"
13320         $LCTL get_param osc.*.stats
13321         $LCTL set_param osc.*.stats=0
13322         local fsize=$((2048 * 1024))
13323
13324         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13325         cancel_lru_locks osc
13326         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13327
13328         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13329         stack_trap "rm -f $TMP/$tfile.tmp"
13330         while read name count samp unit min max sum sumsq; do
13331                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13332                 [ ! $min ] && error "Missing min value for $name proc entry"
13333                 eval $name=$count || error "Wrong proc format"
13334
13335                 case $name in
13336                 read_bytes|write_bytes)
13337                         [[ "$unit" =~ "bytes" ]] ||
13338                                 error "unit is not 'bytes': $unit"
13339                         (( $min >= 4096 )) || error "min is too small: $min"
13340                         (( $min <= $fsize )) || error "min is too big: $min"
13341                         (( $max >= 4096 )) || error "max is too small: $max"
13342                         (( $max <= $fsize )) || error "max is too big: $max"
13343                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13344                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13345                                 error "sumsquare is too small: $sumsq"
13346                         (( $sumsq <= $fsize * $fsize )) ||
13347                                 error "sumsquare is too big: $sumsq"
13348                         ;;
13349                 ost_read|ost_write)
13350                         [[ "$unit" =~ "usec" ]] ||
13351                                 error "unit is not 'usec': $unit"
13352                         ;;
13353                 *)      ;;
13354                 esac
13355         done < $DIR/$tfile.tmp
13356
13357         #check that we actually got some stats
13358         [ "$read_bytes" ] || error "Missing read_bytes stats"
13359         [ "$write_bytes" ] || error "Missing write_bytes stats"
13360         [ "$read_bytes" != 0 ] || error "no read done"
13361         [ "$write_bytes" != 0 ] || error "no write done"
13362 }
13363 run_test 127a "verify the client stats are sane"
13364
13365 test_127b() { # bug LU-333
13366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13367         local name count samp unit min max sum sumsq
13368
13369         echo "stats before reset"
13370         $LCTL get_param llite.*.stats
13371         $LCTL set_param llite.*.stats=0
13372
13373         # perform 2 reads and writes so MAX is different from SUM.
13374         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13375         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13376         cancel_lru_locks osc
13377         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13378         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13379
13380         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13381         stack_trap "rm -f $TMP/$tfile.tmp"
13382         while read name count samp unit min max sum sumsq; do
13383                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13384                 eval $name=$count || error "Wrong proc format"
13385
13386                 case $name in
13387                 read_bytes|write_bytes)
13388                         [[ "$unit" =~ "bytes" ]] ||
13389                                 error "unit is not 'bytes': $unit"
13390                         (( $count == 2 )) || error "count is not 2: $count"
13391                         (( $min == $PAGE_SIZE )) ||
13392                                 error "min is not $PAGE_SIZE: $min"
13393                         (( $max == $PAGE_SIZE )) ||
13394                                 error "max is not $PAGE_SIZE: $max"
13395                         (( $sum == $PAGE_SIZE * 2 )) ||
13396                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13397                         ;;
13398                 read|write)
13399                         [[ "$unit" =~ "usec" ]] ||
13400                                 error "unit is not 'usec': $unit"
13401                         ;;
13402                 *)      ;;
13403                 esac
13404         done < $TMP/$tfile.tmp
13405
13406         #check that we actually got some stats
13407         [ "$read_bytes" ] || error "Missing read_bytes stats"
13408         [ "$write_bytes" ] || error "Missing write_bytes stats"
13409         [ "$read_bytes" != 0 ] || error "no read done"
13410         [ "$write_bytes" != 0 ] || error "no write done"
13411 }
13412 run_test 127b "verify the llite client stats are sane"
13413
13414 test_127c() { # LU-12394
13415         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13416         local size
13417         local bsize
13418         local reads
13419         local writes
13420         local count
13421
13422         $LCTL set_param llite.*.extents_stats=1
13423         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13424
13425         # Use two stripes so there is enough space in default config
13426         $LFS setstripe -c 2 $DIR/$tfile
13427
13428         # Extent stats start at 0-4K and go in power of two buckets
13429         # LL_HIST_START = 12 --> 2^12 = 4K
13430         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13431         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13432         # small configs
13433         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13434                 do
13435                 # Write and read, 2x each, second time at a non-zero offset
13436                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13437                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13438                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13439                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13440                 rm -f $DIR/$tfile
13441         done
13442
13443         $LCTL get_param llite.*.extents_stats
13444
13445         count=2
13446         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13447                 do
13448                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13449                                 grep -m 1 $bsize)
13450                 reads=$(echo $bucket | awk '{print $5}')
13451                 writes=$(echo $bucket | awk '{print $9}')
13452                 [ "$reads" -eq $count ] ||
13453                         error "$reads reads in < $bsize bucket, expect $count"
13454                 [ "$writes" -eq $count ] ||
13455                         error "$writes writes in < $bsize bucket, expect $count"
13456         done
13457
13458         # Test mmap write and read
13459         $LCTL set_param llite.*.extents_stats=c
13460         size=512
13461         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13462         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13463         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13464
13465         $LCTL get_param llite.*.extents_stats
13466
13467         count=$(((size*1024) / PAGE_SIZE))
13468
13469         bsize=$((2 * PAGE_SIZE / 1024))K
13470
13471         bucket=$($LCTL get_param -n llite.*.extents_stats |
13472                         grep -m 1 $bsize)
13473         reads=$(echo $bucket | awk '{print $5}')
13474         writes=$(echo $bucket | awk '{print $9}')
13475         # mmap writes fault in the page first, creating an additonal read
13476         [ "$reads" -eq $((2 * count)) ] ||
13477                 error "$reads reads in < $bsize bucket, expect $count"
13478         [ "$writes" -eq $count ] ||
13479                 error "$writes writes in < $bsize bucket, expect $count"
13480 }
13481 run_test 127c "test llite extent stats with regular & mmap i/o"
13482
13483 test_128() { # bug 15212
13484         touch $DIR/$tfile
13485         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13486                 find $DIR/$tfile
13487                 find $DIR/$tfile
13488         EOF
13489
13490         result=$(grep error $TMP/$tfile.log)
13491         rm -f $DIR/$tfile $TMP/$tfile.log
13492         [ -z "$result" ] ||
13493                 error "consecutive find's under interactive lfs failed"
13494 }
13495 run_test 128 "interactive lfs for 2 consecutive find's"
13496
13497 set_dir_limits () {
13498         local mntdev
13499         local canondev
13500         local node
13501
13502         local ldproc=/proc/fs/ldiskfs
13503         local facets=$(get_facets MDS)
13504
13505         for facet in ${facets//,/ }; do
13506                 canondev=$(ldiskfs_canon \
13507                            *.$(convert_facet2label $facet).mntdev $facet)
13508                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13509                         ldproc=/sys/fs/ldiskfs
13510                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13511                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13512         done
13513 }
13514
13515 check_mds_dmesg() {
13516         local facets=$(get_facets MDS)
13517         for facet in ${facets//,/ }; do
13518                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13519         done
13520         return 1
13521 }
13522
13523 test_129() {
13524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13525         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13526                 skip "Need MDS version with at least 2.5.56"
13527         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13528                 skip_env "ldiskfs only test"
13529         fi
13530         remote_mds_nodsh && skip "remote MDS with nodsh"
13531
13532         local ENOSPC=28
13533         local has_warning=false
13534
13535         rm -rf $DIR/$tdir
13536         mkdir -p $DIR/$tdir
13537
13538         # block size of mds1
13539         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13540         set_dir_limits $maxsize $((maxsize * 6 / 8))
13541         stack_trap "set_dir_limits 0 0"
13542         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13543         local dirsize=$(stat -c%s "$DIR/$tdir")
13544         local nfiles=0
13545         while (( $dirsize <= $maxsize )); do
13546                 $MCREATE $DIR/$tdir/file_base_$nfiles
13547                 rc=$?
13548                 # check two errors:
13549                 # ENOSPC for ext4 max_dir_size, which has been used since
13550                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13551                 if (( rc == ENOSPC )); then
13552                         set_dir_limits 0 0
13553                         echo "rc=$rc returned as expected after $nfiles files"
13554
13555                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13556                                 error "create failed w/o dir size limit"
13557
13558                         # messages may be rate limited if test is run repeatedly
13559                         check_mds_dmesg '"is approaching max"' ||
13560                                 echo "warning message should be output"
13561                         check_mds_dmesg '"has reached max"' ||
13562                                 echo "reached message should be output"
13563
13564                         dirsize=$(stat -c%s "$DIR/$tdir")
13565
13566                         [[ $dirsize -ge $maxsize ]] && return 0
13567                         error "dirsize $dirsize < $maxsize after $nfiles files"
13568                 elif (( rc != 0 )); then
13569                         break
13570                 fi
13571                 nfiles=$((nfiles + 1))
13572                 dirsize=$(stat -c%s "$DIR/$tdir")
13573         done
13574
13575         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13576 }
13577 run_test 129 "test directory size limit ========================"
13578
13579 OLDIFS="$IFS"
13580 cleanup_130() {
13581         trap 0
13582         IFS="$OLDIFS"
13583 }
13584
13585 test_130a() {
13586         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13587         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13588
13589         trap cleanup_130 EXIT RETURN
13590
13591         local fm_file=$DIR/$tfile
13592         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13593         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13594                 error "dd failed for $fm_file"
13595
13596         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13597         filefrag -ves $fm_file
13598         RC=$?
13599         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13600                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13601         [ $RC != 0 ] && error "filefrag $fm_file failed"
13602
13603         filefrag_op=$(filefrag -ve -k $fm_file |
13604                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13605         lun=$($LFS getstripe -i $fm_file)
13606
13607         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13608         IFS=$'\n'
13609         tot_len=0
13610         for line in $filefrag_op
13611         do
13612                 frag_lun=`echo $line | cut -d: -f5`
13613                 ext_len=`echo $line | cut -d: -f4`
13614                 if (( $frag_lun != $lun )); then
13615                         cleanup_130
13616                         error "FIEMAP on 1-stripe file($fm_file) failed"
13617                         return
13618                 fi
13619                 (( tot_len += ext_len ))
13620         done
13621
13622         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13623                 cleanup_130
13624                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13625                 return
13626         fi
13627
13628         cleanup_130
13629
13630         echo "FIEMAP on single striped file succeeded"
13631 }
13632 run_test 130a "FIEMAP (1-stripe file)"
13633
13634 test_130b() {
13635         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13636
13637         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13638         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13639
13640         trap cleanup_130 EXIT RETURN
13641
13642         local fm_file=$DIR/$tfile
13643         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13644                         error "setstripe on $fm_file"
13645         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13646                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13647
13648         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13649                 error "dd failed on $fm_file"
13650
13651         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13652         filefrag_op=$(filefrag -ve -k $fm_file |
13653                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13654
13655         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13656                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13657
13658         IFS=$'\n'
13659         tot_len=0
13660         num_luns=1
13661         for line in $filefrag_op
13662         do
13663                 frag_lun=$(echo $line | cut -d: -f5 |
13664                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13665                 ext_len=$(echo $line | cut -d: -f4)
13666                 if (( $frag_lun != $last_lun )); then
13667                         if (( tot_len != 1024 )); then
13668                                 cleanup_130
13669                                 error "FIEMAP on $fm_file failed; returned " \
13670                                 "len $tot_len for OST $last_lun instead of 1024"
13671                                 return
13672                         else
13673                                 (( num_luns += 1 ))
13674                                 tot_len=0
13675                         fi
13676                 fi
13677                 (( tot_len += ext_len ))
13678                 last_lun=$frag_lun
13679         done
13680         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13681                 cleanup_130
13682                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13683                         "luns or wrong len for OST $last_lun"
13684                 return
13685         fi
13686
13687         cleanup_130
13688
13689         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13690 }
13691 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13692
13693 test_130c() {
13694         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13695
13696         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13697         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13698
13699         trap cleanup_130 EXIT RETURN
13700
13701         local fm_file=$DIR/$tfile
13702         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13703         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13704                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13705
13706         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13707                         error "dd failed on $fm_file"
13708
13709         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13710         filefrag_op=$(filefrag -ve -k $fm_file |
13711                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13712
13713         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13714                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13715
13716         IFS=$'\n'
13717         tot_len=0
13718         num_luns=1
13719         for line in $filefrag_op
13720         do
13721                 frag_lun=$(echo $line | cut -d: -f5 |
13722                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13723                 ext_len=$(echo $line | cut -d: -f4)
13724                 if (( $frag_lun != $last_lun )); then
13725                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13726                         if (( logical != 512 )); then
13727                                 cleanup_130
13728                                 error "FIEMAP on $fm_file failed; returned " \
13729                                 "logical start for lun $logical instead of 512"
13730                                 return
13731                         fi
13732                         if (( tot_len != 512 )); then
13733                                 cleanup_130
13734                                 error "FIEMAP on $fm_file failed; returned " \
13735                                 "len $tot_len for OST $last_lun instead of 1024"
13736                                 return
13737                         else
13738                                 (( num_luns += 1 ))
13739                                 tot_len=0
13740                         fi
13741                 fi
13742                 (( tot_len += ext_len ))
13743                 last_lun=$frag_lun
13744         done
13745         if (( num_luns != 2 || tot_len != 512 )); then
13746                 cleanup_130
13747                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13748                         "luns or wrong len for OST $last_lun"
13749                 return
13750         fi
13751
13752         cleanup_130
13753
13754         echo "FIEMAP on 2-stripe file with hole succeeded"
13755 }
13756 run_test 130c "FIEMAP (2-stripe file with hole)"
13757
13758 test_130d() {
13759         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13760
13761         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13762         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13763
13764         trap cleanup_130 EXIT RETURN
13765
13766         local fm_file=$DIR/$tfile
13767         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13768                         error "setstripe on $fm_file"
13769         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13770                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13771
13772         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13773         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13774                 error "dd failed on $fm_file"
13775
13776         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13777         filefrag_op=$(filefrag -ve -k $fm_file |
13778                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13779
13780         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13781                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13782
13783         IFS=$'\n'
13784         tot_len=0
13785         num_luns=1
13786         for line in $filefrag_op
13787         do
13788                 frag_lun=$(echo $line | cut -d: -f5 |
13789                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13790                 ext_len=$(echo $line | cut -d: -f4)
13791                 if (( $frag_lun != $last_lun )); then
13792                         if (( tot_len != 1024 )); then
13793                                 cleanup_130
13794                                 error "FIEMAP on $fm_file failed; returned " \
13795                                 "len $tot_len for OST $last_lun instead of 1024"
13796                                 return
13797                         else
13798                                 (( num_luns += 1 ))
13799                                 tot_len=0
13800                         fi
13801                 fi
13802                 (( tot_len += ext_len ))
13803                 last_lun=$frag_lun
13804         done
13805         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13806                 cleanup_130
13807                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13808                         "luns or wrong len for OST $last_lun"
13809                 return
13810         fi
13811
13812         cleanup_130
13813
13814         echo "FIEMAP on N-stripe file succeeded"
13815 }
13816 run_test 130d "FIEMAP (N-stripe file)"
13817
13818 test_130e() {
13819         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13820
13821         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13822         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13823
13824         trap cleanup_130 EXIT RETURN
13825
13826         local fm_file=$DIR/$tfile
13827         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13828
13829         NUM_BLKS=512
13830         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13831         for ((i = 0; i < $NUM_BLKS; i++)); do
13832                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13833                         conv=notrunc > /dev/null 2>&1
13834         done
13835
13836         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13837         filefrag_op=$(filefrag -ve -k $fm_file |
13838                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13839
13840         last_lun=$(echo $filefrag_op | cut -d: -f5)
13841
13842         IFS=$'\n'
13843         tot_len=0
13844         num_luns=1
13845         for line in $filefrag_op; do
13846                 frag_lun=$(echo $line | cut -d: -f5)
13847                 ext_len=$(echo $line | cut -d: -f4)
13848                 if [[ "$frag_lun" != "$last_lun" ]]; then
13849                         if (( tot_len != $EXPECTED_LEN )); then
13850                                 cleanup_130
13851                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13852                         else
13853                                 (( num_luns += 1 ))
13854                                 tot_len=0
13855                         fi
13856                 fi
13857                 (( tot_len += ext_len ))
13858                 last_lun=$frag_lun
13859         done
13860         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13861                 cleanup_130
13862                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13863         fi
13864
13865         echo "FIEMAP with continuation calls succeeded"
13866 }
13867 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13868
13869 test_130f() {
13870         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13871         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13872
13873         local fm_file=$DIR/$tfile
13874         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13875                 error "multiop create with lov_delay_create on $fm_file"
13876
13877         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13878         filefrag_extents=$(filefrag -vek $fm_file |
13879                            awk '/extents? found/ { print $2 }')
13880         if [[ "$filefrag_extents" != "0" ]]; then
13881                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13882         fi
13883
13884         rm -f $fm_file
13885 }
13886 run_test 130f "FIEMAP (unstriped file)"
13887
13888 test_130g() {
13889         local file=$DIR/$tfile
13890         local nr=$((OSTCOUNT * 100))
13891
13892         $LFS setstripe -C $nr $file ||
13893                 error "failed to setstripe -C $nr $file"
13894
13895         dd if=/dev/zero of=$file count=$nr bs=1M
13896         sync
13897         nr=$($LFS getstripe -c $file)
13898
13899         local extents=$(filefrag -v $file |
13900                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13901
13902         echo "filefrag list $extents extents in file with stripecount $nr"
13903         if (( extents < nr )); then
13904                 $LFS getstripe $file
13905                 filefrag -v $file
13906                 error "filefrag printed $extents < $nr extents"
13907         fi
13908
13909         rm -f $file
13910 }
13911 run_test 130g "FIEMAP (overstripe file)"
13912
13913 # Test for writev/readv
13914 test_131a() {
13915         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13916                 error "writev test failed"
13917         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13918                 error "readv failed"
13919         rm -f $DIR/$tfile
13920 }
13921 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13922
13923 test_131b() {
13924         local fsize=$((524288 + 1048576 + 1572864))
13925         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13926                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13927                         error "append writev test failed"
13928
13929         ((fsize += 1572864 + 1048576))
13930         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13931                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13932                         error "append writev test failed"
13933         rm -f $DIR/$tfile
13934 }
13935 run_test 131b "test append writev"
13936
13937 test_131c() {
13938         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13939         error "NOT PASS"
13940 }
13941 run_test 131c "test read/write on file w/o objects"
13942
13943 test_131d() {
13944         rwv -f $DIR/$tfile -w -n 1 1572864
13945         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13946         if [ "$NOB" != 1572864 ]; then
13947                 error "Short read filed: read $NOB bytes instead of 1572864"
13948         fi
13949         rm -f $DIR/$tfile
13950 }
13951 run_test 131d "test short read"
13952
13953 test_131e() {
13954         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13955         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13956         error "read hitting hole failed"
13957         rm -f $DIR/$tfile
13958 }
13959 run_test 131e "test read hitting hole"
13960
13961 check_stats() {
13962         local facet=$1
13963         local op=$2
13964         local want=${3:-0}
13965         local res
13966
13967         case $facet in
13968         mds*) res=$(do_facet $facet \
13969                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13970                  ;;
13971         ost*) res=$(do_facet $facet \
13972                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13973                  ;;
13974         *) error "Wrong facet '$facet'" ;;
13975         esac
13976         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13977         # if the argument $3 is zero, it means any stat increment is ok.
13978         if [[ $want -gt 0 ]]; then
13979                 local count=$(echo $res | awk '{ print $2 }')
13980                 [[ $count -ne $want ]] &&
13981                         error "The $op counter on $facet is $count, not $want"
13982         fi
13983 }
13984
13985 test_133a() {
13986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13987         remote_ost_nodsh && skip "remote OST with nodsh"
13988         remote_mds_nodsh && skip "remote MDS with nodsh"
13989         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13990                 skip_env "MDS doesn't support rename stats"
13991
13992         local testdir=$DIR/${tdir}/stats_testdir
13993
13994         mkdir -p $DIR/${tdir}
13995
13996         # clear stats.
13997         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13998         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13999
14000         # verify mdt stats first.
14001         mkdir ${testdir} || error "mkdir failed"
14002         check_stats $SINGLEMDS "mkdir" 1
14003         touch ${testdir}/${tfile} || error "touch failed"
14004         check_stats $SINGLEMDS "open" 1
14005         check_stats $SINGLEMDS "close" 1
14006         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14007                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14008                 check_stats $SINGLEMDS "mknod" 2
14009         }
14010         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14011         check_stats $SINGLEMDS "unlink" 1
14012         rm -f ${testdir}/${tfile} || error "file remove failed"
14013         check_stats $SINGLEMDS "unlink" 2
14014
14015         # remove working dir and check mdt stats again.
14016         rmdir ${testdir} || error "rmdir failed"
14017         check_stats $SINGLEMDS "rmdir" 1
14018
14019         local testdir1=$DIR/${tdir}/stats_testdir1
14020         mkdir -p ${testdir}
14021         mkdir -p ${testdir1}
14022         touch ${testdir1}/test1
14023         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14024         check_stats $SINGLEMDS "crossdir_rename" 1
14025
14026         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14027         check_stats $SINGLEMDS "samedir_rename" 1
14028
14029         rm -rf $DIR/${tdir}
14030 }
14031 run_test 133a "Verifying MDT stats ========================================"
14032
14033 test_133b() {
14034         local res
14035
14036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14037         remote_ost_nodsh && skip "remote OST with nodsh"
14038         remote_mds_nodsh && skip "remote MDS with nodsh"
14039
14040         local testdir=$DIR/${tdir}/stats_testdir
14041
14042         mkdir -p ${testdir} || error "mkdir failed"
14043         touch ${testdir}/${tfile} || error "touch failed"
14044         cancel_lru_locks mdc
14045
14046         # clear stats.
14047         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14048         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14049
14050         # extra mdt stats verification.
14051         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14052         check_stats $SINGLEMDS "setattr" 1
14053         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14054         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14055         then            # LU-1740
14056                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14057                 check_stats $SINGLEMDS "getattr" 1
14058         fi
14059         rm -rf $DIR/${tdir}
14060
14061         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14062         # so the check below is not reliable
14063         [ $MDSCOUNT -eq 1 ] || return 0
14064
14065         # Sleep to avoid a cached response.
14066         #define OBD_STATFS_CACHE_SECONDS 1
14067         sleep 2
14068         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14069         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14070         $LFS df || error "lfs failed"
14071         check_stats $SINGLEMDS "statfs" 1
14072
14073         # check aggregated statfs (LU-10018)
14074         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14075                 return 0
14076         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14077                 return 0
14078         sleep 2
14079         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14080         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14081         df $DIR
14082         check_stats $SINGLEMDS "statfs" 1
14083
14084         # We want to check that the client didn't send OST_STATFS to
14085         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14086         # extra care is needed here.
14087         if remote_mds; then
14088                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14089                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14090
14091                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14092                 [ "$res" ] && error "OST got STATFS"
14093         fi
14094
14095         return 0
14096 }
14097 run_test 133b "Verifying extra MDT stats =================================="
14098
14099 test_133c() {
14100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14101         remote_ost_nodsh && skip "remote OST with nodsh"
14102         remote_mds_nodsh && skip "remote MDS with nodsh"
14103
14104         local testdir=$DIR/$tdir/stats_testdir
14105
14106         test_mkdir -p $testdir
14107
14108         # verify obdfilter stats.
14109         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14110         sync
14111         cancel_lru_locks osc
14112         wait_delete_completed
14113
14114         # clear stats.
14115         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14116         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14117
14118         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14119                 error "dd failed"
14120         sync
14121         cancel_lru_locks osc
14122         check_stats ost1 "write" 1
14123
14124         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14125         check_stats ost1 "read" 1
14126
14127         > $testdir/$tfile || error "truncate failed"
14128         check_stats ost1 "punch" 1
14129
14130         rm -f $testdir/$tfile || error "file remove failed"
14131         wait_delete_completed
14132         check_stats ost1 "destroy" 1
14133
14134         rm -rf $DIR/$tdir
14135 }
14136 run_test 133c "Verifying OST stats ========================================"
14137
14138 order_2() {
14139         local value=$1
14140         local orig=$value
14141         local order=1
14142
14143         while [ $value -ge 2 ]; do
14144                 order=$((order*2))
14145                 value=$((value/2))
14146         done
14147
14148         if [ $orig -gt $order ]; then
14149                 order=$((order*2))
14150         fi
14151         echo $order
14152 }
14153
14154 size_in_KMGT() {
14155     local value=$1
14156     local size=('K' 'M' 'G' 'T');
14157     local i=0
14158     local size_string=$value
14159
14160     while [ $value -ge 1024 ]; do
14161         if [ $i -gt 3 ]; then
14162             #T is the biggest unit we get here, if that is bigger,
14163             #just return XXXT
14164             size_string=${value}T
14165             break
14166         fi
14167         value=$((value >> 10))
14168         if [ $value -lt 1024 ]; then
14169             size_string=${value}${size[$i]}
14170             break
14171         fi
14172         i=$((i + 1))
14173     done
14174
14175     echo $size_string
14176 }
14177
14178 get_rename_size() {
14179         local size=$1
14180         local context=${2:-.}
14181         local sample=$(do_facet $SINGLEMDS $LCTL \
14182                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14183                 grep -A1 $context |
14184                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14185         echo $sample
14186 }
14187
14188 test_133d() {
14189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14190         remote_ost_nodsh && skip "remote OST with nodsh"
14191         remote_mds_nodsh && skip "remote MDS with nodsh"
14192         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14193                 skip_env "MDS doesn't support rename stats"
14194
14195         local testdir1=$DIR/${tdir}/stats_testdir1
14196         local testdir2=$DIR/${tdir}/stats_testdir2
14197         mkdir -p $DIR/${tdir}
14198
14199         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14200
14201         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14202         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14203
14204         createmany -o $testdir1/test 512 || error "createmany failed"
14205
14206         # check samedir rename size
14207         mv ${testdir1}/test0 ${testdir1}/test_0
14208
14209         local testdir1_size=$(ls -l $DIR/${tdir} |
14210                 awk '/stats_testdir1/ {print $5}')
14211         local testdir2_size=$(ls -l $DIR/${tdir} |
14212                 awk '/stats_testdir2/ {print $5}')
14213
14214         testdir1_size=$(order_2 $testdir1_size)
14215         testdir2_size=$(order_2 $testdir2_size)
14216
14217         testdir1_size=$(size_in_KMGT $testdir1_size)
14218         testdir2_size=$(size_in_KMGT $testdir2_size)
14219
14220         echo "source rename dir size: ${testdir1_size}"
14221         echo "target rename dir size: ${testdir2_size}"
14222
14223         local cmd="do_facet $SINGLEMDS $LCTL "
14224         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14225
14226         eval $cmd || error "$cmd failed"
14227         local samedir=$($cmd | grep 'same_dir')
14228         local same_sample=$(get_rename_size $testdir1_size)
14229         [ -z "$samedir" ] && error "samedir_rename_size count error"
14230         [[ $same_sample -eq 1 ]] ||
14231                 error "samedir_rename_size error $same_sample"
14232         echo "Check same dir rename stats success"
14233
14234         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14235
14236         # check crossdir rename size
14237         mv ${testdir1}/test_0 ${testdir2}/test_0
14238
14239         testdir1_size=$(ls -l $DIR/${tdir} |
14240                 awk '/stats_testdir1/ {print $5}')
14241         testdir2_size=$(ls -l $DIR/${tdir} |
14242                 awk '/stats_testdir2/ {print $5}')
14243
14244         testdir1_size=$(order_2 $testdir1_size)
14245         testdir2_size=$(order_2 $testdir2_size)
14246
14247         testdir1_size=$(size_in_KMGT $testdir1_size)
14248         testdir2_size=$(size_in_KMGT $testdir2_size)
14249
14250         echo "source rename dir size: ${testdir1_size}"
14251         echo "target rename dir size: ${testdir2_size}"
14252
14253         eval $cmd || error "$cmd failed"
14254         local crossdir=$($cmd | grep 'crossdir')
14255         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14256         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14257         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14258         [[ $src_sample -eq 1 ]] ||
14259                 error "crossdir_rename_size error $src_sample"
14260         [[ $tgt_sample -eq 1 ]] ||
14261                 error "crossdir_rename_size error $tgt_sample"
14262         echo "Check cross dir rename stats success"
14263         rm -rf $DIR/${tdir}
14264 }
14265 run_test 133d "Verifying rename_stats ========================================"
14266
14267 test_133e() {
14268         remote_mds_nodsh && skip "remote MDS with nodsh"
14269         remote_ost_nodsh && skip "remote OST with nodsh"
14270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14271
14272         local testdir=$DIR/${tdir}/stats_testdir
14273         local ctr f0 f1 bs=32768 count=42 sum
14274
14275         mkdir -p ${testdir} || error "mkdir failed"
14276
14277         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14278
14279         for ctr in {write,read}_bytes; do
14280                 sync
14281                 cancel_lru_locks osc
14282
14283                 do_facet ost1 $LCTL set_param -n \
14284                         "obdfilter.*.exports.clear=clear"
14285
14286                 if [ $ctr = write_bytes ]; then
14287                         f0=/dev/zero
14288                         f1=${testdir}/${tfile}
14289                 else
14290                         f0=${testdir}/${tfile}
14291                         f1=/dev/null
14292                 fi
14293
14294                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14295                         error "dd failed"
14296                 sync
14297                 cancel_lru_locks osc
14298
14299                 sum=$(do_facet ost1 $LCTL get_param \
14300                         "obdfilter.*.exports.*.stats" |
14301                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14302                                 $1 == ctr { sum += $7 }
14303                                 END { printf("%0.0f", sum) }')
14304
14305                 if ((sum != bs * count)); then
14306                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14307                 fi
14308         done
14309
14310         rm -rf $DIR/${tdir}
14311 }
14312 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14313
14314 test_133f() {
14315         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14316                 skip "too old lustre for get_param -R ($facet_ver)"
14317
14318         # verifying readability.
14319         $LCTL get_param -R '*' &> /dev/null
14320
14321         # Verifing writability with badarea_io.
14322         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14323         local skipped_params='force_lbug|changelog_mask|daemon_file'
14324         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14325                 egrep -v "$skipped_params" |
14326                 xargs -n 1 find $proc_dirs -name |
14327                 xargs -n 1 badarea_io ||
14328                 error "client badarea_io failed"
14329
14330         # remount the FS in case writes/reads /proc break the FS
14331         cleanup || error "failed to unmount"
14332         setup || error "failed to setup"
14333 }
14334 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14335
14336 test_133g() {
14337         remote_mds_nodsh && skip "remote MDS with nodsh"
14338         remote_ost_nodsh && skip "remote OST with nodsh"
14339
14340         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14341         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14342         local facet
14343         for facet in mds1 ost1; do
14344                 local facet_ver=$(lustre_version_code $facet)
14345                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14346                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14347                 else
14348                         log "$facet: too old lustre for get_param -R"
14349                 fi
14350                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14351                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14352                                 tr -d = | egrep -v $skipped_params |
14353                                 xargs -n 1 find $proc_dirs -name |
14354                                 xargs -n 1 badarea_io" ||
14355                                         error "$facet badarea_io failed"
14356                 else
14357                         skip_noexit "$facet: too old lustre for get_param -R"
14358                 fi
14359         done
14360
14361         # remount the FS in case writes/reads /proc break the FS
14362         cleanup || error "failed to unmount"
14363         setup || error "failed to setup"
14364 }
14365 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14366
14367 test_133h() {
14368         remote_mds_nodsh && skip "remote MDS with nodsh"
14369         remote_ost_nodsh && skip "remote OST with nodsh"
14370         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14371                 skip "Need MDS version at least 2.9.54"
14372
14373         local facet
14374         for facet in client mds1 ost1; do
14375                 # Get the list of files that are missing the terminating newline
14376                 local plist=$(do_facet $facet
14377                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14378                 local ent
14379                 for ent in $plist; do
14380                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14381                                 awk -v FS='\v' -v RS='\v\v' \
14382                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14383                                         print FILENAME}'" 2>/dev/null)
14384                         [ -z $missing ] || {
14385                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14386                                 error "file does not end with newline: $facet-$ent"
14387                         }
14388                 done
14389         done
14390 }
14391 run_test 133h "Proc files should end with newlines"
14392
14393 test_134a() {
14394         remote_mds_nodsh && skip "remote MDS with nodsh"
14395         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14396                 skip "Need MDS version at least 2.7.54"
14397
14398         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14399         cancel_lru_locks mdc
14400
14401         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14402         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14403         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14404
14405         local nr=1000
14406         createmany -o $DIR/$tdir/f $nr ||
14407                 error "failed to create $nr files in $DIR/$tdir"
14408         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14409
14410         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14411         do_facet mds1 $LCTL set_param fail_loc=0x327
14412         do_facet mds1 $LCTL set_param fail_val=500
14413         touch $DIR/$tdir/m
14414
14415         echo "sleep 10 seconds ..."
14416         sleep 10
14417         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14418
14419         do_facet mds1 $LCTL set_param fail_loc=0
14420         do_facet mds1 $LCTL set_param fail_val=0
14421         [ $lck_cnt -lt $unused ] ||
14422                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14423
14424         rm $DIR/$tdir/m
14425         unlinkmany $DIR/$tdir/f $nr
14426 }
14427 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14428
14429 test_134b() {
14430         remote_mds_nodsh && skip "remote MDS with nodsh"
14431         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14432                 skip "Need MDS version at least 2.7.54"
14433
14434         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14435         cancel_lru_locks mdc
14436
14437         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14438                         ldlm.lock_reclaim_threshold_mb)
14439         # disable reclaim temporarily
14440         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14441
14442         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14443         do_facet mds1 $LCTL set_param fail_loc=0x328
14444         do_facet mds1 $LCTL set_param fail_val=500
14445
14446         $LCTL set_param debug=+trace
14447
14448         local nr=600
14449         createmany -o $DIR/$tdir/f $nr &
14450         local create_pid=$!
14451
14452         echo "Sleep $TIMEOUT seconds ..."
14453         sleep $TIMEOUT
14454         if ! ps -p $create_pid  > /dev/null 2>&1; then
14455                 do_facet mds1 $LCTL set_param fail_loc=0
14456                 do_facet mds1 $LCTL set_param fail_val=0
14457                 do_facet mds1 $LCTL set_param \
14458                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14459                 error "createmany finished incorrectly!"
14460         fi
14461         do_facet mds1 $LCTL set_param fail_loc=0
14462         do_facet mds1 $LCTL set_param fail_val=0
14463         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14464         wait $create_pid || return 1
14465
14466         unlinkmany $DIR/$tdir/f $nr
14467 }
14468 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14469
14470 test_135() {
14471         remote_mds_nodsh && skip "remote MDS with nodsh"
14472         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14473                 skip "Need MDS version at least 2.13.50"
14474         local fname
14475
14476         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14477
14478 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14479         #set only one record at plain llog
14480         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14481
14482         #fill already existed plain llog each 64767
14483         #wrapping whole catalog
14484         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14485
14486         createmany -o $DIR/$tdir/$tfile_ 64700
14487         for (( i = 0; i < 64700; i = i + 2 ))
14488         do
14489                 rm $DIR/$tdir/$tfile_$i &
14490                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14491                 local pid=$!
14492                 wait $pid
14493         done
14494
14495         #waiting osp synchronization
14496         wait_delete_completed
14497 }
14498 run_test 135 "Race catalog processing"
14499
14500 test_136() {
14501         remote_mds_nodsh && skip "remote MDS with nodsh"
14502         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14503                 skip "Need MDS version at least 2.13.50"
14504         local fname
14505
14506         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14507         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14508         #set only one record at plain llog
14509 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14510         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14511
14512         #fill already existed 2 plain llogs each 64767
14513         #wrapping whole catalog
14514         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14515         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14516         wait_delete_completed
14517
14518         createmany -o $DIR/$tdir/$tfile_ 10
14519         sleep 25
14520
14521         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14522         for (( i = 0; i < 10; i = i + 3 ))
14523         do
14524                 rm $DIR/$tdir/$tfile_$i &
14525                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14526                 local pid=$!
14527                 wait $pid
14528                 sleep 7
14529                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14530         done
14531
14532         #waiting osp synchronization
14533         wait_delete_completed
14534 }
14535 run_test 136 "Race catalog processing 2"
14536
14537 test_140() { #bug-17379
14538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14539
14540         test_mkdir $DIR/$tdir
14541         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14542         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14543
14544         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14545         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14546         local i=0
14547         while i=$((i + 1)); do
14548                 test_mkdir $i
14549                 cd $i || error "Changing to $i"
14550                 ln -s ../stat stat || error "Creating stat symlink"
14551                 # Read the symlink until ELOOP present,
14552                 # not LBUGing the system is considered success,
14553                 # we didn't overrun the stack.
14554                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14555                 if [ $ret -ne 0 ]; then
14556                         if [ $ret -eq 40 ]; then
14557                                 break  # -ELOOP
14558                         else
14559                                 error "Open stat symlink"
14560                                         return
14561                         fi
14562                 fi
14563         done
14564         i=$((i - 1))
14565         echo "The symlink depth = $i"
14566         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14567                 error "Invalid symlink depth"
14568
14569         # Test recursive symlink
14570         ln -s symlink_self symlink_self
14571         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14572         echo "open symlink_self returns $ret"
14573         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14574 }
14575 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14576
14577 test_150a() {
14578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14579
14580         local TF="$TMP/$tfile"
14581
14582         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14583         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14584         cp $TF $DIR/$tfile
14585         cancel_lru_locks $OSC
14586         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14587         remount_client $MOUNT
14588         df -P $MOUNT
14589         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14590
14591         $TRUNCATE $TF 6000
14592         $TRUNCATE $DIR/$tfile 6000
14593         cancel_lru_locks $OSC
14594         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14595
14596         echo "12345" >>$TF
14597         echo "12345" >>$DIR/$tfile
14598         cancel_lru_locks $OSC
14599         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14600
14601         echo "12345" >>$TF
14602         echo "12345" >>$DIR/$tfile
14603         cancel_lru_locks $OSC
14604         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14605 }
14606 run_test 150a "truncate/append tests"
14607
14608 test_150b() {
14609         check_set_fallocate_or_skip
14610
14611         touch $DIR/$tfile
14612         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14613         check_fallocate $DIR/$tfile || skip_eopnotsupp "fallocate failed"
14614 }
14615 run_test 150b "Verify fallocate (prealloc) functionality"
14616
14617 test_150bb() {
14618         check_set_fallocate_or_skip
14619
14620         touch $DIR/$tfile
14621         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14622         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14623         > $DIR/$tfile
14624         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14625         # precomputed md5sum for 20MB of zeroes
14626         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14627         local sum=($(md5sum $DIR/$tfile))
14628
14629         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14630
14631         check_set_fallocate 1
14632
14633         > $DIR/$tfile
14634         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14635         sum=($(md5sum $DIR/$tfile))
14636
14637         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14638 }
14639 run_test 150bb "Verify fallocate modes both zero space"
14640
14641 test_150c() {
14642         check_set_fallocate_or_skip
14643         local striping="-c2"
14644
14645         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14646         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14647         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14648         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14649         local want=$((OSTCOUNT * 1048576))
14650
14651         # Must allocate all requested space, not more than 5% extra
14652         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14653                 error "bytes $bytes is not $want"
14654
14655         rm -f $DIR/$tfile
14656
14657         echo "verify fallocate on PFL file"
14658
14659         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14660
14661         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14662                 error "Create $DIR/$tfile failed"
14663         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
14664         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14665         want=$((512 * 1048576))
14666
14667         # Must allocate all requested space, not more than 5% extra
14668         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14669                 error "bytes $bytes is not $want"
14670 }
14671 run_test 150c "Verify fallocate Size and Blocks"
14672
14673 test_150d() {
14674         check_set_fallocate_or_skip
14675         local striping="-c2"
14676
14677         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14678
14679         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14680         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14681                 error "setstripe failed"
14682         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14683         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14684         local want=$((OSTCOUNT * 1048576))
14685
14686         # Must allocate all requested space, not more than 5% extra
14687         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14688                 error "bytes $bytes is not $want"
14689 }
14690 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14691
14692 test_150e() {
14693         check_set_fallocate_or_skip
14694
14695         echo "df before:"
14696         $LFS df
14697         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14698         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14699                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14700
14701         # Find OST with Minimum Size
14702         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14703                        sort -un | head -1)
14704
14705         # Get 100MB per OST of the available space to reduce run time
14706         # else 60% of the available space if we are running SLOW tests
14707         if [ $SLOW == "no" ]; then
14708                 local space=$((1024 * 100 * OSTCOUNT))
14709         else
14710                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14711         fi
14712
14713         fallocate -l${space}k $DIR/$tfile ||
14714                 error "fallocate ${space}k $DIR/$tfile failed"
14715         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14716
14717         # get size immediately after fallocate. This should be correctly
14718         # updated
14719         local size=$(stat -c '%s' $DIR/$tfile)
14720         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14721
14722         # Sleep for a while for statfs to get updated. And not pull from cache.
14723         sleep 2
14724
14725         echo "df after fallocate:"
14726         $LFS df
14727
14728         (( size / 1024 == space )) || error "size $size != requested $space"
14729         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14730                 error "used $used < space $space"
14731
14732         rm $DIR/$tfile || error "rm failed"
14733         sync
14734         wait_delete_completed
14735
14736         echo "df after unlink:"
14737         $LFS df
14738 }
14739 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14740
14741 test_150f() {
14742         local size
14743         local blocks
14744         local want_size_before=20480 # in bytes
14745         local want_blocks_before=40 # 512 sized blocks
14746         local want_blocks_after=24  # 512 sized blocks
14747         local length=$(((want_blocks_before - want_blocks_after) * 512))
14748
14749         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14750                 skip "need at least 2.14.0 for fallocate punch"
14751
14752         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14753                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14754         fi
14755
14756         check_set_fallocate_or_skip
14757         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14758
14759         [[ "x$DOM" == "xyes" ]] &&
14760                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14761
14762         echo "Verify fallocate punch: Range within the file range"
14763         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14764                 error "dd failed for bs 4096 and count 5"
14765
14766         # Call fallocate with punch range which is within the file range
14767         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
14768                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
14769         # client must see changes immediately after fallocate
14770         size=$(stat -c '%s' $DIR/$tfile)
14771         blocks=$(stat -c '%b' $DIR/$tfile)
14772
14773         # Verify punch worked.
14774         (( blocks == want_blocks_after )) ||
14775                 error "punch failed: blocks $blocks != $want_blocks_after"
14776
14777         (( size == want_size_before )) ||
14778                 error "punch failed: size $size != $want_size_before"
14779
14780         # Verify there is hole in file
14781         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14782         # precomputed md5sum
14783         local expect="4a9a834a2db02452929c0a348273b4aa"
14784
14785         cksum=($(md5sum $DIR/$tfile))
14786         [[ "${cksum[0]}" == "$expect" ]] ||
14787                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14788
14789         # Start second sub-case for fallocate punch.
14790         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14791         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14792                 error "dd failed for bs 4096 and count 5"
14793
14794         # Punch range less than block size will have no change in block count
14795         want_blocks_after=40  # 512 sized blocks
14796
14797         # Punch overlaps two blocks and less than blocksize
14798         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
14799                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
14800         size=$(stat -c '%s' $DIR/$tfile)
14801         blocks=$(stat -c '%b' $DIR/$tfile)
14802
14803         # Verify punch worked.
14804         (( blocks == want_blocks_after )) ||
14805                 error "punch failed: blocks $blocks != $want_blocks_after"
14806
14807         (( size == want_size_before )) ||
14808                 error "punch failed: size $size != $want_size_before"
14809
14810         # Verify if range is really zero'ed out. We expect Zeros.
14811         # precomputed md5sum
14812         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14813         cksum=($(md5sum $DIR/$tfile))
14814         [[ "${cksum[0]}" == "$expect" ]] ||
14815                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14816 }
14817 run_test 150f "Verify fallocate punch functionality"
14818
14819 test_150g() {
14820         local space
14821         local size
14822         local blocks
14823         local blocks_after
14824         local size_after
14825         local BS=4096 # Block size in bytes
14826
14827         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14828                 skip "need at least 2.14.0 for fallocate punch"
14829
14830         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14831                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14832         fi
14833
14834         check_set_fallocate_or_skip
14835         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14836
14837         if [[ "x$DOM" == "xyes" ]]; then
14838                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
14839                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
14840         else
14841                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14842                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14843         fi
14844
14845         # Get 100MB per OST of the available space to reduce run time
14846         # else 60% of the available space if we are running SLOW tests
14847         if [ $SLOW == "no" ]; then
14848                 space=$((1024 * 100 * OSTCOUNT))
14849         else
14850                 # Find OST with Minimum Size
14851                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14852                         sort -un | head -1)
14853                 echo "min size OST: $space"
14854                 space=$(((space * 60)/100 * OSTCOUNT))
14855         fi
14856         # space in 1k units, round to 4k blocks
14857         local blkcount=$((space * 1024 / $BS))
14858
14859         echo "Verify fallocate punch: Very large Range"
14860         fallocate -l${space}k $DIR/$tfile ||
14861                 error "fallocate ${space}k $DIR/$tfile failed"
14862         # write 1M at the end, start and in the middle
14863         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14864                 error "dd failed: bs $BS count 256"
14865         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14866                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14867         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14868                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14869
14870         # Gather stats.
14871         size=$(stat -c '%s' $DIR/$tfile)
14872
14873         # gather punch length.
14874         local punch_size=$((size - (BS * 2)))
14875
14876         echo "punch_size = $punch_size"
14877         echo "size - punch_size: $((size - punch_size))"
14878         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14879
14880         # Call fallocate to punch all except 2 blocks. We leave the
14881         # first and the last block
14882         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14883         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
14884                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
14885
14886         size_after=$(stat -c '%s' $DIR/$tfile)
14887         blocks_after=$(stat -c '%b' $DIR/$tfile)
14888
14889         # Verify punch worked.
14890         # Size should be kept
14891         (( size == size_after )) ||
14892                 error "punch failed: size $size != $size_after"
14893
14894         # two 4k data blocks to remain plus possible 1 extra extent block
14895         (( blocks_after <= ((BS / 512) * 3) )) ||
14896                 error "too many blocks remains: $blocks_after"
14897
14898         # Verify that file has hole between the first and the last blocks
14899         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14900         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14901
14902         echo "Hole at [$hole_start, $hole_end)"
14903         (( hole_start == BS )) ||
14904                 error "no hole at offset $BS after punch"
14905
14906         (( hole_end == BS + punch_size )) ||
14907                 error "data at offset $hole_end < $((BS + punch_size))"
14908 }
14909 run_test 150g "Verify fallocate punch on large range"
14910
14911 #LU-2902 roc_hit was not able to read all values from lproc
14912 function roc_hit_init() {
14913         local list=$(comma_list $(osts_nodes))
14914         local dir=$DIR/$tdir-check
14915         local file=$dir/$tfile
14916         local BEFORE
14917         local AFTER
14918         local idx
14919
14920         test_mkdir $dir
14921         #use setstripe to do a write to every ost
14922         for i in $(seq 0 $((OSTCOUNT-1))); do
14923                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14924                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14925                 idx=$(printf %04x $i)
14926                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14927                         awk '$1 == "cache_access" {sum += $7}
14928                                 END { printf("%0.0f", sum) }')
14929
14930                 cancel_lru_locks osc
14931                 cat $file >/dev/null
14932
14933                 AFTER=$(get_osd_param $list *OST*$idx stats |
14934                         awk '$1 == "cache_access" {sum += $7}
14935                                 END { printf("%0.0f", sum) }')
14936
14937                 echo BEFORE:$BEFORE AFTER:$AFTER
14938                 if ! let "AFTER - BEFORE == 4"; then
14939                         rm -rf $dir
14940                         error "roc_hit is not safe to use"
14941                 fi
14942                 rm $file
14943         done
14944
14945         rm -rf $dir
14946 }
14947
14948 function roc_hit() {
14949         local list=$(comma_list $(osts_nodes))
14950         echo $(get_osd_param $list '' stats |
14951                 awk '$1 == "cache_hit" {sum += $7}
14952                         END { printf("%0.0f", sum) }')
14953 }
14954
14955 function set_cache() {
14956         local on=1
14957
14958         if [ "$2" == "off" ]; then
14959                 on=0;
14960         fi
14961         local list=$(comma_list $(osts_nodes))
14962         set_osd_param $list '' $1_cache_enable $on
14963
14964         cancel_lru_locks osc
14965 }
14966
14967 test_151() {
14968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14969         remote_ost_nodsh && skip "remote OST with nodsh"
14970
14971         local CPAGES=3
14972         local list=$(comma_list $(osts_nodes))
14973
14974         # check whether obdfilter is cache capable at all
14975         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14976                 skip "not cache-capable obdfilter"
14977         fi
14978
14979         # check cache is enabled on all obdfilters
14980         if get_osd_param $list '' read_cache_enable | grep 0; then
14981                 skip "oss cache is disabled"
14982         fi
14983
14984         set_osd_param $list '' writethrough_cache_enable 1
14985
14986         # check write cache is enabled on all obdfilters
14987         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14988                 skip "oss write cache is NOT enabled"
14989         fi
14990
14991         roc_hit_init
14992
14993         #define OBD_FAIL_OBD_NO_LRU  0x609
14994         do_nodes $list $LCTL set_param fail_loc=0x609
14995
14996         # pages should be in the case right after write
14997         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14998                 error "dd failed"
14999
15000         local BEFORE=$(roc_hit)
15001         cancel_lru_locks osc
15002         cat $DIR/$tfile >/dev/null
15003         local AFTER=$(roc_hit)
15004
15005         do_nodes $list $LCTL set_param fail_loc=0
15006
15007         if ! let "AFTER - BEFORE == CPAGES"; then
15008                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15009         fi
15010
15011         cancel_lru_locks osc
15012         # invalidates OST cache
15013         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15014         set_osd_param $list '' read_cache_enable 0
15015         cat $DIR/$tfile >/dev/null
15016
15017         # now data shouldn't be found in the cache
15018         BEFORE=$(roc_hit)
15019         cancel_lru_locks osc
15020         cat $DIR/$tfile >/dev/null
15021         AFTER=$(roc_hit)
15022         if let "AFTER - BEFORE != 0"; then
15023                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15024         fi
15025
15026         set_osd_param $list '' read_cache_enable 1
15027         rm -f $DIR/$tfile
15028 }
15029 run_test 151 "test cache on oss and controls ==============================="
15030
15031 test_152() {
15032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15033
15034         local TF="$TMP/$tfile"
15035
15036         # simulate ENOMEM during write
15037 #define OBD_FAIL_OST_NOMEM      0x226
15038         lctl set_param fail_loc=0x80000226
15039         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15040         cp $TF $DIR/$tfile
15041         sync || error "sync failed"
15042         lctl set_param fail_loc=0
15043
15044         # discard client's cache
15045         cancel_lru_locks osc
15046
15047         # simulate ENOMEM during read
15048         lctl set_param fail_loc=0x80000226
15049         cmp $TF $DIR/$tfile || error "cmp failed"
15050         lctl set_param fail_loc=0
15051
15052         rm -f $TF
15053 }
15054 run_test 152 "test read/write with enomem ============================"
15055
15056 test_153() {
15057         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15058 }
15059 run_test 153 "test if fdatasync does not crash ======================="
15060
15061 dot_lustre_fid_permission_check() {
15062         local fid=$1
15063         local ffid=$MOUNT/.lustre/fid/$fid
15064         local test_dir=$2
15065
15066         echo "stat fid $fid"
15067         stat $ffid > /dev/null || error "stat $ffid failed."
15068         echo "touch fid $fid"
15069         touch $ffid || error "touch $ffid failed."
15070         echo "write to fid $fid"
15071         cat /etc/hosts > $ffid || error "write $ffid failed."
15072         echo "read fid $fid"
15073         diff /etc/hosts $ffid || error "read $ffid failed."
15074         echo "append write to fid $fid"
15075         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15076         echo "rename fid $fid"
15077         mv $ffid $test_dir/$tfile.1 &&
15078                 error "rename $ffid to $tfile.1 should fail."
15079         touch $test_dir/$tfile.1
15080         mv $test_dir/$tfile.1 $ffid &&
15081                 error "rename $tfile.1 to $ffid should fail."
15082         rm -f $test_dir/$tfile.1
15083         echo "truncate fid $fid"
15084         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15085         echo "link fid $fid"
15086         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15087         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15088                 echo "setfacl fid $fid"
15089                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
15090                 echo "getfacl fid $fid"
15091                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
15092         fi
15093         echo "unlink fid $fid"
15094         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15095         echo "mknod fid $fid"
15096         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15097
15098         fid=[0xf00000400:0x1:0x0]
15099         ffid=$MOUNT/.lustre/fid/$fid
15100
15101         echo "stat non-exist fid $fid"
15102         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15103         echo "write to non-exist fid $fid"
15104         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15105         echo "link new fid $fid"
15106         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15107
15108         mkdir -p $test_dir/$tdir
15109         touch $test_dir/$tdir/$tfile
15110         fid=$($LFS path2fid $test_dir/$tdir)
15111         rc=$?
15112         [ $rc -ne 0 ] &&
15113                 error "error: could not get fid for $test_dir/$dir/$tfile."
15114
15115         ffid=$MOUNT/.lustre/fid/$fid
15116
15117         echo "ls $fid"
15118         ls $ffid > /dev/null || error "ls $ffid failed."
15119         echo "touch $fid/$tfile.1"
15120         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15121
15122         echo "touch $MOUNT/.lustre/fid/$tfile"
15123         touch $MOUNT/.lustre/fid/$tfile && \
15124                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15125
15126         echo "setxattr to $MOUNT/.lustre/fid"
15127         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15128
15129         echo "listxattr for $MOUNT/.lustre/fid"
15130         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15131
15132         echo "delxattr from $MOUNT/.lustre/fid"
15133         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15134
15135         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15136         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15137                 error "touch invalid fid should fail."
15138
15139         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15140         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15141                 error "touch non-normal fid should fail."
15142
15143         echo "rename $tdir to $MOUNT/.lustre/fid"
15144         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15145                 error "rename to $MOUNT/.lustre/fid should fail."
15146
15147         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15148         then            # LU-3547
15149                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15150                 local new_obf_mode=777
15151
15152                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15153                 chmod $new_obf_mode $DIR/.lustre/fid ||
15154                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15155
15156                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15157                 [ $obf_mode -eq $new_obf_mode ] ||
15158                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15159
15160                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15161                 chmod $old_obf_mode $DIR/.lustre/fid ||
15162                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15163         fi
15164
15165         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15166         fid=$($LFS path2fid $test_dir/$tfile-2)
15167
15168         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15169         then # LU-5424
15170                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15171                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15172                         error "create lov data thru .lustre failed"
15173         fi
15174         echo "cp /etc/passwd $test_dir/$tfile-2"
15175         cp /etc/passwd $test_dir/$tfile-2 ||
15176                 error "copy to $test_dir/$tfile-2 failed."
15177         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15178         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15179                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15180
15181         rm -rf $test_dir/tfile.lnk
15182         rm -rf $test_dir/$tfile-2
15183 }
15184
15185 test_154A() {
15186         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15187                 skip "Need MDS version at least 2.4.1"
15188
15189         local tf=$DIR/$tfile
15190         touch $tf
15191
15192         local fid=$($LFS path2fid $tf)
15193         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15194
15195         # check that we get the same pathname back
15196         local rootpath
15197         local found
15198         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15199                 echo "$rootpath $fid"
15200                 found=$($LFS fid2path $rootpath "$fid")
15201                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15202                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15203         done
15204
15205         # check wrong root path format
15206         rootpath=$MOUNT"_wrong"
15207         found=$($LFS fid2path $rootpath "$fid")
15208         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15209 }
15210 run_test 154A "lfs path2fid and fid2path basic checks"
15211
15212 test_154B() {
15213         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15214                 skip "Need MDS version at least 2.4.1"
15215
15216         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15217         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15218         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15219         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15220
15221         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15222         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15223
15224         # check that we get the same pathname
15225         echo "PFID: $PFID, name: $name"
15226         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15227         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15228         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15229                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15230
15231         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15232 }
15233 run_test 154B "verify the ll_decode_linkea tool"
15234
15235 test_154a() {
15236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15237         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15238         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15239                 skip "Need MDS version at least 2.2.51"
15240         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15241
15242         cp /etc/hosts $DIR/$tfile
15243
15244         fid=$($LFS path2fid $DIR/$tfile)
15245         rc=$?
15246         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15247
15248         dot_lustre_fid_permission_check "$fid" $DIR ||
15249                 error "dot lustre permission check $fid failed"
15250
15251         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15252
15253         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15254
15255         touch $MOUNT/.lustre/file &&
15256                 error "creation is not allowed under .lustre"
15257
15258         mkdir $MOUNT/.lustre/dir &&
15259                 error "mkdir is not allowed under .lustre"
15260
15261         rm -rf $DIR/$tfile
15262 }
15263 run_test 154a "Open-by-FID"
15264
15265 test_154b() {
15266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15267         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15268         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15269         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15270                 skip "Need MDS version at least 2.2.51"
15271
15272         local remote_dir=$DIR/$tdir/remote_dir
15273         local MDTIDX=1
15274         local rc=0
15275
15276         mkdir -p $DIR/$tdir
15277         $LFS mkdir -i $MDTIDX $remote_dir ||
15278                 error "create remote directory failed"
15279
15280         cp /etc/hosts $remote_dir/$tfile
15281
15282         fid=$($LFS path2fid $remote_dir/$tfile)
15283         rc=$?
15284         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15285
15286         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15287                 error "dot lustre permission check $fid failed"
15288         rm -rf $DIR/$tdir
15289 }
15290 run_test 154b "Open-by-FID for remote directory"
15291
15292 test_154c() {
15293         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15294                 skip "Need MDS version at least 2.4.1"
15295
15296         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15297         local FID1=$($LFS path2fid $DIR/$tfile.1)
15298         local FID2=$($LFS path2fid $DIR/$tfile.2)
15299         local FID3=$($LFS path2fid $DIR/$tfile.3)
15300
15301         local N=1
15302         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15303                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15304                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15305                 local want=FID$N
15306                 [ "$FID" = "${!want}" ] ||
15307                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15308                 N=$((N + 1))
15309         done
15310
15311         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15312         do
15313                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15314                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15315                 N=$((N + 1))
15316         done
15317 }
15318 run_test 154c "lfs path2fid and fid2path multiple arguments"
15319
15320 test_154d() {
15321         remote_mds_nodsh && skip "remote MDS with nodsh"
15322         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15323                 skip "Need MDS version at least 2.5.53"
15324
15325         if remote_mds; then
15326                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15327         else
15328                 nid="0@lo"
15329         fi
15330         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15331         local fd
15332         local cmd
15333
15334         rm -f $DIR/$tfile
15335         touch $DIR/$tfile
15336
15337         local fid=$($LFS path2fid $DIR/$tfile)
15338         # Open the file
15339         fd=$(free_fd)
15340         cmd="exec $fd<$DIR/$tfile"
15341         eval $cmd
15342         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15343         echo "$fid_list" | grep "$fid"
15344         rc=$?
15345
15346         cmd="exec $fd>/dev/null"
15347         eval $cmd
15348         if [ $rc -ne 0 ]; then
15349                 error "FID $fid not found in open files list $fid_list"
15350         fi
15351 }
15352 run_test 154d "Verify open file fid"
15353
15354 test_154e()
15355 {
15356         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15357                 skip "Need MDS version at least 2.6.50"
15358
15359         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15360                 error ".lustre returned by readdir"
15361         fi
15362 }
15363 run_test 154e ".lustre is not returned by readdir"
15364
15365 test_154f() {
15366         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15367
15368         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15369         mkdir_on_mdt0 $DIR/$tdir
15370         # test dirs inherit from its stripe
15371         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15372         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15373         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15374         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15375         touch $DIR/f
15376
15377         # get fid of parents
15378         local FID0=$($LFS path2fid $DIR/$tdir)
15379         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15380         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15381         local FID3=$($LFS path2fid $DIR)
15382
15383         # check that path2fid --parents returns expected <parent_fid>/name
15384         # 1) test for a directory (single parent)
15385         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15386         [ "$parent" == "$FID0/foo1" ] ||
15387                 error "expected parent: $FID0/foo1, got: $parent"
15388
15389         # 2) test for a file with nlink > 1 (multiple parents)
15390         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15391         echo "$parent" | grep -F "$FID1/$tfile" ||
15392                 error "$FID1/$tfile not returned in parent list"
15393         echo "$parent" | grep -F "$FID2/link" ||
15394                 error "$FID2/link not returned in parent list"
15395
15396         # 3) get parent by fid
15397         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15398         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15399         echo "$parent" | grep -F "$FID1/$tfile" ||
15400                 error "$FID1/$tfile not returned in parent list (by fid)"
15401         echo "$parent" | grep -F "$FID2/link" ||
15402                 error "$FID2/link not returned in parent list (by fid)"
15403
15404         # 4) test for entry in root directory
15405         parent=$($LFS path2fid --parents $DIR/f)
15406         echo "$parent" | grep -F "$FID3/f" ||
15407                 error "$FID3/f not returned in parent list"
15408
15409         # 5) test it on root directory
15410         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15411                 error "$MOUNT should not have parents"
15412
15413         # enable xattr caching and check that linkea is correctly updated
15414         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15415         save_lustre_params client "llite.*.xattr_cache" > $save
15416         lctl set_param llite.*.xattr_cache 1
15417
15418         # 6.1) linkea update on rename
15419         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15420
15421         # get parents by fid
15422         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15423         # foo1 should no longer be returned in parent list
15424         echo "$parent" | grep -F "$FID1" &&
15425                 error "$FID1 should no longer be in parent list"
15426         # the new path should appear
15427         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15428                 error "$FID2/$tfile.moved is not in parent list"
15429
15430         # 6.2) linkea update on unlink
15431         rm -f $DIR/$tdir/foo2/link
15432         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15433         # foo2/link should no longer be returned in parent list
15434         echo "$parent" | grep -F "$FID2/link" &&
15435                 error "$FID2/link should no longer be in parent list"
15436         true
15437
15438         rm -f $DIR/f
15439         restore_lustre_params < $save
15440         rm -f $save
15441 }
15442 run_test 154f "get parent fids by reading link ea"
15443
15444 test_154g()
15445 {
15446         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15447         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15448            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15449                 skip "Need MDS version at least 2.6.92"
15450
15451         mkdir_on_mdt0 $DIR/$tdir
15452         llapi_fid_test -d $DIR/$tdir
15453 }
15454 run_test 154g "various llapi FID tests"
15455
15456 test_155_small_load() {
15457     local temp=$TMP/$tfile
15458     local file=$DIR/$tfile
15459
15460     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15461         error "dd of=$temp bs=6096 count=1 failed"
15462     cp $temp $file
15463     cancel_lru_locks $OSC
15464     cmp $temp $file || error "$temp $file differ"
15465
15466     $TRUNCATE $temp 6000
15467     $TRUNCATE $file 6000
15468     cmp $temp $file || error "$temp $file differ (truncate1)"
15469
15470     echo "12345" >>$temp
15471     echo "12345" >>$file
15472     cmp $temp $file || error "$temp $file differ (append1)"
15473
15474     echo "12345" >>$temp
15475     echo "12345" >>$file
15476     cmp $temp $file || error "$temp $file differ (append2)"
15477
15478     rm -f $temp $file
15479     true
15480 }
15481
15482 test_155_big_load() {
15483         remote_ost_nodsh && skip "remote OST with nodsh"
15484
15485         local temp=$TMP/$tfile
15486         local file=$DIR/$tfile
15487
15488         free_min_max
15489         local cache_size=$(do_facet ost$((MAXI+1)) \
15490                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15491         local large_file_size=$((cache_size * 2))
15492
15493         echo "OSS cache size: $cache_size KB"
15494         echo "Large file size: $large_file_size KB"
15495
15496         [ $MAXV -le $large_file_size ] &&
15497                 skip_env "max available OST size needs > $large_file_size KB"
15498
15499         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15500
15501         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15502                 error "dd of=$temp bs=$large_file_size count=1k failed"
15503         cp $temp $file
15504         ls -lh $temp $file
15505         cancel_lru_locks osc
15506         cmp $temp $file || error "$temp $file differ"
15507
15508         rm -f $temp $file
15509         true
15510 }
15511
15512 save_writethrough() {
15513         local facets=$(get_facets OST)
15514
15515         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15516 }
15517
15518 test_155a() {
15519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15520
15521         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15522
15523         save_writethrough $p
15524
15525         set_cache read on
15526         set_cache writethrough on
15527         test_155_small_load
15528         restore_lustre_params < $p
15529         rm -f $p
15530 }
15531 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15532
15533 test_155b() {
15534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15535
15536         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15537
15538         save_writethrough $p
15539
15540         set_cache read on
15541         set_cache writethrough off
15542         test_155_small_load
15543         restore_lustre_params < $p
15544         rm -f $p
15545 }
15546 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15547
15548 test_155c() {
15549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15550
15551         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15552
15553         save_writethrough $p
15554
15555         set_cache read off
15556         set_cache writethrough on
15557         test_155_small_load
15558         restore_lustre_params < $p
15559         rm -f $p
15560 }
15561 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15562
15563 test_155d() {
15564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15565
15566         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15567
15568         save_writethrough $p
15569
15570         set_cache read off
15571         set_cache writethrough off
15572         test_155_small_load
15573         restore_lustre_params < $p
15574         rm -f $p
15575 }
15576 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15577
15578 test_155e() {
15579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15580
15581         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15582
15583         save_writethrough $p
15584
15585         set_cache read on
15586         set_cache writethrough on
15587         test_155_big_load
15588         restore_lustre_params < $p
15589         rm -f $p
15590 }
15591 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15592
15593 test_155f() {
15594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15595
15596         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15597
15598         save_writethrough $p
15599
15600         set_cache read on
15601         set_cache writethrough off
15602         test_155_big_load
15603         restore_lustre_params < $p
15604         rm -f $p
15605 }
15606 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15607
15608 test_155g() {
15609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15610
15611         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15612
15613         save_writethrough $p
15614
15615         set_cache read off
15616         set_cache writethrough on
15617         test_155_big_load
15618         restore_lustre_params < $p
15619         rm -f $p
15620 }
15621 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15622
15623 test_155h() {
15624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15625
15626         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15627
15628         save_writethrough $p
15629
15630         set_cache read off
15631         set_cache writethrough off
15632         test_155_big_load
15633         restore_lustre_params < $p
15634         rm -f $p
15635 }
15636 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15637
15638 test_156() {
15639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15640         remote_ost_nodsh && skip "remote OST with nodsh"
15641         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15642                 skip "stats not implemented on old servers"
15643         [ "$ost1_FSTYPE" = "zfs" ] &&
15644                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15645
15646         local CPAGES=3
15647         local BEFORE
15648         local AFTER
15649         local file="$DIR/$tfile"
15650         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15651
15652         save_writethrough $p
15653         roc_hit_init
15654
15655         log "Turn on read and write cache"
15656         set_cache read on
15657         set_cache writethrough on
15658
15659         log "Write data and read it back."
15660         log "Read should be satisfied from the cache."
15661         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15662         BEFORE=$(roc_hit)
15663         cancel_lru_locks osc
15664         cat $file >/dev/null
15665         AFTER=$(roc_hit)
15666         if ! let "AFTER - BEFORE == CPAGES"; then
15667                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15668         else
15669                 log "cache hits: before: $BEFORE, after: $AFTER"
15670         fi
15671
15672         log "Read again; it should be satisfied from the cache."
15673         BEFORE=$AFTER
15674         cancel_lru_locks osc
15675         cat $file >/dev/null
15676         AFTER=$(roc_hit)
15677         if ! let "AFTER - BEFORE == CPAGES"; then
15678                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15679         else
15680                 log "cache hits:: before: $BEFORE, after: $AFTER"
15681         fi
15682
15683         log "Turn off the read cache and turn on the write cache"
15684         set_cache read off
15685         set_cache writethrough on
15686
15687         log "Read again; it should be satisfied from the cache."
15688         BEFORE=$(roc_hit)
15689         cancel_lru_locks osc
15690         cat $file >/dev/null
15691         AFTER=$(roc_hit)
15692         if ! let "AFTER - BEFORE == CPAGES"; then
15693                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15694         else
15695                 log "cache hits:: before: $BEFORE, after: $AFTER"
15696         fi
15697
15698         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15699                 # > 2.12.56 uses pagecache if cached
15700                 log "Read again; it should not be satisfied from the cache."
15701                 BEFORE=$AFTER
15702                 cancel_lru_locks osc
15703                 cat $file >/dev/null
15704                 AFTER=$(roc_hit)
15705                 if ! let "AFTER - BEFORE == 0"; then
15706                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15707                 else
15708                         log "cache hits:: before: $BEFORE, after: $AFTER"
15709                 fi
15710         fi
15711
15712         log "Write data and read it back."
15713         log "Read should be satisfied from the cache."
15714         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15715         BEFORE=$(roc_hit)
15716         cancel_lru_locks osc
15717         cat $file >/dev/null
15718         AFTER=$(roc_hit)
15719         if ! let "AFTER - BEFORE == CPAGES"; then
15720                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15721         else
15722                 log "cache hits:: before: $BEFORE, after: $AFTER"
15723         fi
15724
15725         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15726                 # > 2.12.56 uses pagecache if cached
15727                 log "Read again; it should not be satisfied from the cache."
15728                 BEFORE=$AFTER
15729                 cancel_lru_locks osc
15730                 cat $file >/dev/null
15731                 AFTER=$(roc_hit)
15732                 if ! let "AFTER - BEFORE == 0"; then
15733                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15734                 else
15735                         log "cache hits:: before: $BEFORE, after: $AFTER"
15736                 fi
15737         fi
15738
15739         log "Turn off read and write cache"
15740         set_cache read off
15741         set_cache writethrough off
15742
15743         log "Write data and read it back"
15744         log "It should not be satisfied from the cache."
15745         rm -f $file
15746         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15747         cancel_lru_locks osc
15748         BEFORE=$(roc_hit)
15749         cat $file >/dev/null
15750         AFTER=$(roc_hit)
15751         if ! let "AFTER - BEFORE == 0"; then
15752                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15753         else
15754                 log "cache hits:: before: $BEFORE, after: $AFTER"
15755         fi
15756
15757         log "Turn on the read cache and turn off the write cache"
15758         set_cache read on
15759         set_cache writethrough off
15760
15761         log "Write data and read it back"
15762         log "It should not be satisfied from the cache."
15763         rm -f $file
15764         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15765         BEFORE=$(roc_hit)
15766         cancel_lru_locks osc
15767         cat $file >/dev/null
15768         AFTER=$(roc_hit)
15769         if ! let "AFTER - BEFORE == 0"; then
15770                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15771         else
15772                 log "cache hits:: before: $BEFORE, after: $AFTER"
15773         fi
15774
15775         log "Read again; it should be satisfied from the cache."
15776         BEFORE=$(roc_hit)
15777         cancel_lru_locks osc
15778         cat $file >/dev/null
15779         AFTER=$(roc_hit)
15780         if ! let "AFTER - BEFORE == CPAGES"; then
15781                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15782         else
15783                 log "cache hits:: before: $BEFORE, after: $AFTER"
15784         fi
15785
15786         restore_lustre_params < $p
15787         rm -f $p $file
15788 }
15789 run_test 156 "Verification of tunables"
15790
15791 test_160a() {
15792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15793         remote_mds_nodsh && skip "remote MDS with nodsh"
15794         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15795                 skip "Need MDS version at least 2.2.0"
15796
15797         changelog_register || error "changelog_register failed"
15798         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15799         changelog_users $SINGLEMDS | grep -q $cl_user ||
15800                 error "User $cl_user not found in changelog_users"
15801
15802         mkdir_on_mdt0 $DIR/$tdir
15803
15804         # change something
15805         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15806         changelog_clear 0 || error "changelog_clear failed"
15807         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15808         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15809         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15810         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15811         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15812         rm $DIR/$tdir/pics/desktop.jpg
15813
15814         echo "verifying changelog mask"
15815         changelog_chmask "-MKDIR"
15816         changelog_chmask "-CLOSE"
15817
15818         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15819         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15820
15821         changelog_chmask "+MKDIR"
15822         changelog_chmask "+CLOSE"
15823
15824         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15825         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15826
15827         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15828         CLOSES=$(changelog_dump | grep -c "CLOSE")
15829         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15830         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15831
15832         # verify contents
15833         echo "verifying target fid"
15834         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15835         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15836         [ "$fidc" == "$fidf" ] ||
15837                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15838         echo "verifying parent fid"
15839         # The FID returned from the Changelog may be the directory shard on
15840         # a different MDT, and not the FID returned by path2fid on the parent.
15841         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15842         # since this is what will matter when recreating this file in the tree.
15843         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15844         local pathp=$($LFS fid2path $MOUNT "$fidp")
15845         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15846                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15847
15848         echo "getting records for $cl_user"
15849         changelog_users $SINGLEMDS
15850         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15851         local nclr=3
15852         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15853                 error "changelog_clear failed"
15854         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15855         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15856         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15857                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15858
15859         local min0_rec=$(changelog_users $SINGLEMDS |
15860                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15861         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15862                           awk '{ print $1; exit; }')
15863
15864         changelog_dump | tail -n 5
15865         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15866         [ $first_rec == $((min0_rec + 1)) ] ||
15867                 error "first index should be $min0_rec + 1 not $first_rec"
15868
15869         # LU-3446 changelog index reset on MDT restart
15870         local cur_rec1=$(changelog_users $SINGLEMDS |
15871                          awk '/^current.index:/ { print $NF }')
15872         changelog_clear 0 ||
15873                 error "clear all changelog records for $cl_user failed"
15874         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15875         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15876                 error "Fail to start $SINGLEMDS"
15877         local cur_rec2=$(changelog_users $SINGLEMDS |
15878                          awk '/^current.index:/ { print $NF }')
15879         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15880         [ $cur_rec1 == $cur_rec2 ] ||
15881                 error "current index should be $cur_rec1 not $cur_rec2"
15882
15883         echo "verifying users from this test are deregistered"
15884         changelog_deregister || error "changelog_deregister failed"
15885         changelog_users $SINGLEMDS | grep -q $cl_user &&
15886                 error "User '$cl_user' still in changelog_users"
15887
15888         # lctl get_param -n mdd.*.changelog_users
15889         # current_index: 144
15890         # ID    index (idle seconds)
15891         # cl3   144   (2) mask=<list>
15892         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15893                 # this is the normal case where all users were deregistered
15894                 # make sure no new records are added when no users are present
15895                 local last_rec1=$(changelog_users $SINGLEMDS |
15896                                   awk '/^current.index:/ { print $NF }')
15897                 touch $DIR/$tdir/chloe
15898                 local last_rec2=$(changelog_users $SINGLEMDS |
15899                                   awk '/^current.index:/ { print $NF }')
15900                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15901                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15902         else
15903                 # any changelog users must be leftovers from a previous test
15904                 changelog_users $SINGLEMDS
15905                 echo "other changelog users; can't verify off"
15906         fi
15907 }
15908 run_test 160a "changelog sanity"
15909
15910 test_160b() { # LU-3587
15911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15912         remote_mds_nodsh && skip "remote MDS with nodsh"
15913         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15914                 skip "Need MDS version at least 2.2.0"
15915
15916         changelog_register || error "changelog_register failed"
15917         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15918         changelog_users $SINGLEMDS | grep -q $cl_user ||
15919                 error "User '$cl_user' not found in changelog_users"
15920
15921         local longname1=$(str_repeat a 255)
15922         local longname2=$(str_repeat b 255)
15923
15924         cd $DIR
15925         echo "creating very long named file"
15926         touch $longname1 || error "create of '$longname1' failed"
15927         echo "renaming very long named file"
15928         mv $longname1 $longname2
15929
15930         changelog_dump | grep RENME | tail -n 5
15931         rm -f $longname2
15932 }
15933 run_test 160b "Verify that very long rename doesn't crash in changelog"
15934
15935 test_160c() {
15936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15937         remote_mds_nodsh && skip "remote MDS with nodsh"
15938
15939         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15940                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15941                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15942                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15943
15944         local rc=0
15945
15946         # Registration step
15947         changelog_register || error "changelog_register failed"
15948
15949         rm -rf $DIR/$tdir
15950         mkdir -p $DIR/$tdir
15951         $MCREATE $DIR/$tdir/foo_160c
15952         changelog_chmask "-TRUNC"
15953         $TRUNCATE $DIR/$tdir/foo_160c 200
15954         changelog_chmask "+TRUNC"
15955         $TRUNCATE $DIR/$tdir/foo_160c 199
15956         changelog_dump | tail -n 5
15957         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15958         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15959 }
15960 run_test 160c "verify that changelog log catch the truncate event"
15961
15962 test_160d() {
15963         remote_mds_nodsh && skip "remote MDS with nodsh"
15964         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15966         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15967                 skip "Need MDS version at least 2.7.60"
15968
15969         # Registration step
15970         changelog_register || error "changelog_register failed"
15971
15972         mkdir -p $DIR/$tdir/migrate_dir
15973         changelog_clear 0 || error "changelog_clear failed"
15974
15975         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15976         changelog_dump | tail -n 5
15977         local migrates=$(changelog_dump | grep -c "MIGRT")
15978         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15979 }
15980 run_test 160d "verify that changelog log catch the migrate event"
15981
15982 test_160e() {
15983         remote_mds_nodsh && skip "remote MDS with nodsh"
15984
15985         # Create a user
15986         changelog_register || error "changelog_register failed"
15987
15988         local MDT0=$(facet_svc $SINGLEMDS)
15989         local rc
15990
15991         # No user (expect fail)
15992         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
15993         rc=$?
15994         if [ $rc -eq 0 ]; then
15995                 error "Should fail without user"
15996         elif [ $rc -ne 4 ]; then
15997                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
15998         fi
15999
16000         # Delete a future user (expect fail)
16001         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16002         rc=$?
16003         if [ $rc -eq 0 ]; then
16004                 error "Deleted non-existant user cl77"
16005         elif [ $rc -ne 2 ]; then
16006                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16007         fi
16008
16009         # Clear to a bad index (1 billion should be safe)
16010         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16011         rc=$?
16012
16013         if [ $rc -eq 0 ]; then
16014                 error "Successfully cleared to invalid CL index"
16015         elif [ $rc -ne 22 ]; then
16016                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16017         fi
16018 }
16019 run_test 160e "changelog negative testing (should return errors)"
16020
16021 test_160f() {
16022         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16023         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16024                 skip "Need MDS version at least 2.10.56"
16025
16026         local mdts=$(comma_list $(mdts_nodes))
16027
16028         # Create a user
16029         changelog_register || error "first changelog_register failed"
16030         changelog_register || error "second changelog_register failed"
16031         local cl_users
16032         declare -A cl_user1
16033         declare -A cl_user2
16034         local user_rec1
16035         local user_rec2
16036         local i
16037
16038         # generate some changelog records to accumulate on each MDT
16039         # use all_char because created files should be evenly distributed
16040         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16041                 error "test_mkdir $tdir failed"
16042         log "$(date +%s): creating first files"
16043         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16044                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16045                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16046         done
16047
16048         # check changelogs have been generated
16049         local start=$SECONDS
16050         local idle_time=$((MDSCOUNT * 5 + 5))
16051         local nbcl=$(changelog_dump | wc -l)
16052         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16053
16054         for param in "changelog_max_idle_time=$idle_time" \
16055                      "changelog_gc=1" \
16056                      "changelog_min_gc_interval=2" \
16057                      "changelog_min_free_cat_entries=3"; do
16058                 local MDT0=$(facet_svc $SINGLEMDS)
16059                 local var="${param%=*}"
16060                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16061
16062                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16063                 do_nodes $mdts $LCTL set_param mdd.*.$param
16064         done
16065
16066         # force cl_user2 to be idle (1st part), but also cancel the
16067         # cl_user1 records so that it is not evicted later in the test.
16068         local sleep1=$((idle_time / 2))
16069         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16070         sleep $sleep1
16071
16072         # simulate changelog catalog almost full
16073         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16074         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16075
16076         for i in $(seq $MDSCOUNT); do
16077                 cl_users=(${CL_USERS[mds$i]})
16078                 cl_user1[mds$i]="${cl_users[0]}"
16079                 cl_user2[mds$i]="${cl_users[1]}"
16080
16081                 [ -n "${cl_user1[mds$i]}" ] ||
16082                         error "mds$i: no user registered"
16083                 [ -n "${cl_user2[mds$i]}" ] ||
16084                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16085
16086                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16087                 [ -n "$user_rec1" ] ||
16088                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16089                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16090                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16091                 [ -n "$user_rec2" ] ||
16092                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16093                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16094                      "$user_rec1 + 2 == $user_rec2"
16095                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16096                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16097                               "$user_rec1 + 2, but is $user_rec2"
16098                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16099                 [ -n "$user_rec2" ] ||
16100                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16101                 [ $user_rec1 == $user_rec2 ] ||
16102                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16103                               "$user_rec1, but is $user_rec2"
16104         done
16105
16106         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16107         local sleep2=$((idle_time - (SECONDS - start) + 1))
16108         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16109         sleep $sleep2
16110
16111         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16112         # cl_user1 should be OK because it recently processed records.
16113         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16114         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16115                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16116                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16117         done
16118
16119         # ensure gc thread is done
16120         for i in $(mdts_nodes); do
16121                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16122                         error "$i: GC-thread not done"
16123         done
16124
16125         local first_rec
16126         for (( i = 1; i <= MDSCOUNT; i++ )); do
16127                 # check cl_user1 still registered
16128                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16129                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16130                 # check cl_user2 unregistered
16131                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16132                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16133
16134                 # check changelogs are present and starting at $user_rec1 + 1
16135                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16136                 [ -n "$user_rec1" ] ||
16137                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16138                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16139                             awk '{ print $1; exit; }')
16140
16141                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16142                 [ $((user_rec1 + 1)) == $first_rec ] ||
16143                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16144         done
16145 }
16146 run_test 160f "changelog garbage collect (timestamped users)"
16147
16148 test_160g() {
16149         remote_mds_nodsh && skip "remote MDS with nodsh"
16150         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16151                 skip "Need MDS version at least 2.14.55"
16152
16153         local mdts=$(comma_list $(mdts_nodes))
16154
16155         # Create a user
16156         changelog_register || error "first changelog_register failed"
16157         changelog_register || error "second changelog_register failed"
16158         local cl_users
16159         declare -A cl_user1
16160         declare -A cl_user2
16161         local user_rec1
16162         local user_rec2
16163         local i
16164
16165         # generate some changelog records to accumulate on each MDT
16166         # use all_char because created files should be evenly distributed
16167         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16168                 error "test_mkdir $tdir failed"
16169         for ((i = 0; i < MDSCOUNT; i++)); do
16170                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16171                         error "create $DIR/$tdir/d$i.1 failed"
16172         done
16173
16174         # check changelogs have been generated
16175         local nbcl=$(changelog_dump | wc -l)
16176         (( $nbcl > 0 )) || error "no changelogs found"
16177
16178         # reduce the max_idle_indexes value to make sure we exceed it
16179         for param in "changelog_max_idle_indexes=2" \
16180                      "changelog_gc=1" \
16181                      "changelog_min_gc_interval=2"; do
16182                 local MDT0=$(facet_svc $SINGLEMDS)
16183                 local var="${param%=*}"
16184                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16185
16186                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16187                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16188                         error "unable to set mdd.*.$param"
16189         done
16190
16191         local start=$SECONDS
16192         for i in $(seq $MDSCOUNT); do
16193                 cl_users=(${CL_USERS[mds$i]})
16194                 cl_user1[mds$i]="${cl_users[0]}"
16195                 cl_user2[mds$i]="${cl_users[1]}"
16196
16197                 [ -n "${cl_user1[mds$i]}" ] ||
16198                         error "mds$i: user1 is not registered"
16199                 [ -n "${cl_user2[mds$i]}" ] ||
16200                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16201
16202                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16203                 [ -n "$user_rec1" ] ||
16204                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16205                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16206                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16207                 [ -n "$user_rec2" ] ||
16208                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16209                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16210                      "$user_rec1 + 2 == $user_rec2"
16211                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16212                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16213                               "expected $user_rec1 + 2, but is $user_rec2"
16214                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16215                 [ -n "$user_rec2" ] ||
16216                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16217                 [ $user_rec1 == $user_rec2 ] ||
16218                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16219                               "expected $user_rec1, but is $user_rec2"
16220         done
16221
16222         # ensure we are past the previous changelog_min_gc_interval set above
16223         local sleep2=$((start + 2 - SECONDS))
16224         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16225         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16226         # cl_user1 should be OK because it recently processed records.
16227         for ((i = 0; i < MDSCOUNT; i++)); do
16228                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16229                         error "create $DIR/$tdir/d$i.3 failed"
16230         done
16231
16232         # ensure gc thread is done
16233         for i in $(mdts_nodes); do
16234                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16235                         error "$i: GC-thread not done"
16236         done
16237
16238         local first_rec
16239         for (( i = 1; i <= MDSCOUNT; i++ )); do
16240                 # check cl_user1 still registered
16241                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16242                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16243                 # check cl_user2 unregistered
16244                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16245                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16246
16247                 # check changelogs are present and starting at $user_rec1 + 1
16248                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16249                 [ -n "$user_rec1" ] ||
16250                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16251                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16252                             awk '{ print $1; exit; }')
16253
16254                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16255                 [ $((user_rec1 + 1)) == $first_rec ] ||
16256                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16257         done
16258 }
16259 run_test 160g "changelog garbage collect on idle records"
16260
16261 test_160h() {
16262         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16263         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16264                 skip "Need MDS version at least 2.10.56"
16265
16266         local mdts=$(comma_list $(mdts_nodes))
16267
16268         # Create a user
16269         changelog_register || error "first changelog_register failed"
16270         changelog_register || error "second changelog_register failed"
16271         local cl_users
16272         declare -A cl_user1
16273         declare -A cl_user2
16274         local user_rec1
16275         local user_rec2
16276         local i
16277
16278         # generate some changelog records to accumulate on each MDT
16279         # use all_char because created files should be evenly distributed
16280         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16281                 error "test_mkdir $tdir failed"
16282         for ((i = 0; i < MDSCOUNT; i++)); do
16283                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16284                         error "create $DIR/$tdir/d$i.1 failed"
16285         done
16286
16287         # check changelogs have been generated
16288         local nbcl=$(changelog_dump | wc -l)
16289         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16290
16291         for param in "changelog_max_idle_time=10" \
16292                      "changelog_gc=1" \
16293                      "changelog_min_gc_interval=2"; do
16294                 local MDT0=$(facet_svc $SINGLEMDS)
16295                 local var="${param%=*}"
16296                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16297
16298                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16299                 do_nodes $mdts $LCTL set_param mdd.*.$param
16300         done
16301
16302         # force cl_user2 to be idle (1st part)
16303         sleep 9
16304
16305         for i in $(seq $MDSCOUNT); do
16306                 cl_users=(${CL_USERS[mds$i]})
16307                 cl_user1[mds$i]="${cl_users[0]}"
16308                 cl_user2[mds$i]="${cl_users[1]}"
16309
16310                 [ -n "${cl_user1[mds$i]}" ] ||
16311                         error "mds$i: no user registered"
16312                 [ -n "${cl_user2[mds$i]}" ] ||
16313                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16314
16315                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16316                 [ -n "$user_rec1" ] ||
16317                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16318                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16319                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16320                 [ -n "$user_rec2" ] ||
16321                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16322                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16323                      "$user_rec1 + 2 == $user_rec2"
16324                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16325                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16326                               "$user_rec1 + 2, but is $user_rec2"
16327                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16328                 [ -n "$user_rec2" ] ||
16329                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16330                 [ $user_rec1 == $user_rec2 ] ||
16331                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16332                               "$user_rec1, but is $user_rec2"
16333         done
16334
16335         # force cl_user2 to be idle (2nd part) and to reach
16336         # changelog_max_idle_time
16337         sleep 2
16338
16339         # force each GC-thread start and block then
16340         # one per MDT/MDD, set fail_val accordingly
16341         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16342         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16343
16344         # generate more changelogs to trigger fail_loc
16345         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16346                 error "create $DIR/$tdir/${tfile}bis failed"
16347
16348         # stop MDT to stop GC-thread, should be done in back-ground as it will
16349         # block waiting for the thread to be released and exit
16350         declare -A stop_pids
16351         for i in $(seq $MDSCOUNT); do
16352                 stop mds$i &
16353                 stop_pids[mds$i]=$!
16354         done
16355
16356         for i in $(mdts_nodes); do
16357                 local facet
16358                 local nb=0
16359                 local facets=$(facets_up_on_host $i)
16360
16361                 for facet in ${facets//,/ }; do
16362                         if [[ $facet == mds* ]]; then
16363                                 nb=$((nb + 1))
16364                         fi
16365                 done
16366                 # ensure each MDS's gc threads are still present and all in "R"
16367                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16368                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16369                         error "$i: expected $nb GC-thread"
16370                 wait_update $i \
16371                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16372                         "R" 20 ||
16373                         error "$i: GC-thread not found in R-state"
16374                 # check umounts of each MDT on MDS have reached kthread_stop()
16375                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16376                         error "$i: expected $nb umount"
16377                 wait_update $i \
16378                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16379                         error "$i: umount not found in D-state"
16380         done
16381
16382         # release all GC-threads
16383         do_nodes $mdts $LCTL set_param fail_loc=0
16384
16385         # wait for MDT stop to complete
16386         for i in $(seq $MDSCOUNT); do
16387                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16388         done
16389
16390         # XXX
16391         # may try to check if any orphan changelog records are present
16392         # via ldiskfs/zfs and llog_reader...
16393
16394         # re-start/mount MDTs
16395         for i in $(seq $MDSCOUNT); do
16396                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16397                         error "Fail to start mds$i"
16398         done
16399
16400         local first_rec
16401         for i in $(seq $MDSCOUNT); do
16402                 # check cl_user1 still registered
16403                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16404                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16405                 # check cl_user2 unregistered
16406                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16407                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16408
16409                 # check changelogs are present and starting at $user_rec1 + 1
16410                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16411                 [ -n "$user_rec1" ] ||
16412                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16413                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16414                             awk '{ print $1; exit; }')
16415
16416                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16417                 [ $((user_rec1 + 1)) == $first_rec ] ||
16418                         error "mds$i: first index should be $user_rec1 + 1, " \
16419                               "but is $first_rec"
16420         done
16421 }
16422 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16423               "during mount"
16424
16425 test_160i() {
16426
16427         local mdts=$(comma_list $(mdts_nodes))
16428
16429         changelog_register || error "first changelog_register failed"
16430
16431         # generate some changelog records to accumulate on each MDT
16432         # use all_char because created files should be evenly distributed
16433         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16434                 error "test_mkdir $tdir failed"
16435         for ((i = 0; i < MDSCOUNT; i++)); do
16436                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16437                         error "create $DIR/$tdir/d$i.1 failed"
16438         done
16439
16440         # check changelogs have been generated
16441         local nbcl=$(changelog_dump | wc -l)
16442         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16443
16444         # simulate race between register and unregister
16445         # XXX as fail_loc is set per-MDS, with DNE configs the race
16446         # simulation will only occur for one MDT per MDS and for the
16447         # others the normal race scenario will take place
16448         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16449         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16450         do_nodes $mdts $LCTL set_param fail_val=1
16451
16452         # unregister 1st user
16453         changelog_deregister &
16454         local pid1=$!
16455         # wait some time for deregister work to reach race rdv
16456         sleep 2
16457         # register 2nd user
16458         changelog_register || error "2nd user register failed"
16459
16460         wait $pid1 || error "1st user deregister failed"
16461
16462         local i
16463         local last_rec
16464         declare -A LAST_REC
16465         for i in $(seq $MDSCOUNT); do
16466                 if changelog_users mds$i | grep "^cl"; then
16467                         # make sure new records are added with one user present
16468                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16469                                           awk '/^current.index:/ { print $NF }')
16470                 else
16471                         error "mds$i has no user registered"
16472                 fi
16473         done
16474
16475         # generate more changelog records to accumulate on each MDT
16476         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16477                 error "create $DIR/$tdir/${tfile}bis failed"
16478
16479         for i in $(seq $MDSCOUNT); do
16480                 last_rec=$(changelog_users $SINGLEMDS |
16481                            awk '/^current.index:/ { print $NF }')
16482                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16483                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16484                         error "changelogs are off on mds$i"
16485         done
16486 }
16487 run_test 160i "changelog user register/unregister race"
16488
16489 test_160j() {
16490         remote_mds_nodsh && skip "remote MDS with nodsh"
16491         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16492                 skip "Need MDS version at least 2.12.56"
16493
16494         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16495         stack_trap "umount $MOUNT2" EXIT
16496
16497         changelog_register || error "first changelog_register failed"
16498         stack_trap "changelog_deregister" EXIT
16499
16500         # generate some changelog
16501         # use all_char because created files should be evenly distributed
16502         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16503                 error "mkdir $tdir failed"
16504         for ((i = 0; i < MDSCOUNT; i++)); do
16505                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16506                         error "create $DIR/$tdir/d$i.1 failed"
16507         done
16508
16509         # open the changelog device
16510         exec 3>/dev/changelog-$FSNAME-MDT0000
16511         stack_trap "exec 3>&-" EXIT
16512         exec 4</dev/changelog-$FSNAME-MDT0000
16513         stack_trap "exec 4<&-" EXIT
16514
16515         # umount the first lustre mount
16516         umount $MOUNT
16517         stack_trap "mount_client $MOUNT" EXIT
16518
16519         # read changelog, which may or may not fail, but should not crash
16520         cat <&4 >/dev/null
16521
16522         # clear changelog
16523         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16524         changelog_users $SINGLEMDS | grep -q $cl_user ||
16525                 error "User $cl_user not found in changelog_users"
16526
16527         printf 'clear:'$cl_user':0' >&3
16528 }
16529 run_test 160j "client can be umounted while its chanangelog is being used"
16530
16531 test_160k() {
16532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16533         remote_mds_nodsh && skip "remote MDS with nodsh"
16534
16535         mkdir -p $DIR/$tdir/1/1
16536
16537         changelog_register || error "changelog_register failed"
16538         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16539
16540         changelog_users $SINGLEMDS | grep -q $cl_user ||
16541                 error "User '$cl_user' not found in changelog_users"
16542 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16543         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16544         rmdir $DIR/$tdir/1/1 & sleep 1
16545         mkdir $DIR/$tdir/2
16546         touch $DIR/$tdir/2/2
16547         rm -rf $DIR/$tdir/2
16548
16549         wait
16550         sleep 4
16551
16552         changelog_dump | grep rmdir || error "rmdir not recorded"
16553 }
16554 run_test 160k "Verify that changelog records are not lost"
16555
16556 # Verifies that a file passed as a parameter has recently had an operation
16557 # performed on it that has generated an MTIME changelog which contains the
16558 # correct parent FID. As files might reside on a different MDT from the
16559 # parent directory in DNE configurations, the FIDs are translated to paths
16560 # before being compared, which should be identical
16561 compare_mtime_changelog() {
16562         local file="${1}"
16563         local mdtidx
16564         local mtime
16565         local cl_fid
16566         local pdir
16567         local dir
16568
16569         mdtidx=$($LFS getstripe --mdt-index $file)
16570         mdtidx=$(printf "%04x" $mdtidx)
16571
16572         # Obtain the parent FID from the MTIME changelog
16573         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16574         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16575
16576         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16577         [ -z "$cl_fid" ] && error "parent FID not present"
16578
16579         # Verify that the path for the parent FID is the same as the path for
16580         # the test directory
16581         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16582
16583         dir=$(dirname $1)
16584
16585         [[ "${pdir%/}" == "$dir" ]] ||
16586                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16587 }
16588
16589 test_160l() {
16590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16591
16592         remote_mds_nodsh && skip "remote MDS with nodsh"
16593         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16594                 skip "Need MDS version at least 2.13.55"
16595
16596         local cl_user
16597
16598         changelog_register || error "changelog_register failed"
16599         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16600
16601         changelog_users $SINGLEMDS | grep -q $cl_user ||
16602                 error "User '$cl_user' not found in changelog_users"
16603
16604         # Clear some types so that MTIME changelogs are generated
16605         changelog_chmask "-CREAT"
16606         changelog_chmask "-CLOSE"
16607
16608         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16609
16610         # Test CL_MTIME during setattr
16611         touch $DIR/$tdir/$tfile
16612         compare_mtime_changelog $DIR/$tdir/$tfile
16613
16614         # Test CL_MTIME during close
16615         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16616         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16617 }
16618 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16619
16620 test_160m() {
16621         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16622         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16623                 skip "Need MDS version at least 2.14.51"
16624         local cl_users
16625         local cl_user1
16626         local cl_user2
16627         local pid1
16628
16629         # Create a user
16630         changelog_register || error "first changelog_register failed"
16631         changelog_register || error "second changelog_register failed"
16632
16633         cl_users=(${CL_USERS[mds1]})
16634         cl_user1="${cl_users[0]}"
16635         cl_user2="${cl_users[1]}"
16636         # generate some changelog records to accumulate on MDT0
16637         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16638         createmany -m $DIR/$tdir/$tfile 50 ||
16639                 error "create $DIR/$tdir/$tfile failed"
16640         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16641         rm -f $DIR/$tdir
16642
16643         # check changelogs have been generated
16644         local nbcl=$(changelog_dump | wc -l)
16645         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16646
16647 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16648         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16649
16650         __changelog_clear mds1 $cl_user1 +10
16651         __changelog_clear mds1 $cl_user2 0 &
16652         pid1=$!
16653         sleep 2
16654         __changelog_clear mds1 $cl_user1 0 ||
16655                 error "fail to cancel record for $cl_user1"
16656         wait $pid1
16657         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16658 }
16659 run_test 160m "Changelog clear race"
16660
16661 test_160n() {
16662         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16663         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16664                 skip "Need MDS version at least 2.14.51"
16665         local cl_users
16666         local cl_user1
16667         local cl_user2
16668         local pid1
16669         local first_rec
16670         local last_rec=0
16671
16672         # Create a user
16673         changelog_register || error "first changelog_register failed"
16674
16675         cl_users=(${CL_USERS[mds1]})
16676         cl_user1="${cl_users[0]}"
16677
16678         # generate some changelog records to accumulate on MDT0
16679         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16680         first_rec=$(changelog_users $SINGLEMDS |
16681                         awk '/^current.index:/ { print $NF }')
16682         while (( last_rec < (( first_rec + 65000)) )); do
16683                 createmany -m $DIR/$tdir/$tfile 10000 ||
16684                         error "create $DIR/$tdir/$tfile failed"
16685
16686                 for i in $(seq 0 10000); do
16687                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16688                                 > /dev/null
16689                 done
16690
16691                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16692                         error "unlinkmany failed unlink"
16693                 last_rec=$(changelog_users $SINGLEMDS |
16694                         awk '/^current.index:/ { print $NF }')
16695                 echo last record $last_rec
16696                 (( last_rec == 0 )) && error "no changelog found"
16697         done
16698
16699 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16700         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16701
16702         __changelog_clear mds1 $cl_user1 0 &
16703         pid1=$!
16704         sleep 2
16705         __changelog_clear mds1 $cl_user1 0 ||
16706                 error "fail to cancel record for $cl_user1"
16707         wait $pid1
16708         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16709 }
16710 run_test 160n "Changelog destroy race"
16711
16712 test_160o() {
16713         local mdt="$(facet_svc $SINGLEMDS)"
16714
16715         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16716         remote_mds_nodsh && skip "remote MDS with nodsh"
16717         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16718                 skip "Need MDS version at least 2.14.52"
16719
16720         changelog_register --user test_160o -m unlnk+close+open ||
16721                 error "changelog_register failed"
16722
16723         do_facet $SINGLEMDS $LCTL --device $mdt \
16724                                 changelog_register -u "Tt3_-#" &&
16725                 error "bad symbols in name should fail"
16726
16727         do_facet $SINGLEMDS $LCTL --device $mdt \
16728                                 changelog_register -u test_160o &&
16729                 error "the same name registration should fail"
16730
16731         do_facet $SINGLEMDS $LCTL --device $mdt \
16732                         changelog_register -u test_160toolongname &&
16733                 error "too long name registration should fail"
16734
16735         changelog_chmask "MARK+HSM"
16736         lctl get_param mdd.*.changelog*mask
16737         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16738         changelog_users $SINGLEMDS | grep -q $cl_user ||
16739                 error "User $cl_user not found in changelog_users"
16740         #verify username
16741         echo $cl_user | grep -q test_160o ||
16742                 error "User $cl_user has no specific name 'test160o'"
16743
16744         # change something
16745         changelog_clear 0 || error "changelog_clear failed"
16746         # generate some changelog records to accumulate on MDT0
16747         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16748         touch $DIR/$tdir/$tfile                 # open 1
16749
16750         OPENS=$(changelog_dump | grep -c "OPEN")
16751         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16752
16753         # must be no MKDIR it wasn't set as user mask
16754         MKDIR=$(changelog_dump | grep -c "MKDIR")
16755         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16756
16757         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16758                                 mdd.$mdt.changelog_current_mask -n)
16759         # register maskless user
16760         changelog_register || error "changelog_register failed"
16761         # effective mask should be not changed because it is not minimal
16762         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16763                                 mdd.$mdt.changelog_current_mask -n)
16764         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16765         # set server mask to minimal value
16766         changelog_chmask "MARK"
16767         # check effective mask again, should be treated as DEFMASK now
16768         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16769                                 mdd.$mdt.changelog_current_mask -n)
16770         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16771
16772         do_facet $SINGLEMDS $LCTL --device $mdt \
16773                                 changelog_deregister -u test_160o ||
16774                 error "cannot deregister by name"
16775 }
16776 run_test 160o "changelog user name and mask"
16777
16778 test_160p() {
16779         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16780         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16781                 skip "Need MDS version at least 2.14.51"
16782         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16783         local cl_users
16784         local cl_user1
16785         local entry_count
16786
16787         # Create a user
16788         changelog_register || error "first changelog_register failed"
16789
16790         cl_users=(${CL_USERS[mds1]})
16791         cl_user1="${cl_users[0]}"
16792
16793         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16794         createmany -m $DIR/$tdir/$tfile 50 ||
16795                 error "create $DIR/$tdir/$tfile failed"
16796         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16797         rm -rf $DIR/$tdir
16798
16799         # check changelogs have been generated
16800         entry_count=$(changelog_dump | wc -l)
16801         ((entry_count != 0)) || error "no changelog entries found"
16802
16803         # remove changelog_users and check that orphan entries are removed
16804         stop mds1
16805         local dev=$(mdsdevname 1)
16806         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
16807         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
16808         entry_count=$(changelog_dump | wc -l)
16809         ((entry_count == 0)) ||
16810                 error "found $entry_count changelog entries, expected none"
16811 }
16812 run_test 160p "Changelog orphan cleanup with no users"
16813
16814 test_160q() {
16815         local mdt="$(facet_svc $SINGLEMDS)"
16816         local clu
16817
16818         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16819         remote_mds_nodsh && skip "remote MDS with nodsh"
16820         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16821                 skip "Need MDS version at least 2.14.54"
16822
16823         # set server mask to minimal value like server init does
16824         changelog_chmask "MARK"
16825         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16826                 error "changelog_register failed"
16827         # check effective mask again, should be treated as DEFMASK now
16828         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16829                                 mdd.$mdt.changelog_current_mask -n)
16830         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
16831                 error "changelog_deregister failed"
16832         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16833 }
16834 run_test 160q "changelog effective mask is DEFMASK if not set"
16835
16836 test_160s() {
16837         remote_mds_nodsh && skip "remote MDS with nodsh"
16838         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
16839                 skip "Need MDS version at least 2.14.55"
16840
16841         local mdts=$(comma_list $(mdts_nodes))
16842
16843         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
16844         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
16845                                        fail_val=$((24 * 3600 * 10))
16846
16847         # Create a user which is 10 days old
16848         changelog_register || error "first changelog_register failed"
16849         local cl_users
16850         declare -A cl_user1
16851         local i
16852
16853         # generate some changelog records to accumulate on each MDT
16854         # use all_char because created files should be evenly distributed
16855         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16856                 error "test_mkdir $tdir failed"
16857         for ((i = 0; i < MDSCOUNT; i++)); do
16858                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16859                         error "create $DIR/$tdir/d$i.1 failed"
16860         done
16861
16862         # check changelogs have been generated
16863         local nbcl=$(changelog_dump | wc -l)
16864         (( nbcl > 0 )) || error "no changelogs found"
16865
16866         # reduce the max_idle_indexes value to make sure we exceed it
16867         for param in "changelog_max_idle_indexes=2097446912" \
16868                      "changelog_max_idle_time=2592000" \
16869                      "changelog_gc=1" \
16870                      "changelog_min_gc_interval=2"; do
16871                 local MDT0=$(facet_svc $SINGLEMDS)
16872                 local var="${param%=*}"
16873                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16874
16875                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16876                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16877                         error "unable to set mdd.*.$param"
16878         done
16879
16880         local start=$SECONDS
16881         for i in $(seq $MDSCOUNT); do
16882                 cl_users=(${CL_USERS[mds$i]})
16883                 cl_user1[mds$i]="${cl_users[0]}"
16884
16885                 [[ -n "${cl_user1[mds$i]}" ]] ||
16886                         error "mds$i: no user registered"
16887         done
16888
16889         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
16890         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
16891
16892         # ensure we are past the previous changelog_min_gc_interval set above
16893         local sleep2=$((start + 2 - SECONDS))
16894         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16895
16896         # Generate one more changelog to trigger GC
16897         for ((i = 0; i < MDSCOUNT; i++)); do
16898                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
16899                         error "create $DIR/$tdir/d$i.3 failed"
16900         done
16901
16902         # ensure gc thread is done
16903         for node in $(mdts_nodes); do
16904                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
16905                         error "$node: GC-thread not done"
16906         done
16907
16908         do_nodes $mdts $LCTL set_param fail_loc=0
16909
16910         for (( i = 1; i <= MDSCOUNT; i++ )); do
16911                 # check cl_user1 is purged
16912                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
16913                         error "mds$i: User ${cl_user1[mds$i]} is registered"
16914         done
16915         return 0
16916 }
16917 run_test 160s "changelog garbage collect on idle records * time"
16918
16919 test_161a() {
16920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16921
16922         test_mkdir -c1 $DIR/$tdir
16923         cp /etc/hosts $DIR/$tdir/$tfile
16924         test_mkdir -c1 $DIR/$tdir/foo1
16925         test_mkdir -c1 $DIR/$tdir/foo2
16926         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16927         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16928         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16929         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16930         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16931         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16932                 $LFS fid2path $DIR $FID
16933                 error "bad link ea"
16934         fi
16935         # middle
16936         rm $DIR/$tdir/foo2/zachary
16937         # last
16938         rm $DIR/$tdir/foo2/thor
16939         # first
16940         rm $DIR/$tdir/$tfile
16941         # rename
16942         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16943         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16944                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16945         rm $DIR/$tdir/foo2/maggie
16946
16947         # overflow the EA
16948         local longname=$tfile.avg_len_is_thirty_two_
16949         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16950                 error_noexit 'failed to unlink many hardlinks'" EXIT
16951         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16952                 error "failed to hardlink many files"
16953         links=$($LFS fid2path $DIR $FID | wc -l)
16954         echo -n "${links}/1000 links in link EA"
16955         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16956 }
16957 run_test 161a "link ea sanity"
16958
16959 test_161b() {
16960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16961         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16962
16963         local MDTIDX=1
16964         local remote_dir=$DIR/$tdir/remote_dir
16965
16966         mkdir -p $DIR/$tdir
16967         $LFS mkdir -i $MDTIDX $remote_dir ||
16968                 error "create remote directory failed"
16969
16970         cp /etc/hosts $remote_dir/$tfile
16971         mkdir -p $remote_dir/foo1
16972         mkdir -p $remote_dir/foo2
16973         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16974         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16975         ln $remote_dir/$tfile $remote_dir/foo1/luna
16976         ln $remote_dir/$tfile $remote_dir/foo2/thor
16977
16978         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16979                      tr -d ']')
16980         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16981                 $LFS fid2path $DIR $FID
16982                 error "bad link ea"
16983         fi
16984         # middle
16985         rm $remote_dir/foo2/zachary
16986         # last
16987         rm $remote_dir/foo2/thor
16988         # first
16989         rm $remote_dir/$tfile
16990         # rename
16991         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16992         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16993         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16994                 $LFS fid2path $DIR $FID
16995                 error "bad link rename"
16996         fi
16997         rm $remote_dir/foo2/maggie
16998
16999         # overflow the EA
17000         local longname=filename_avg_len_is_thirty_two_
17001         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17002                 error "failed to hardlink many files"
17003         links=$($LFS fid2path $DIR $FID | wc -l)
17004         echo -n "${links}/1000 links in link EA"
17005         [[ ${links} -gt 60 ]] ||
17006                 error "expected at least 60 links in link EA"
17007         unlinkmany $remote_dir/foo2/$longname 1000 ||
17008         error "failed to unlink many hardlinks"
17009 }
17010 run_test 161b "link ea sanity under remote directory"
17011
17012 test_161c() {
17013         remote_mds_nodsh && skip "remote MDS with nodsh"
17014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17015         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17016                 skip "Need MDS version at least 2.1.5"
17017
17018         # define CLF_RENAME_LAST 0x0001
17019         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17020         changelog_register || error "changelog_register failed"
17021
17022         rm -rf $DIR/$tdir
17023         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17024         touch $DIR/$tdir/foo_161c
17025         touch $DIR/$tdir/bar_161c
17026         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17027         changelog_dump | grep RENME | tail -n 5
17028         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17029         changelog_clear 0 || error "changelog_clear failed"
17030         if [ x$flags != "x0x1" ]; then
17031                 error "flag $flags is not 0x1"
17032         fi
17033
17034         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17035         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17036         touch $DIR/$tdir/foo_161c
17037         touch $DIR/$tdir/bar_161c
17038         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17039         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17040         changelog_dump | grep RENME | tail -n 5
17041         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17042         changelog_clear 0 || error "changelog_clear failed"
17043         if [ x$flags != "x0x0" ]; then
17044                 error "flag $flags is not 0x0"
17045         fi
17046         echo "rename overwrite a target having nlink > 1," \
17047                 "changelog record has flags of $flags"
17048
17049         # rename doesn't overwrite a target (changelog flag 0x0)
17050         touch $DIR/$tdir/foo_161c
17051         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17052         changelog_dump | grep RENME | tail -n 5
17053         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17054         changelog_clear 0 || error "changelog_clear failed"
17055         if [ x$flags != "x0x0" ]; then
17056                 error "flag $flags is not 0x0"
17057         fi
17058         echo "rename doesn't overwrite a target," \
17059                 "changelog record has flags of $flags"
17060
17061         # define CLF_UNLINK_LAST 0x0001
17062         # unlink a file having nlink = 1 (changelog flag 0x1)
17063         rm -f $DIR/$tdir/foo2_161c
17064         changelog_dump | grep UNLNK | tail -n 5
17065         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17066         changelog_clear 0 || error "changelog_clear failed"
17067         if [ x$flags != "x0x1" ]; then
17068                 error "flag $flags is not 0x1"
17069         fi
17070         echo "unlink a file having nlink = 1," \
17071                 "changelog record has flags of $flags"
17072
17073         # unlink a file having nlink > 1 (changelog flag 0x0)
17074         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17075         rm -f $DIR/$tdir/foobar_161c
17076         changelog_dump | grep UNLNK | tail -n 5
17077         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17078         changelog_clear 0 || error "changelog_clear failed"
17079         if [ x$flags != "x0x0" ]; then
17080                 error "flag $flags is not 0x0"
17081         fi
17082         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17083 }
17084 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17085
17086 test_161d() {
17087         remote_mds_nodsh && skip "remote MDS with nodsh"
17088         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17089
17090         local pid
17091         local fid
17092
17093         changelog_register || error "changelog_register failed"
17094
17095         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17096         # interfer with $MOUNT/.lustre/fid/ access
17097         mkdir $DIR/$tdir
17098         [[ $? -eq 0 ]] || error "mkdir failed"
17099
17100         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17101         $LCTL set_param fail_loc=0x8000140c
17102         # 5s pause
17103         $LCTL set_param fail_val=5
17104
17105         # create file
17106         echo foofoo > $DIR/$tdir/$tfile &
17107         pid=$!
17108
17109         # wait for create to be delayed
17110         sleep 2
17111
17112         ps -p $pid
17113         [[ $? -eq 0 ]] || error "create should be blocked"
17114
17115         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17116         stack_trap "rm -f $tempfile"
17117         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17118         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17119         # some delay may occur during ChangeLog publishing and file read just
17120         # above, that could allow file write to happen finally
17121         [[ -s $tempfile ]] && echo "file should be empty"
17122
17123         $LCTL set_param fail_loc=0
17124
17125         wait $pid
17126         [[ $? -eq 0 ]] || error "create failed"
17127 }
17128 run_test 161d "create with concurrent .lustre/fid access"
17129
17130 check_path() {
17131         local expected="$1"
17132         shift
17133         local fid="$2"
17134
17135         local path
17136         path=$($LFS fid2path "$@")
17137         local rc=$?
17138
17139         if [ $rc -ne 0 ]; then
17140                 error "path looked up of '$expected' failed: rc=$rc"
17141         elif [ "$path" != "$expected" ]; then
17142                 error "path looked up '$path' instead of '$expected'"
17143         else
17144                 echo "FID '$fid' resolves to path '$path' as expected"
17145         fi
17146 }
17147
17148 test_162a() { # was test_162
17149         test_mkdir -p -c1 $DIR/$tdir/d2
17150         touch $DIR/$tdir/d2/$tfile
17151         touch $DIR/$tdir/d2/x1
17152         touch $DIR/$tdir/d2/x2
17153         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17154         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17155         # regular file
17156         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17157         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17158
17159         # softlink
17160         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17161         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17162         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17163
17164         # softlink to wrong file
17165         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17166         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17167         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17168
17169         # hardlink
17170         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17171         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17172         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17173         # fid2path dir/fsname should both work
17174         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17175         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17176
17177         # hardlink count: check that there are 2 links
17178         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17179         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17180
17181         # hardlink indexing: remove the first link
17182         rm $DIR/$tdir/d2/p/q/r/hlink
17183         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17184 }
17185 run_test 162a "path lookup sanity"
17186
17187 test_162b() {
17188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17189         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17190
17191         mkdir $DIR/$tdir
17192         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17193                                 error "create striped dir failed"
17194
17195         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17196                                         tail -n 1 | awk '{print $2}')
17197         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17198
17199         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17200         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17201
17202         # regular file
17203         for ((i=0;i<5;i++)); do
17204                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17205                         error "get fid for f$i failed"
17206                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17207
17208                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17209                         error "get fid for d$i failed"
17210                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17211         done
17212
17213         return 0
17214 }
17215 run_test 162b "striped directory path lookup sanity"
17216
17217 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17218 test_162c() {
17219         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17220                 skip "Need MDS version at least 2.7.51"
17221
17222         local lpath=$tdir.local
17223         local rpath=$tdir.remote
17224
17225         test_mkdir $DIR/$lpath
17226         test_mkdir $DIR/$rpath
17227
17228         for ((i = 0; i <= 101; i++)); do
17229                 lpath="$lpath/$i"
17230                 mkdir $DIR/$lpath
17231                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17232                         error "get fid for local directory $DIR/$lpath failed"
17233                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17234
17235                 rpath="$rpath/$i"
17236                 test_mkdir $DIR/$rpath
17237                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17238                         error "get fid for remote directory $DIR/$rpath failed"
17239                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17240         done
17241
17242         return 0
17243 }
17244 run_test 162c "fid2path works with paths 100 or more directories deep"
17245
17246 oalr_event_count() {
17247         local event="${1}"
17248         local trace="${2}"
17249
17250         awk -v name="${FSNAME}-OST0000" \
17251             -v event="${event}" \
17252             '$1 == "TRACE" && $2 == event && $3 == name' \
17253             "${trace}" |
17254         wc -l
17255 }
17256
17257 oalr_expect_event_count() {
17258         local event="${1}"
17259         local trace="${2}"
17260         local expect="${3}"
17261         local count
17262
17263         count=$(oalr_event_count "${event}" "${trace}")
17264         if ((count == expect)); then
17265                 return 0
17266         fi
17267
17268         error_noexit "${event} event count was '${count}', expected ${expect}"
17269         cat "${trace}" >&2
17270         exit 1
17271 }
17272
17273 cleanup_165() {
17274         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17275         stop ost1
17276         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17277 }
17278
17279 setup_165() {
17280         sync # Flush previous IOs so we can count log entries.
17281         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17282         stack_trap cleanup_165 EXIT
17283 }
17284
17285 test_165a() {
17286         local trace="/tmp/${tfile}.trace"
17287         local rc
17288         local count
17289
17290         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17291                 skip "OFD access log unsupported"
17292
17293         setup_165
17294         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17295         sleep 5
17296
17297         do_facet ost1 ofd_access_log_reader --list
17298         stop ost1
17299
17300         do_facet ost1 killall -TERM ofd_access_log_reader
17301         wait
17302         rc=$?
17303
17304         if ((rc != 0)); then
17305                 error "ofd_access_log_reader exited with rc = '${rc}'"
17306         fi
17307
17308         # Parse trace file for discovery events:
17309         oalr_expect_event_count alr_log_add "${trace}" 1
17310         oalr_expect_event_count alr_log_eof "${trace}" 1
17311         oalr_expect_event_count alr_log_free "${trace}" 1
17312 }
17313 run_test 165a "ofd access log discovery"
17314
17315 test_165b() {
17316         local trace="/tmp/${tfile}.trace"
17317         local file="${DIR}/${tfile}"
17318         local pfid1
17319         local pfid2
17320         local -a entry
17321         local rc
17322         local count
17323         local size
17324         local flags
17325
17326         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17327                 skip "OFD access log unsupported"
17328
17329         setup_165
17330         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17331         sleep 5
17332
17333         do_facet ost1 ofd_access_log_reader --list
17334
17335         lfs setstripe -c 1 -i 0 "${file}"
17336         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17337                 error "cannot create '${file}'"
17338
17339         sleep 5
17340         do_facet ost1 killall -TERM ofd_access_log_reader
17341         wait
17342         rc=$?
17343
17344         if ((rc != 0)); then
17345                 error "ofd_access_log_reader exited with rc = '${rc}'"
17346         fi
17347
17348         oalr_expect_event_count alr_log_entry "${trace}" 1
17349
17350         pfid1=$($LFS path2fid "${file}")
17351
17352         # 1     2             3   4    5     6   7    8    9     10
17353         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17354         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17355
17356         echo "entry = '${entry[*]}'" >&2
17357
17358         pfid2=${entry[4]}
17359         if [[ "${pfid1}" != "${pfid2}" ]]; then
17360                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17361         fi
17362
17363         size=${entry[8]}
17364         if ((size != 1048576)); then
17365                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17366         fi
17367
17368         flags=${entry[10]}
17369         if [[ "${flags}" != "w" ]]; then
17370                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17371         fi
17372
17373         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17374         sleep 5
17375
17376         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17377                 error "cannot read '${file}'"
17378         sleep 5
17379
17380         do_facet ost1 killall -TERM ofd_access_log_reader
17381         wait
17382         rc=$?
17383
17384         if ((rc != 0)); then
17385                 error "ofd_access_log_reader exited with rc = '${rc}'"
17386         fi
17387
17388         oalr_expect_event_count alr_log_entry "${trace}" 1
17389
17390         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17391         echo "entry = '${entry[*]}'" >&2
17392
17393         pfid2=${entry[4]}
17394         if [[ "${pfid1}" != "${pfid2}" ]]; then
17395                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17396         fi
17397
17398         size=${entry[8]}
17399         if ((size != 524288)); then
17400                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17401         fi
17402
17403         flags=${entry[10]}
17404         if [[ "${flags}" != "r" ]]; then
17405                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17406         fi
17407 }
17408 run_test 165b "ofd access log entries are produced and consumed"
17409
17410 test_165c() {
17411         local trace="/tmp/${tfile}.trace"
17412         local file="${DIR}/${tdir}/${tfile}"
17413
17414         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17415                 skip "OFD access log unsupported"
17416
17417         test_mkdir "${DIR}/${tdir}"
17418
17419         setup_165
17420         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17421         sleep 5
17422
17423         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17424
17425         # 4096 / 64 = 64. Create twice as many entries.
17426         for ((i = 0; i < 128; i++)); do
17427                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17428                         error "cannot create file"
17429         done
17430
17431         sync
17432
17433         do_facet ost1 killall -TERM ofd_access_log_reader
17434         wait
17435         rc=$?
17436         if ((rc != 0)); then
17437                 error "ofd_access_log_reader exited with rc = '${rc}'"
17438         fi
17439
17440         unlinkmany  "${file}-%d" 128
17441 }
17442 run_test 165c "full ofd access logs do not block IOs"
17443
17444 oal_get_read_count() {
17445         local stats="$1"
17446
17447         # STATS lustre-OST0001 alr_read_count 1
17448
17449         do_facet ost1 cat "${stats}" |
17450         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17451              END { print count; }'
17452 }
17453
17454 oal_expect_read_count() {
17455         local stats="$1"
17456         local count
17457         local expect="$2"
17458
17459         # Ask ofd_access_log_reader to write stats.
17460         do_facet ost1 killall -USR1 ofd_access_log_reader
17461
17462         # Allow some time for things to happen.
17463         sleep 1
17464
17465         count=$(oal_get_read_count "${stats}")
17466         if ((count == expect)); then
17467                 return 0
17468         fi
17469
17470         error_noexit "bad read count, got ${count}, expected ${expect}"
17471         do_facet ost1 cat "${stats}" >&2
17472         exit 1
17473 }
17474
17475 test_165d() {
17476         local stats="/tmp/${tfile}.stats"
17477         local file="${DIR}/${tdir}/${tfile}"
17478         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17479
17480         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17481                 skip "OFD access log unsupported"
17482
17483         test_mkdir "${DIR}/${tdir}"
17484
17485         setup_165
17486         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17487         sleep 5
17488
17489         lfs setstripe -c 1 -i 0 "${file}"
17490
17491         do_facet ost1 lctl set_param "${param}=rw"
17492         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17493                 error "cannot create '${file}'"
17494         oal_expect_read_count "${stats}" 1
17495
17496         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17497                 error "cannot read '${file}'"
17498         oal_expect_read_count "${stats}" 2
17499
17500         do_facet ost1 lctl set_param "${param}=r"
17501         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17502                 error "cannot create '${file}'"
17503         oal_expect_read_count "${stats}" 2
17504
17505         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17506                 error "cannot read '${file}'"
17507         oal_expect_read_count "${stats}" 3
17508
17509         do_facet ost1 lctl set_param "${param}=w"
17510         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17511                 error "cannot create '${file}'"
17512         oal_expect_read_count "${stats}" 4
17513
17514         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17515                 error "cannot read '${file}'"
17516         oal_expect_read_count "${stats}" 4
17517
17518         do_facet ost1 lctl set_param "${param}=0"
17519         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17520                 error "cannot create '${file}'"
17521         oal_expect_read_count "${stats}" 4
17522
17523         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17524                 error "cannot read '${file}'"
17525         oal_expect_read_count "${stats}" 4
17526
17527         do_facet ost1 killall -TERM ofd_access_log_reader
17528         wait
17529         rc=$?
17530         if ((rc != 0)); then
17531                 error "ofd_access_log_reader exited with rc = '${rc}'"
17532         fi
17533 }
17534 run_test 165d "ofd_access_log mask works"
17535
17536 test_165e() {
17537         local stats="/tmp/${tfile}.stats"
17538         local file0="${DIR}/${tdir}-0/${tfile}"
17539         local file1="${DIR}/${tdir}-1/${tfile}"
17540
17541         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17542                 skip "OFD access log unsupported"
17543
17544         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17545
17546         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17547         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17548
17549         lfs setstripe -c 1 -i 0 "${file0}"
17550         lfs setstripe -c 1 -i 0 "${file1}"
17551
17552         setup_165
17553         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17554         sleep 5
17555
17556         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17557                 error "cannot create '${file0}'"
17558         sync
17559         oal_expect_read_count "${stats}" 0
17560
17561         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17562                 error "cannot create '${file1}'"
17563         sync
17564         oal_expect_read_count "${stats}" 1
17565
17566         do_facet ost1 killall -TERM ofd_access_log_reader
17567         wait
17568         rc=$?
17569         if ((rc != 0)); then
17570                 error "ofd_access_log_reader exited with rc = '${rc}'"
17571         fi
17572 }
17573 run_test 165e "ofd_access_log MDT index filter works"
17574
17575 test_165f() {
17576         local trace="/tmp/${tfile}.trace"
17577         local rc
17578         local count
17579
17580         setup_165
17581         do_facet ost1 timeout 60 ofd_access_log_reader \
17582                 --exit-on-close --debug=- --trace=- > "${trace}" &
17583         sleep 5
17584         stop ost1
17585
17586         wait
17587         rc=$?
17588
17589         if ((rc != 0)); then
17590                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17591                 cat "${trace}"
17592                 exit 1
17593         fi
17594 }
17595 run_test 165f "ofd_access_log_reader --exit-on-close works"
17596
17597 test_169() {
17598         # do directio so as not to populate the page cache
17599         log "creating a 10 Mb file"
17600         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17601                 error "multiop failed while creating a file"
17602         log "starting reads"
17603         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17604         log "truncating the file"
17605         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17606                 error "multiop failed while truncating the file"
17607         log "killing dd"
17608         kill %+ || true # reads might have finished
17609         echo "wait until dd is finished"
17610         wait
17611         log "removing the temporary file"
17612         rm -rf $DIR/$tfile || error "tmp file removal failed"
17613 }
17614 run_test 169 "parallel read and truncate should not deadlock"
17615
17616 test_170() {
17617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17618
17619         $LCTL clear     # bug 18514
17620         $LCTL debug_daemon start $TMP/${tfile}_log_good
17621         touch $DIR/$tfile
17622         $LCTL debug_daemon stop
17623         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17624                 error "sed failed to read log_good"
17625
17626         $LCTL debug_daemon start $TMP/${tfile}_log_good
17627         rm -rf $DIR/$tfile
17628         $LCTL debug_daemon stop
17629
17630         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17631                error "lctl df log_bad failed"
17632
17633         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17634         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17635
17636         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17637         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17638
17639         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17640                 error "bad_line good_line1 good_line2 are empty"
17641
17642         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17643         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17644         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17645
17646         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17647         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17648         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17649
17650         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17651                 error "bad_line_new good_line_new are empty"
17652
17653         local expected_good=$((good_line1 + good_line2*2))
17654
17655         rm -f $TMP/${tfile}*
17656         # LU-231, short malformed line may not be counted into bad lines
17657         if [ $bad_line -ne $bad_line_new ] &&
17658                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17659                 error "expected $bad_line bad lines, but got $bad_line_new"
17660                 return 1
17661         fi
17662
17663         if [ $expected_good -ne $good_line_new ]; then
17664                 error "expected $expected_good good lines, but got $good_line_new"
17665                 return 2
17666         fi
17667         true
17668 }
17669 run_test 170 "test lctl df to handle corrupted log ====================="
17670
17671 test_171() { # bug20592
17672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17673
17674         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17675         $LCTL set_param fail_loc=0x50e
17676         $LCTL set_param fail_val=3000
17677         multiop_bg_pause $DIR/$tfile O_s || true
17678         local MULTIPID=$!
17679         kill -USR1 $MULTIPID
17680         # cause log dump
17681         sleep 3
17682         wait $MULTIPID
17683         if dmesg | grep "recursive fault"; then
17684                 error "caught a recursive fault"
17685         fi
17686         $LCTL set_param fail_loc=0
17687         true
17688 }
17689 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17690
17691 # it would be good to share it with obdfilter-survey/iokit-libecho code
17692 setup_obdecho_osc () {
17693         local rc=0
17694         local ost_nid=$1
17695         local obdfilter_name=$2
17696         echo "Creating new osc for $obdfilter_name on $ost_nid"
17697         # make sure we can find loopback nid
17698         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17699
17700         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17701                            ${obdfilter_name}_osc_UUID || rc=2; }
17702         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17703                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17704         return $rc
17705 }
17706
17707 cleanup_obdecho_osc () {
17708         local obdfilter_name=$1
17709         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17710         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17711         return 0
17712 }
17713
17714 obdecho_test() {
17715         local OBD=$1
17716         local node=$2
17717         local pages=${3:-64}
17718         local rc=0
17719         local id
17720
17721         local count=10
17722         local obd_size=$(get_obd_size $node $OBD)
17723         local page_size=$(get_page_size $node)
17724         if [[ -n "$obd_size" ]]; then
17725                 local new_count=$((obd_size / (pages * page_size / 1024)))
17726                 [[ $new_count -ge $count ]] || count=$new_count
17727         fi
17728
17729         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17730         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17731                            rc=2; }
17732         if [ $rc -eq 0 ]; then
17733             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17734             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17735         fi
17736         echo "New object id is $id"
17737         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17738                            rc=4; }
17739         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17740                            "test_brw $count w v $pages $id" || rc=4; }
17741         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17742                            rc=4; }
17743         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17744                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17745         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17746                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17747         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17748         return $rc
17749 }
17750
17751 test_180a() {
17752         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17753
17754         if ! [ -d /sys/fs/lustre/echo_client ] &&
17755            ! module_loaded obdecho; then
17756                 load_module obdecho/obdecho &&
17757                         stack_trap "rmmod obdecho" EXIT ||
17758                         error "unable to load obdecho on client"
17759         fi
17760
17761         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17762         local host=$($LCTL get_param -n osc.$osc.import |
17763                      awk '/current_connection:/ { print $2 }' )
17764         local target=$($LCTL get_param -n osc.$osc.import |
17765                        awk '/target:/ { print $2 }' )
17766         target=${target%_UUID}
17767
17768         if [ -n "$target" ]; then
17769                 setup_obdecho_osc $host $target &&
17770                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17771                         { error "obdecho setup failed with $?"; return; }
17772
17773                 obdecho_test ${target}_osc client ||
17774                         error "obdecho_test failed on ${target}_osc"
17775         else
17776                 $LCTL get_param osc.$osc.import
17777                 error "there is no osc.$osc.import target"
17778         fi
17779 }
17780 run_test 180a "test obdecho on osc"
17781
17782 test_180b() {
17783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17784         remote_ost_nodsh && skip "remote OST with nodsh"
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                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17795         else
17796                 do_facet ost1 $LCTL dl
17797                 error "there is no obdfilter target on ost1"
17798         fi
17799 }
17800 run_test 180b "test obdecho directly on obdfilter"
17801
17802 test_180c() { # LU-2598
17803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17804         remote_ost_nodsh && skip "remote OST with nodsh"
17805         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17806                 skip "Need MDS version at least 2.4.0"
17807
17808         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17809                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17810                 error "failed to load module obdecho"
17811
17812         local target=$(do_facet ost1 $LCTL dl |
17813                        awk '/obdfilter/ { print $4; exit; }')
17814
17815         if [ -n "$target" ]; then
17816                 local pages=16384 # 64MB bulk I/O RPC size
17817
17818                 obdecho_test "$target" ost1 "$pages" ||
17819                         error "obdecho_test with pages=$pages failed with $?"
17820         else
17821                 do_facet ost1 $LCTL dl
17822                 error "there is no obdfilter target on ost1"
17823         fi
17824 }
17825 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17826
17827 test_181() { # bug 22177
17828         test_mkdir $DIR/$tdir
17829         # create enough files to index the directory
17830         createmany -o $DIR/$tdir/foobar 4000
17831         # print attributes for debug purpose
17832         lsattr -d .
17833         # open dir
17834         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17835         MULTIPID=$!
17836         # remove the files & current working dir
17837         unlinkmany $DIR/$tdir/foobar 4000
17838         rmdir $DIR/$tdir
17839         kill -USR1 $MULTIPID
17840         wait $MULTIPID
17841         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17842         return 0
17843 }
17844 run_test 181 "Test open-unlinked dir ========================"
17845
17846 test_182a() {
17847         local fcount=1000
17848         local tcount=10
17849
17850         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17851
17852         $LCTL set_param mdc.*.rpc_stats=clear
17853
17854         for (( i = 0; i < $tcount; i++ )) ; do
17855                 mkdir $DIR/$tdir/$i
17856         done
17857
17858         for (( i = 0; i < $tcount; i++ )) ; do
17859                 createmany -o $DIR/$tdir/$i/f- $fcount &
17860         done
17861         wait
17862
17863         for (( i = 0; i < $tcount; i++ )) ; do
17864                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17865         done
17866         wait
17867
17868         $LCTL get_param mdc.*.rpc_stats
17869
17870         rm -rf $DIR/$tdir
17871 }
17872 run_test 182a "Test parallel modify metadata operations from mdc"
17873
17874 test_182b() {
17875         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
17876         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
17877         local dcount=1000
17878         local tcount=10
17879         local stime
17880         local etime
17881         local delta
17882
17883         do_facet mds1 $LCTL list_param \
17884                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
17885                 skip "MDS lacks parallel RPC handling"
17886
17887         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17888
17889         rpc_count=$(do_facet mds1 $LCTL get_param -n \
17890                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
17891
17892         stime=$(date +%s)
17893         createmany -i 0 -d $DIR/$tdir/t- $tcount
17894
17895         for (( i = 0; i < $tcount; i++ )) ; do
17896                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
17897         done
17898         wait
17899         etime=$(date +%s)
17900         delta=$((etime - stime))
17901         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
17902
17903         stime=$(date +%s)
17904         for (( i = 0; i < $tcount; i++ )) ; do
17905                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
17906         done
17907         wait
17908         etime=$(date +%s)
17909         delta=$((etime - stime))
17910         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
17911
17912         rm -rf $DIR/$tdir
17913
17914         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17915
17916         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
17917
17918         stime=$(date +%s)
17919         createmany -i 0 -d $DIR/$tdir/t- $tcount
17920
17921         for (( i = 0; i < $tcount; i++ )) ; do
17922                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
17923         done
17924         wait
17925         etime=$(date +%s)
17926         delta=$((etime - stime))
17927         echo "Time for file creation $delta sec for 1 RPC sent at a time"
17928
17929         stime=$(date +%s)
17930         for (( i = 0; i < $tcount; i++ )) ; do
17931                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
17932         done
17933         wait
17934         etime=$(date +%s)
17935         delta=$((etime - stime))
17936         echo "Time for file removal $delta sec for 1 RPC sent at a time"
17937
17938         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
17939 }
17940 run_test 182b "Test parallel modify metadata operations from osp"
17941
17942 test_183() { # LU-2275
17943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17944         remote_mds_nodsh && skip "remote MDS with nodsh"
17945         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17946                 skip "Need MDS version at least 2.3.56"
17947
17948         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17949         echo aaa > $DIR/$tdir/$tfile
17950
17951 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17952         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17953
17954         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17955         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17956
17957         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17958
17959         # Flush negative dentry cache
17960         touch $DIR/$tdir/$tfile
17961
17962         # We are not checking for any leaked references here, they'll
17963         # become evident next time we do cleanup with module unload.
17964         rm -rf $DIR/$tdir
17965 }
17966 run_test 183 "No crash or request leak in case of strange dispositions ========"
17967
17968 # test suite 184 is for LU-2016, LU-2017
17969 test_184a() {
17970         check_swap_layouts_support
17971
17972         dir0=$DIR/$tdir/$testnum
17973         test_mkdir -p -c1 $dir0
17974         ref1=/etc/passwd
17975         ref2=/etc/group
17976         file1=$dir0/f1
17977         file2=$dir0/f2
17978         $LFS setstripe -c1 $file1
17979         cp $ref1 $file1
17980         $LFS setstripe -c2 $file2
17981         cp $ref2 $file2
17982         gen1=$($LFS getstripe -g $file1)
17983         gen2=$($LFS getstripe -g $file2)
17984
17985         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17986         gen=$($LFS getstripe -g $file1)
17987         [[ $gen1 != $gen ]] ||
17988                 error "Layout generation on $file1 does not change"
17989         gen=$($LFS getstripe -g $file2)
17990         [[ $gen2 != $gen ]] ||
17991                 error "Layout generation on $file2 does not change"
17992
17993         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17994         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17995
17996         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17997 }
17998 run_test 184a "Basic layout swap"
17999
18000 test_184b() {
18001         check_swap_layouts_support
18002
18003         dir0=$DIR/$tdir/$testnum
18004         mkdir -p $dir0 || error "creating dir $dir0"
18005         file1=$dir0/f1
18006         file2=$dir0/f2
18007         file3=$dir0/f3
18008         dir1=$dir0/d1
18009         dir2=$dir0/d2
18010         mkdir $dir1 $dir2
18011         $LFS setstripe -c1 $file1
18012         $LFS setstripe -c2 $file2
18013         $LFS setstripe -c1 $file3
18014         chown $RUNAS_ID $file3
18015         gen1=$($LFS getstripe -g $file1)
18016         gen2=$($LFS getstripe -g $file2)
18017
18018         $LFS swap_layouts $dir1 $dir2 &&
18019                 error "swap of directories layouts should fail"
18020         $LFS swap_layouts $dir1 $file1 &&
18021                 error "swap of directory and file layouts should fail"
18022         $RUNAS $LFS swap_layouts $file1 $file2 &&
18023                 error "swap of file we cannot write should fail"
18024         $LFS swap_layouts $file1 $file3 &&
18025                 error "swap of file with different owner should fail"
18026         /bin/true # to clear error code
18027 }
18028 run_test 184b "Forbidden layout swap (will generate errors)"
18029
18030 test_184c() {
18031         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18032         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18033         check_swap_layouts_support
18034         check_swap_layout_no_dom $DIR
18035
18036         local dir0=$DIR/$tdir/$testnum
18037         mkdir -p $dir0 || error "creating dir $dir0"
18038
18039         local ref1=$dir0/ref1
18040         local ref2=$dir0/ref2
18041         local file1=$dir0/file1
18042         local file2=$dir0/file2
18043         # create a file large enough for the concurrent test
18044         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18045         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18046         echo "ref file size: ref1($(stat -c %s $ref1))," \
18047              "ref2($(stat -c %s $ref2))"
18048
18049         cp $ref2 $file2
18050         dd if=$ref1 of=$file1 bs=16k &
18051         local DD_PID=$!
18052
18053         # Make sure dd starts to copy file, but wait at most 5 seconds
18054         local loops=0
18055         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18056
18057         $LFS swap_layouts $file1 $file2
18058         local rc=$?
18059         wait $DD_PID
18060         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18061         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18062
18063         # how many bytes copied before swapping layout
18064         local copied=$(stat -c %s $file2)
18065         local remaining=$(stat -c %s $ref1)
18066         remaining=$((remaining - copied))
18067         echo "Copied $copied bytes before swapping layout..."
18068
18069         cmp -n $copied $file1 $ref2 | grep differ &&
18070                 error "Content mismatch [0, $copied) of ref2 and file1"
18071         cmp -n $copied $file2 $ref1 ||
18072                 error "Content mismatch [0, $copied) of ref1 and file2"
18073         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18074                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18075
18076         # clean up
18077         rm -f $ref1 $ref2 $file1 $file2
18078 }
18079 run_test 184c "Concurrent write and layout swap"
18080
18081 test_184d() {
18082         check_swap_layouts_support
18083         check_swap_layout_no_dom $DIR
18084         [ -z "$(which getfattr 2>/dev/null)" ] &&
18085                 skip_env "no getfattr command"
18086
18087         local file1=$DIR/$tdir/$tfile-1
18088         local file2=$DIR/$tdir/$tfile-2
18089         local file3=$DIR/$tdir/$tfile-3
18090         local lovea1
18091         local lovea2
18092
18093         mkdir -p $DIR/$tdir
18094         touch $file1 || error "create $file1 failed"
18095         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18096                 error "create $file2 failed"
18097         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18098                 error "create $file3 failed"
18099         lovea1=$(get_layout_param $file1)
18100
18101         $LFS swap_layouts $file2 $file3 ||
18102                 error "swap $file2 $file3 layouts failed"
18103         $LFS swap_layouts $file1 $file2 ||
18104                 error "swap $file1 $file2 layouts failed"
18105
18106         lovea2=$(get_layout_param $file2)
18107         echo "$lovea1"
18108         echo "$lovea2"
18109         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18110
18111         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18112         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18113 }
18114 run_test 184d "allow stripeless layouts swap"
18115
18116 test_184e() {
18117         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18118                 skip "Need MDS version at least 2.6.94"
18119         check_swap_layouts_support
18120         check_swap_layout_no_dom $DIR
18121         [ -z "$(which getfattr 2>/dev/null)" ] &&
18122                 skip_env "no getfattr command"
18123
18124         local file1=$DIR/$tdir/$tfile-1
18125         local file2=$DIR/$tdir/$tfile-2
18126         local file3=$DIR/$tdir/$tfile-3
18127         local lovea
18128
18129         mkdir -p $DIR/$tdir
18130         touch $file1 || error "create $file1 failed"
18131         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18132                 error "create $file2 failed"
18133         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18134                 error "create $file3 failed"
18135
18136         $LFS swap_layouts $file1 $file2 ||
18137                 error "swap $file1 $file2 layouts failed"
18138
18139         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18140         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18141
18142         echo 123 > $file1 || error "Should be able to write into $file1"
18143
18144         $LFS swap_layouts $file1 $file3 ||
18145                 error "swap $file1 $file3 layouts failed"
18146
18147         echo 123 > $file1 || error "Should be able to write into $file1"
18148
18149         rm -rf $file1 $file2 $file3
18150 }
18151 run_test 184e "Recreate layout after stripeless layout swaps"
18152
18153 test_184f() {
18154         # Create a file with name longer than sizeof(struct stat) ==
18155         # 144 to see if we can get chars from the file name to appear
18156         # in the returned striping. Note that 'f' == 0x66.
18157         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18158
18159         mkdir -p $DIR/$tdir
18160         mcreate $DIR/$tdir/$file
18161         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18162                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18163         fi
18164 }
18165 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18166
18167 test_185() { # LU-2441
18168         # LU-3553 - no volatile file support in old servers
18169         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18170                 skip "Need MDS version at least 2.3.60"
18171
18172         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18173         touch $DIR/$tdir/spoo
18174         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18175         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18176                 error "cannot create/write a volatile file"
18177         [ "$FILESET" == "" ] &&
18178         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18179                 error "FID is still valid after close"
18180
18181         multiop_bg_pause $DIR/$tdir vVw4096_c
18182         local multi_pid=$!
18183
18184         local OLD_IFS=$IFS
18185         IFS=":"
18186         local fidv=($fid)
18187         IFS=$OLD_IFS
18188         # assume that the next FID for this client is sequential, since stdout
18189         # is unfortunately eaten by multiop_bg_pause
18190         local n=$((${fidv[1]} + 1))
18191         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18192         if [ "$FILESET" == "" ]; then
18193                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18194                         error "FID is missing before close"
18195         fi
18196         kill -USR1 $multi_pid
18197         # 1 second delay, so if mtime change we will see it
18198         sleep 1
18199         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18200         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18201 }
18202 run_test 185 "Volatile file support"
18203
18204 function create_check_volatile() {
18205         local idx=$1
18206         local tgt
18207
18208         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18209         local PID=$!
18210         sleep 1
18211         local FID=$(cat /tmp/${tfile}.fid)
18212         [ "$FID" == "" ] && error "can't get FID for volatile"
18213         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18214         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18215         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18216         kill -USR1 $PID
18217         wait
18218         sleep 1
18219         cancel_lru_locks mdc # flush opencache
18220         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18221         return 0
18222 }
18223
18224 test_185a(){
18225         # LU-12516 - volatile creation via .lustre
18226         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18227                 skip "Need MDS version at least 2.3.55"
18228
18229         create_check_volatile 0
18230         [ $MDSCOUNT -lt 2 ] && return 0
18231
18232         # DNE case
18233         create_check_volatile 1
18234
18235         return 0
18236 }
18237 run_test 185a "Volatile file creation in .lustre/fid/"
18238
18239 test_187a() {
18240         remote_mds_nodsh && skip "remote MDS with nodsh"
18241         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18242                 skip "Need MDS version at least 2.3.0"
18243
18244         local dir0=$DIR/$tdir/$testnum
18245         mkdir -p $dir0 || error "creating dir $dir0"
18246
18247         local file=$dir0/file1
18248         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18249         local dv1=$($LFS data_version $file)
18250         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18251         local dv2=$($LFS data_version $file)
18252         [[ $dv1 != $dv2 ]] ||
18253                 error "data version did not change on write $dv1 == $dv2"
18254
18255         # clean up
18256         rm -f $file1
18257 }
18258 run_test 187a "Test data version change"
18259
18260 test_187b() {
18261         remote_mds_nodsh && skip "remote MDS with nodsh"
18262         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18263                 skip "Need MDS version at least 2.3.0"
18264
18265         local dir0=$DIR/$tdir/$testnum
18266         mkdir -p $dir0 || error "creating dir $dir0"
18267
18268         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18269         [[ ${DV[0]} != ${DV[1]} ]] ||
18270                 error "data version did not change on write"\
18271                       " ${DV[0]} == ${DV[1]}"
18272
18273         # clean up
18274         rm -f $file1
18275 }
18276 run_test 187b "Test data version change on volatile file"
18277
18278 test_200() {
18279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18280         remote_mgs_nodsh && skip "remote MGS with nodsh"
18281         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18282
18283         local POOL=${POOL:-cea1}
18284         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18285         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18286         # Pool OST targets
18287         local first_ost=0
18288         local last_ost=$(($OSTCOUNT - 1))
18289         local ost_step=2
18290         local ost_list=$(seq $first_ost $ost_step $last_ost)
18291         local ost_range="$first_ost $last_ost $ost_step"
18292         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18293         local file_dir=$POOL_ROOT/file_tst
18294         local subdir=$test_path/subdir
18295         local rc=0
18296
18297         while : ; do
18298                 # former test_200a test_200b
18299                 pool_add $POOL                          || { rc=$? ; break; }
18300                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18301                 # former test_200c test_200d
18302                 mkdir -p $test_path
18303                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18304                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18305                 mkdir -p $subdir
18306                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18307                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18308                                                         || { rc=$? ; break; }
18309                 # former test_200e test_200f
18310                 local files=$((OSTCOUNT*3))
18311                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18312                                                         || { rc=$? ; break; }
18313                 pool_create_files $POOL $file_dir $files "$ost_list" \
18314                                                         || { rc=$? ; break; }
18315                 # former test_200g test_200h
18316                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18317                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18318
18319                 # former test_201a test_201b test_201c
18320                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18321
18322                 local f=$test_path/$tfile
18323                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18324                 pool_remove $POOL $f                    || { rc=$? ; break; }
18325                 break
18326         done
18327
18328         destroy_test_pools
18329
18330         return $rc
18331 }
18332 run_test 200 "OST pools"
18333
18334 # usage: default_attr <count | size | offset>
18335 default_attr() {
18336         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18337 }
18338
18339 # usage: check_default_stripe_attr
18340 check_default_stripe_attr() {
18341         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18342         case $1 in
18343         --stripe-count|-c)
18344                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18345         --stripe-size|-S)
18346                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18347         --stripe-index|-i)
18348                 EXPECTED=-1;;
18349         *)
18350                 error "unknown getstripe attr '$1'"
18351         esac
18352
18353         [ $ACTUAL == $EXPECTED ] ||
18354                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18355 }
18356
18357 test_204a() {
18358         test_mkdir $DIR/$tdir
18359         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18360
18361         check_default_stripe_attr --stripe-count
18362         check_default_stripe_attr --stripe-size
18363         check_default_stripe_attr --stripe-index
18364 }
18365 run_test 204a "Print default stripe attributes"
18366
18367 test_204b() {
18368         test_mkdir $DIR/$tdir
18369         $LFS setstripe --stripe-count 1 $DIR/$tdir
18370
18371         check_default_stripe_attr --stripe-size
18372         check_default_stripe_attr --stripe-index
18373 }
18374 run_test 204b "Print default stripe size and offset"
18375
18376 test_204c() {
18377         test_mkdir $DIR/$tdir
18378         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18379
18380         check_default_stripe_attr --stripe-count
18381         check_default_stripe_attr --stripe-index
18382 }
18383 run_test 204c "Print default stripe count and offset"
18384
18385 test_204d() {
18386         test_mkdir $DIR/$tdir
18387         $LFS setstripe --stripe-index 0 $DIR/$tdir
18388
18389         check_default_stripe_attr --stripe-count
18390         check_default_stripe_attr --stripe-size
18391 }
18392 run_test 204d "Print default stripe count and size"
18393
18394 test_204e() {
18395         test_mkdir $DIR/$tdir
18396         $LFS setstripe -d $DIR/$tdir
18397
18398         check_default_stripe_attr --stripe-count --raw
18399         check_default_stripe_attr --stripe-size --raw
18400         check_default_stripe_attr --stripe-index --raw
18401 }
18402 run_test 204e "Print raw stripe attributes"
18403
18404 test_204f() {
18405         test_mkdir $DIR/$tdir
18406         $LFS setstripe --stripe-count 1 $DIR/$tdir
18407
18408         check_default_stripe_attr --stripe-size --raw
18409         check_default_stripe_attr --stripe-index --raw
18410 }
18411 run_test 204f "Print raw stripe size and offset"
18412
18413 test_204g() {
18414         test_mkdir $DIR/$tdir
18415         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18416
18417         check_default_stripe_attr --stripe-count --raw
18418         check_default_stripe_attr --stripe-index --raw
18419 }
18420 run_test 204g "Print raw stripe count and offset"
18421
18422 test_204h() {
18423         test_mkdir $DIR/$tdir
18424         $LFS setstripe --stripe-index 0 $DIR/$tdir
18425
18426         check_default_stripe_attr --stripe-count --raw
18427         check_default_stripe_attr --stripe-size --raw
18428 }
18429 run_test 204h "Print raw stripe count and size"
18430
18431 # Figure out which job scheduler is being used, if any,
18432 # or use a fake one
18433 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18434         JOBENV=SLURM_JOB_ID
18435 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18436         JOBENV=LSB_JOBID
18437 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18438         JOBENV=PBS_JOBID
18439 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18440         JOBENV=LOADL_STEP_ID
18441 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18442         JOBENV=JOB_ID
18443 else
18444         $LCTL list_param jobid_name > /dev/null 2>&1
18445         if [ $? -eq 0 ]; then
18446                 JOBENV=nodelocal
18447         else
18448                 JOBENV=FAKE_JOBID
18449         fi
18450 fi
18451 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18452
18453 verify_jobstats() {
18454         local cmd=($1)
18455         shift
18456         local facets="$@"
18457
18458 # we don't really need to clear the stats for this test to work, since each
18459 # command has a unique jobid, but it makes debugging easier if needed.
18460 #       for facet in $facets; do
18461 #               local dev=$(convert_facet2label $facet)
18462 #               # clear old jobstats
18463 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18464 #       done
18465
18466         # use a new JobID for each test, or we might see an old one
18467         [ "$JOBENV" = "FAKE_JOBID" ] &&
18468                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18469
18470         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18471
18472         [ "$JOBENV" = "nodelocal" ] && {
18473                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18474                 $LCTL set_param jobid_name=$FAKE_JOBID
18475                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18476         }
18477
18478         log "Test: ${cmd[*]}"
18479         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18480
18481         if [ $JOBENV = "FAKE_JOBID" ]; then
18482                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18483         else
18484                 ${cmd[*]}
18485         fi
18486
18487         # all files are created on OST0000
18488         for facet in $facets; do
18489                 local stats="*.$(convert_facet2label $facet).job_stats"
18490
18491                 # strip out libtool wrappers for in-tree executables
18492                 if (( $(do_facet $facet lctl get_param $stats |
18493                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18494                         do_facet $facet lctl get_param $stats
18495                         error "No jobstats for $JOBVAL found on $facet::$stats"
18496                 fi
18497         done
18498 }
18499
18500 jobstats_set() {
18501         local new_jobenv=$1
18502
18503         set_persistent_param_and_check client "jobid_var" \
18504                 "$FSNAME.sys.jobid_var" $new_jobenv
18505 }
18506
18507 test_205a() { # Job stats
18508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18509         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18510                 skip "Need MDS version with at least 2.7.1"
18511         remote_mgs_nodsh && skip "remote MGS with nodsh"
18512         remote_mds_nodsh && skip "remote MDS with nodsh"
18513         remote_ost_nodsh && skip "remote OST with nodsh"
18514         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18515                 skip "Server doesn't support jobstats"
18516         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18517
18518         local old_jobenv=$($LCTL get_param -n jobid_var)
18519         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18520
18521         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18522                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18523         else
18524                 stack_trap "do_facet mgs $PERM_CMD \
18525                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18526         fi
18527         changelog_register
18528
18529         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18530                                 mdt.*.job_cleanup_interval | head -n 1)
18531         local new_interval=5
18532         do_facet $SINGLEMDS \
18533                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18534         stack_trap "do_facet $SINGLEMDS \
18535                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18536         local start=$SECONDS
18537
18538         local cmd
18539         # mkdir
18540         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18541         verify_jobstats "$cmd" "$SINGLEMDS"
18542         # rmdir
18543         cmd="rmdir $DIR/$tdir"
18544         verify_jobstats "$cmd" "$SINGLEMDS"
18545         # mkdir on secondary MDT
18546         if [ $MDSCOUNT -gt 1 ]; then
18547                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18548                 verify_jobstats "$cmd" "mds2"
18549         fi
18550         # mknod
18551         cmd="mknod $DIR/$tfile c 1 3"
18552         verify_jobstats "$cmd" "$SINGLEMDS"
18553         # unlink
18554         cmd="rm -f $DIR/$tfile"
18555         verify_jobstats "$cmd" "$SINGLEMDS"
18556         # create all files on OST0000 so verify_jobstats can find OST stats
18557         # open & close
18558         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18559         verify_jobstats "$cmd" "$SINGLEMDS"
18560         # setattr
18561         cmd="touch $DIR/$tfile"
18562         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18563         # write
18564         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18565         verify_jobstats "$cmd" "ost1"
18566         # read
18567         cancel_lru_locks osc
18568         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18569         verify_jobstats "$cmd" "ost1"
18570         # truncate
18571         cmd="$TRUNCATE $DIR/$tfile 0"
18572         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18573         # rename
18574         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18575         verify_jobstats "$cmd" "$SINGLEMDS"
18576         # jobstats expiry - sleep until old stats should be expired
18577         local left=$((new_interval + 5 - (SECONDS - start)))
18578         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18579                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18580                         "0" $left
18581         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18582         verify_jobstats "$cmd" "$SINGLEMDS"
18583         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18584             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18585
18586         # Ensure that jobid are present in changelog (if supported by MDS)
18587         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18588                 changelog_dump | tail -10
18589                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18590                 [ $jobids -eq 9 ] ||
18591                         error "Wrong changelog jobid count $jobids != 9"
18592
18593                 # LU-5862
18594                 JOBENV="disable"
18595                 jobstats_set $JOBENV
18596                 touch $DIR/$tfile
18597                 changelog_dump | grep $tfile
18598                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18599                 [ $jobids -eq 0 ] ||
18600                         error "Unexpected jobids when jobid_var=$JOBENV"
18601         fi
18602
18603         # test '%j' access to environment variable - if supported
18604         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18605                 JOBENV="JOBCOMPLEX"
18606                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18607
18608                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18609         fi
18610
18611         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18612                 JOBENV="JOBCOMPLEX"
18613                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18614
18615                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18616         fi
18617
18618         # test '%j' access to per-session jobid - if supported
18619         if lctl list_param jobid_this_session > /dev/null 2>&1
18620         then
18621                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18622                 lctl set_param jobid_this_session=$USER
18623
18624                 JOBENV="JOBCOMPLEX"
18625                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18626
18627                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18628         fi
18629 }
18630 run_test 205a "Verify job stats"
18631
18632 # LU-13117, LU-13597
18633 test_205b() {
18634         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18635                 skip "Need MDS version at least 2.13.54.91"
18636
18637         job_stats="mdt.*.job_stats"
18638         $LCTL set_param $job_stats=clear
18639         # Setting jobid_var to USER might not be supported
18640         $LCTL set_param jobid_var=USER || true
18641         $LCTL set_param jobid_name="%e.%u"
18642         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18643         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18644                 grep "job_id:.*foolish" &&
18645                         error "Unexpected jobid found"
18646         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18647                 grep "open:.*min.*max.*sum" ||
18648                         error "wrong job_stats format found"
18649 }
18650 run_test 205b "Verify job stats jobid and output format"
18651
18652 # LU-13733
18653 test_205c() {
18654         $LCTL set_param llite.*.stats=0
18655         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18656         $LCTL get_param llite.*.stats
18657         $LCTL get_param llite.*.stats | grep \
18658                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18659                         error "wrong client stats format found"
18660 }
18661 run_test 205c "Verify client stats format"
18662
18663 # LU-1480, LU-1773 and LU-1657
18664 test_206() {
18665         mkdir -p $DIR/$tdir
18666         $LFS setstripe -c -1 $DIR/$tdir
18667 #define OBD_FAIL_LOV_INIT 0x1403
18668         $LCTL set_param fail_loc=0xa0001403
18669         $LCTL set_param fail_val=1
18670         touch $DIR/$tdir/$tfile || true
18671 }
18672 run_test 206 "fail lov_init_raid0() doesn't lbug"
18673
18674 test_207a() {
18675         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18676         local fsz=`stat -c %s $DIR/$tfile`
18677         cancel_lru_locks mdc
18678
18679         # do not return layout in getattr intent
18680 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18681         $LCTL set_param fail_loc=0x170
18682         local sz=`stat -c %s $DIR/$tfile`
18683
18684         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18685
18686         rm -rf $DIR/$tfile
18687 }
18688 run_test 207a "can refresh layout at glimpse"
18689
18690 test_207b() {
18691         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18692         local cksum=`md5sum $DIR/$tfile`
18693         local fsz=`stat -c %s $DIR/$tfile`
18694         cancel_lru_locks mdc
18695         cancel_lru_locks osc
18696
18697         # do not return layout in getattr intent
18698 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18699         $LCTL set_param fail_loc=0x171
18700
18701         # it will refresh layout after the file is opened but before read issues
18702         echo checksum is "$cksum"
18703         echo "$cksum" |md5sum -c --quiet || error "file differs"
18704
18705         rm -rf $DIR/$tfile
18706 }
18707 run_test 207b "can refresh layout at open"
18708
18709 test_208() {
18710         # FIXME: in this test suite, only RD lease is used. This is okay
18711         # for now as only exclusive open is supported. After generic lease
18712         # is done, this test suite should be revised. - Jinshan
18713
18714         remote_mds_nodsh && skip "remote MDS with nodsh"
18715         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18716                 skip "Need MDS version at least 2.4.52"
18717
18718         echo "==== test 1: verify get lease work"
18719         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18720
18721         echo "==== test 2: verify lease can be broken by upcoming open"
18722         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18723         local PID=$!
18724         sleep 2
18725
18726         $MULTIOP $DIR/$tfile oO_RDWR:c
18727         kill -USR1 $PID && wait $PID || error "break lease error"
18728
18729         echo "==== test 3: verify lease can't be granted if an open already exists"
18730         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18731         local PID=$!
18732         sleep 2
18733
18734         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18735         kill -USR1 $PID && wait $PID || error "open file error"
18736
18737         echo "==== test 4: lease can sustain over recovery"
18738         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18739         PID=$!
18740         sleep 2
18741
18742         fail mds1
18743
18744         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18745
18746         echo "==== test 5: lease broken can't be regained by replay"
18747         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18748         PID=$!
18749         sleep 2
18750
18751         # open file to break lease and then recovery
18752         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18753         fail mds1
18754
18755         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18756
18757         rm -f $DIR/$tfile
18758 }
18759 run_test 208 "Exclusive open"
18760
18761 test_209() {
18762         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18763                 skip_env "must have disp_stripe"
18764
18765         touch $DIR/$tfile
18766         sync; sleep 5; sync;
18767
18768         echo 3 > /proc/sys/vm/drop_caches
18769         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18770                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18771         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18772
18773         # open/close 500 times
18774         for i in $(seq 500); do
18775                 cat $DIR/$tfile
18776         done
18777
18778         echo 3 > /proc/sys/vm/drop_caches
18779         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18780                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18781         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18782
18783         echo "before: $req_before, after: $req_after"
18784         [ $((req_after - req_before)) -ge 300 ] &&
18785                 error "open/close requests are not freed"
18786         return 0
18787 }
18788 run_test 209 "read-only open/close requests should be freed promptly"
18789
18790 test_210() {
18791         local pid
18792
18793         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18794         pid=$!
18795         sleep 1
18796
18797         $LFS getstripe $DIR/$tfile
18798         kill -USR1 $pid
18799         wait $pid || error "multiop failed"
18800
18801         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18802         pid=$!
18803         sleep 1
18804
18805         $LFS getstripe $DIR/$tfile
18806         kill -USR1 $pid
18807         wait $pid || error "multiop failed"
18808 }
18809 run_test 210 "lfs getstripe does not break leases"
18810
18811 test_212() {
18812         size=`date +%s`
18813         size=$((size % 8192 + 1))
18814         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18815         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18816         rm -f $DIR/f212 $DIR/f212.xyz
18817 }
18818 run_test 212 "Sendfile test ============================================"
18819
18820 test_213() {
18821         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18822         cancel_lru_locks osc
18823         lctl set_param fail_loc=0x8000040f
18824         # generate a read lock
18825         cat $DIR/$tfile > /dev/null
18826         # write to the file, it will try to cancel the above read lock.
18827         cat /etc/hosts >> $DIR/$tfile
18828 }
18829 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18830
18831 test_214() { # for bug 20133
18832         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18833         for (( i=0; i < 340; i++ )) ; do
18834                 touch $DIR/$tdir/d214c/a$i
18835         done
18836
18837         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18838         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18839         ls $DIR/d214c || error "ls $DIR/d214c failed"
18840         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18841         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18842 }
18843 run_test 214 "hash-indexed directory test - bug 20133"
18844
18845 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18846 create_lnet_proc_files() {
18847         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18848 }
18849
18850 # counterpart of create_lnet_proc_files
18851 remove_lnet_proc_files() {
18852         rm -f $TMP/lnet_$1.sys
18853 }
18854
18855 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18856 # 3rd arg as regexp for body
18857 check_lnet_proc_stats() {
18858         local l=$(cat "$TMP/lnet_$1" |wc -l)
18859         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18860
18861         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18862 }
18863
18864 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18865 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18866 # optional and can be regexp for 2nd line (lnet.routes case)
18867 check_lnet_proc_entry() {
18868         local blp=2          # blp stands for 'position of 1st line of body'
18869         [ -z "$5" ] || blp=3 # lnet.routes case
18870
18871         local l=$(cat "$TMP/lnet_$1" |wc -l)
18872         # subtracting one from $blp because the body can be empty
18873         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18874
18875         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18876                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18877
18878         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18879                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18880
18881         # bail out if any unexpected line happened
18882         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18883         [ "$?" != 0 ] || error "$2 misformatted"
18884 }
18885
18886 test_215() { # for bugs 18102, 21079, 21517
18887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18888
18889         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18890         local P='[1-9][0-9]*'           # positive numeric
18891         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18892         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18893         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18894         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18895
18896         local L1 # regexp for 1st line
18897         local L2 # regexp for 2nd line (optional)
18898         local BR # regexp for the rest (body)
18899
18900         # lnet.stats should look as 11 space-separated non-negative numerics
18901         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18902         create_lnet_proc_files "stats"
18903         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18904         remove_lnet_proc_files "stats"
18905
18906         # lnet.routes should look like this:
18907         # Routing disabled/enabled
18908         # net hops priority state router
18909         # where net is a string like tcp0, hops > 0, priority >= 0,
18910         # state is up/down,
18911         # router is a string like 192.168.1.1@tcp2
18912         L1="^Routing (disabled|enabled)$"
18913         L2="^net +hops +priority +state +router$"
18914         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18915         create_lnet_proc_files "routes"
18916         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18917         remove_lnet_proc_files "routes"
18918
18919         # lnet.routers should look like this:
18920         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18921         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18922         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18923         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18924         L1="^ref +rtr_ref +alive +router$"
18925         BR="^$P +$P +(up|down) +$NID$"
18926         create_lnet_proc_files "routers"
18927         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18928         remove_lnet_proc_files "routers"
18929
18930         # lnet.peers should look like this:
18931         # nid refs state last max rtr min tx min queue
18932         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18933         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18934         # numeric (0 or >0 or <0), queue >= 0.
18935         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18936         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18937         create_lnet_proc_files "peers"
18938         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18939         remove_lnet_proc_files "peers"
18940
18941         # lnet.buffers  should look like this:
18942         # pages count credits min
18943         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18944         L1="^pages +count +credits +min$"
18945         BR="^ +$N +$N +$I +$I$"
18946         create_lnet_proc_files "buffers"
18947         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18948         remove_lnet_proc_files "buffers"
18949
18950         # lnet.nis should look like this:
18951         # nid status alive refs peer rtr max tx min
18952         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18953         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18954         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18955         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18956         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18957         create_lnet_proc_files "nis"
18958         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18959         remove_lnet_proc_files "nis"
18960
18961         # can we successfully write to lnet.stats?
18962         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18963 }
18964 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18965
18966 test_216() { # bug 20317
18967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18968         remote_ost_nodsh && skip "remote OST with nodsh"
18969
18970         local node
18971         local facets=$(get_facets OST)
18972         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18973
18974         save_lustre_params client "osc.*.contention_seconds" > $p
18975         save_lustre_params $facets \
18976                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18977         save_lustre_params $facets \
18978                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18979         save_lustre_params $facets \
18980                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18981         clear_stats osc.*.osc_stats
18982
18983         # agressive lockless i/o settings
18984         do_nodes $(comma_list $(osts_nodes)) \
18985                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18986                         ldlm.namespaces.filter-*.contended_locks=0 \
18987                         ldlm.namespaces.filter-*.contention_seconds=60"
18988         lctl set_param -n osc.*.contention_seconds=60
18989
18990         $DIRECTIO write $DIR/$tfile 0 10 4096
18991         $CHECKSTAT -s 40960 $DIR/$tfile
18992
18993         # disable lockless i/o
18994         do_nodes $(comma_list $(osts_nodes)) \
18995                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18996                         ldlm.namespaces.filter-*.contended_locks=32 \
18997                         ldlm.namespaces.filter-*.contention_seconds=0"
18998         lctl set_param -n osc.*.contention_seconds=0
18999         clear_stats osc.*.osc_stats
19000
19001         dd if=/dev/zero of=$DIR/$tfile count=0
19002         $CHECKSTAT -s 0 $DIR/$tfile
19003
19004         restore_lustre_params <$p
19005         rm -f $p
19006         rm $DIR/$tfile
19007 }
19008 run_test 216 "check lockless direct write updates file size and kms correctly"
19009
19010 test_217() { # bug 22430
19011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19012
19013         local node
19014         local nid
19015
19016         for node in $(nodes_list); do
19017                 nid=$(host_nids_address $node $NETTYPE)
19018                 if [[ $nid = *-* ]] ; then
19019                         echo "lctl ping $(h2nettype $nid)"
19020                         lctl ping $(h2nettype $nid)
19021                 else
19022                         echo "skipping $node (no hyphen detected)"
19023                 fi
19024         done
19025 }
19026 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19027
19028 test_218() {
19029        # do directio so as not to populate the page cache
19030        log "creating a 10 Mb file"
19031        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19032        log "starting reads"
19033        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19034        log "truncating the file"
19035        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19036        log "killing dd"
19037        kill %+ || true # reads might have finished
19038        echo "wait until dd is finished"
19039        wait
19040        log "removing the temporary file"
19041        rm -rf $DIR/$tfile || error "tmp file removal failed"
19042 }
19043 run_test 218 "parallel read and truncate should not deadlock"
19044
19045 test_219() {
19046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19047
19048         # write one partial page
19049         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19050         # set no grant so vvp_io_commit_write will do sync write
19051         $LCTL set_param fail_loc=0x411
19052         # write a full page at the end of file
19053         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19054
19055         $LCTL set_param fail_loc=0
19056         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19057         $LCTL set_param fail_loc=0x411
19058         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19059
19060         # LU-4201
19061         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19062         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19063 }
19064 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19065
19066 test_220() { #LU-325
19067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19068         remote_ost_nodsh && skip "remote OST with nodsh"
19069         remote_mds_nodsh && skip "remote MDS with nodsh"
19070         remote_mgs_nodsh && skip "remote MGS with nodsh"
19071
19072         local OSTIDX=0
19073
19074         # create on MDT0000 so the last_id and next_id are correct
19075         mkdir_on_mdt0 $DIR/$tdir
19076         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19077         OST=${OST%_UUID}
19078
19079         # on the mdt's osc
19080         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19081         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19082                         osp.$mdtosc_proc1.prealloc_last_id)
19083         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19084                         osp.$mdtosc_proc1.prealloc_next_id)
19085
19086         $LFS df -i
19087
19088         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19089         #define OBD_FAIL_OST_ENOINO              0x229
19090         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19091         create_pool $FSNAME.$TESTNAME || return 1
19092         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19093
19094         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19095
19096         MDSOBJS=$((last_id - next_id))
19097         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19098
19099         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19100         echo "OST still has $count kbytes free"
19101
19102         echo "create $MDSOBJS files @next_id..."
19103         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19104
19105         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19106                         osp.$mdtosc_proc1.prealloc_last_id)
19107         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19108                         osp.$mdtosc_proc1.prealloc_next_id)
19109
19110         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19111         $LFS df -i
19112
19113         echo "cleanup..."
19114
19115         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19116         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19117
19118         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19119                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19120         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19121                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19122         echo "unlink $MDSOBJS files @$next_id..."
19123         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19124 }
19125 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19126
19127 test_221() {
19128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19129
19130         dd if=`which date` of=$MOUNT/date oflag=sync
19131         chmod +x $MOUNT/date
19132
19133         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19134         $LCTL set_param fail_loc=0x80001401
19135
19136         $MOUNT/date > /dev/null
19137         rm -f $MOUNT/date
19138 }
19139 run_test 221 "make sure fault and truncate race to not cause OOM"
19140
19141 test_222a () {
19142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19143
19144         rm -rf $DIR/$tdir
19145         test_mkdir $DIR/$tdir
19146         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19147         createmany -o $DIR/$tdir/$tfile 10
19148         cancel_lru_locks mdc
19149         cancel_lru_locks osc
19150         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19151         $LCTL set_param fail_loc=0x31a
19152         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19153         $LCTL set_param fail_loc=0
19154         rm -r $DIR/$tdir
19155 }
19156 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19157
19158 test_222b () {
19159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19160
19161         rm -rf $DIR/$tdir
19162         test_mkdir $DIR/$tdir
19163         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19164         createmany -o $DIR/$tdir/$tfile 10
19165         cancel_lru_locks mdc
19166         cancel_lru_locks osc
19167         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19168         $LCTL set_param fail_loc=0x31a
19169         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19170         $LCTL set_param fail_loc=0
19171 }
19172 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19173
19174 test_223 () {
19175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19176
19177         rm -rf $DIR/$tdir
19178         test_mkdir $DIR/$tdir
19179         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19180         createmany -o $DIR/$tdir/$tfile 10
19181         cancel_lru_locks mdc
19182         cancel_lru_locks osc
19183         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19184         $LCTL set_param fail_loc=0x31b
19185         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19186         $LCTL set_param fail_loc=0
19187         rm -r $DIR/$tdir
19188 }
19189 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19190
19191 test_224a() { # LU-1039, MRP-303
19192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19193         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19194         $LCTL set_param fail_loc=0x508
19195         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19196         $LCTL set_param fail_loc=0
19197         df $DIR
19198 }
19199 run_test 224a "Don't panic on bulk IO failure"
19200
19201 test_224bd_sub() { # LU-1039, MRP-303
19202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19203         local timeout=$1
19204
19205         shift
19206         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19207
19208         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19209
19210         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19211         cancel_lru_locks osc
19212         set_checksums 0
19213         stack_trap "set_checksums $ORIG_CSUM" EXIT
19214         local at_max_saved=0
19215
19216         # adaptive timeouts may prevent seeing the issue
19217         if at_is_enabled; then
19218                 at_max_saved=$(at_max_get mds)
19219                 at_max_set 0 mds client
19220                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19221         fi
19222
19223         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19224         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19225         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19226
19227         do_facet ost1 $LCTL set_param fail_loc=0
19228         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19229         df $DIR
19230 }
19231
19232 test_224b() {
19233         test_224bd_sub 3 error "dd failed"
19234 }
19235 run_test 224b "Don't panic on bulk IO failure"
19236
19237 test_224c() { # LU-6441
19238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19239         remote_mds_nodsh && skip "remote MDS with nodsh"
19240
19241         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19242         save_writethrough $p
19243         set_cache writethrough on
19244
19245         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19246         local at_max=$($LCTL get_param -n at_max)
19247         local timeout=$($LCTL get_param -n timeout)
19248         local test_at="at_max"
19249         local param_at="$FSNAME.sys.at_max"
19250         local test_timeout="timeout"
19251         local param_timeout="$FSNAME.sys.timeout"
19252
19253         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19254
19255         set_persistent_param_and_check client "$test_at" "$param_at" 0
19256         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19257
19258         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19259         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19260         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19261         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19262         sync
19263         do_facet ost1 "$LCTL set_param fail_loc=0"
19264
19265         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19266         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19267                 $timeout
19268
19269         $LCTL set_param -n $pages_per_rpc
19270         restore_lustre_params < $p
19271         rm -f $p
19272 }
19273 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19274
19275 test_224d() { # LU-11169
19276         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19277 }
19278 run_test 224d "Don't corrupt data on bulk IO timeout"
19279
19280 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19281 test_225a () {
19282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19283         if [ -z ${MDSSURVEY} ]; then
19284                 skip_env "mds-survey not found"
19285         fi
19286         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19287                 skip "Need MDS version at least 2.2.51"
19288
19289         local mds=$(facet_host $SINGLEMDS)
19290         local target=$(do_nodes $mds 'lctl dl' |
19291                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19292
19293         local cmd1="file_count=1000 thrhi=4"
19294         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19295         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19296         local cmd="$cmd1 $cmd2 $cmd3"
19297
19298         rm -f ${TMP}/mds_survey*
19299         echo + $cmd
19300         eval $cmd || error "mds-survey with zero-stripe failed"
19301         cat ${TMP}/mds_survey*
19302         rm -f ${TMP}/mds_survey*
19303 }
19304 run_test 225a "Metadata survey sanity with zero-stripe"
19305
19306 test_225b () {
19307         if [ -z ${MDSSURVEY} ]; then
19308                 skip_env "mds-survey not found"
19309         fi
19310         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19311                 skip "Need MDS version at least 2.2.51"
19312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19313         remote_mds_nodsh && skip "remote MDS with nodsh"
19314         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19315                 skip_env "Need to mount OST to test"
19316         fi
19317
19318         local mds=$(facet_host $SINGLEMDS)
19319         local target=$(do_nodes $mds 'lctl dl' |
19320                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19321
19322         local cmd1="file_count=1000 thrhi=4"
19323         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19324         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19325         local cmd="$cmd1 $cmd2 $cmd3"
19326
19327         rm -f ${TMP}/mds_survey*
19328         echo + $cmd
19329         eval $cmd || error "mds-survey with stripe_count failed"
19330         cat ${TMP}/mds_survey*
19331         rm -f ${TMP}/mds_survey*
19332 }
19333 run_test 225b "Metadata survey sanity with stripe_count = 1"
19334
19335 mcreate_path2fid () {
19336         local mode=$1
19337         local major=$2
19338         local minor=$3
19339         local name=$4
19340         local desc=$5
19341         local path=$DIR/$tdir/$name
19342         local fid
19343         local rc
19344         local fid_path
19345
19346         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19347                 error "cannot create $desc"
19348
19349         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19350         rc=$?
19351         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19352
19353         fid_path=$($LFS fid2path $MOUNT $fid)
19354         rc=$?
19355         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19356
19357         [ "$path" == "$fid_path" ] ||
19358                 error "fid2path returned $fid_path, expected $path"
19359
19360         echo "pass with $path and $fid"
19361 }
19362
19363 test_226a () {
19364         rm -rf $DIR/$tdir
19365         mkdir -p $DIR/$tdir
19366
19367         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19368         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19369         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19370         mcreate_path2fid 0040666 0 0 dir "directory"
19371         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19372         mcreate_path2fid 0100666 0 0 file "regular file"
19373         mcreate_path2fid 0120666 0 0 link "symbolic link"
19374         mcreate_path2fid 0140666 0 0 sock "socket"
19375 }
19376 run_test 226a "call path2fid and fid2path on files of all type"
19377
19378 test_226b () {
19379         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19380
19381         local MDTIDX=1
19382
19383         rm -rf $DIR/$tdir
19384         mkdir -p $DIR/$tdir
19385         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19386                 error "create remote directory failed"
19387         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19388         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19389                                 "character special file (null)"
19390         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19391                                 "character special file (no device)"
19392         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19393         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19394                                 "block special file (loop)"
19395         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19396         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19397         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19398 }
19399 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19400
19401 test_226c () {
19402         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19403         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19404                 skip "Need MDS version at least 2.13.55"
19405
19406         local submnt=/mnt/submnt
19407         local srcfile=/etc/passwd
19408         local dstfile=$submnt/passwd
19409         local path
19410         local fid
19411
19412         rm -rf $DIR/$tdir
19413         rm -rf $submnt
19414         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19415                 error "create remote directory failed"
19416         mkdir -p $submnt || error "create $submnt failed"
19417         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19418                 error "mount $submnt failed"
19419         stack_trap "umount $submnt" EXIT
19420
19421         cp $srcfile $dstfile
19422         fid=$($LFS path2fid $dstfile)
19423         path=$($LFS fid2path $submnt "$fid")
19424         [ "$path" = "$dstfile" ] ||
19425                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19426 }
19427 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19428
19429 # LU-1299 Executing or running ldd on a truncated executable does not
19430 # cause an out-of-memory condition.
19431 test_227() {
19432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19433         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19434
19435         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19436         chmod +x $MOUNT/date
19437
19438         $MOUNT/date > /dev/null
19439         ldd $MOUNT/date > /dev/null
19440         rm -f $MOUNT/date
19441 }
19442 run_test 227 "running truncated executable does not cause OOM"
19443
19444 # LU-1512 try to reuse idle OI blocks
19445 test_228a() {
19446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19447         remote_mds_nodsh && skip "remote MDS with nodsh"
19448         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19449
19450         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19451         local myDIR=$DIR/$tdir
19452
19453         mkdir -p $myDIR
19454         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19455         $LCTL set_param fail_loc=0x80001002
19456         createmany -o $myDIR/t- 10000
19457         $LCTL set_param fail_loc=0
19458         # The guard is current the largest FID holder
19459         touch $myDIR/guard
19460         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19461                     tr -d '[')
19462         local IDX=$(($SEQ % 64))
19463
19464         do_facet $SINGLEMDS sync
19465         # Make sure journal flushed.
19466         sleep 6
19467         local blk1=$(do_facet $SINGLEMDS \
19468                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19469                      grep Blockcount | awk '{print $4}')
19470
19471         # Remove old files, some OI blocks will become idle.
19472         unlinkmany $myDIR/t- 10000
19473         # Create new files, idle OI blocks should be reused.
19474         createmany -o $myDIR/t- 2000
19475         do_facet $SINGLEMDS sync
19476         # Make sure journal flushed.
19477         sleep 6
19478         local blk2=$(do_facet $SINGLEMDS \
19479                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19480                      grep Blockcount | awk '{print $4}')
19481
19482         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19483 }
19484 run_test 228a "try to reuse idle OI blocks"
19485
19486 test_228b() {
19487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19488         remote_mds_nodsh && skip "remote MDS with nodsh"
19489         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19490
19491         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19492         local myDIR=$DIR/$tdir
19493
19494         mkdir -p $myDIR
19495         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19496         $LCTL set_param fail_loc=0x80001002
19497         createmany -o $myDIR/t- 10000
19498         $LCTL set_param fail_loc=0
19499         # The guard is current the largest FID holder
19500         touch $myDIR/guard
19501         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19502                     tr -d '[')
19503         local IDX=$(($SEQ % 64))
19504
19505         do_facet $SINGLEMDS sync
19506         # Make sure journal flushed.
19507         sleep 6
19508         local blk1=$(do_facet $SINGLEMDS \
19509                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19510                      grep Blockcount | awk '{print $4}')
19511
19512         # Remove old files, some OI blocks will become idle.
19513         unlinkmany $myDIR/t- 10000
19514
19515         # stop the MDT
19516         stop $SINGLEMDS || error "Fail to stop MDT."
19517         # remount the MDT
19518         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
19519                 error "Fail to start MDT."
19520
19521         df $MOUNT || error "Fail to df."
19522         # Create new files, idle OI blocks should be reused.
19523         createmany -o $myDIR/t- 2000
19524         do_facet $SINGLEMDS sync
19525         # Make sure journal flushed.
19526         sleep 6
19527         local blk2=$(do_facet $SINGLEMDS \
19528                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19529                      grep Blockcount | awk '{print $4}')
19530
19531         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19532 }
19533 run_test 228b "idle OI blocks can be reused after MDT restart"
19534
19535 #LU-1881
19536 test_228c() {
19537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19538         remote_mds_nodsh && skip "remote MDS with nodsh"
19539         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19540
19541         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19542         local myDIR=$DIR/$tdir
19543
19544         mkdir -p $myDIR
19545         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19546         $LCTL set_param fail_loc=0x80001002
19547         # 20000 files can guarantee there are index nodes in the OI file
19548         createmany -o $myDIR/t- 20000
19549         $LCTL set_param fail_loc=0
19550         # The guard is current the largest FID holder
19551         touch $myDIR/guard
19552         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19553                     tr -d '[')
19554         local IDX=$(($SEQ % 64))
19555
19556         do_facet $SINGLEMDS sync
19557         # Make sure journal flushed.
19558         sleep 6
19559         local blk1=$(do_facet $SINGLEMDS \
19560                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19561                      grep Blockcount | awk '{print $4}')
19562
19563         # Remove old files, some OI blocks will become idle.
19564         unlinkmany $myDIR/t- 20000
19565         rm -f $myDIR/guard
19566         # The OI file should become empty now
19567
19568         # Create new files, idle OI blocks should be reused.
19569         createmany -o $myDIR/t- 2000
19570         do_facet $SINGLEMDS sync
19571         # Make sure journal flushed.
19572         sleep 6
19573         local blk2=$(do_facet $SINGLEMDS \
19574                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19575                      grep Blockcount | awk '{print $4}')
19576
19577         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19578 }
19579 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19580
19581 test_229() { # LU-2482, LU-3448
19582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19583         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19584         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19585                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19586
19587         rm -f $DIR/$tfile
19588
19589         # Create a file with a released layout and stripe count 2.
19590         $MULTIOP $DIR/$tfile H2c ||
19591                 error "failed to create file with released layout"
19592
19593         $LFS getstripe -v $DIR/$tfile
19594
19595         local pattern=$($LFS getstripe -L $DIR/$tfile)
19596         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19597
19598         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19599                 error "getstripe"
19600         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19601         stat $DIR/$tfile || error "failed to stat released file"
19602
19603         chown $RUNAS_ID $DIR/$tfile ||
19604                 error "chown $RUNAS_ID $DIR/$tfile failed"
19605
19606         chgrp $RUNAS_ID $DIR/$tfile ||
19607                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19608
19609         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19610         rm $DIR/$tfile || error "failed to remove released file"
19611 }
19612 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19613
19614 test_230a() {
19615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19616         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19617         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19618                 skip "Need MDS version at least 2.11.52"
19619
19620         local MDTIDX=1
19621
19622         test_mkdir $DIR/$tdir
19623         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19624         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19625         [ $mdt_idx -ne 0 ] &&
19626                 error "create local directory on wrong MDT $mdt_idx"
19627
19628         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19629                         error "create remote directory failed"
19630         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19631         [ $mdt_idx -ne $MDTIDX ] &&
19632                 error "create remote directory on wrong MDT $mdt_idx"
19633
19634         createmany -o $DIR/$tdir/test_230/t- 10 ||
19635                 error "create files on remote directory failed"
19636         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19637         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19638         rm -r $DIR/$tdir || error "unlink remote directory failed"
19639 }
19640 run_test 230a "Create remote directory and files under the remote directory"
19641
19642 test_230b() {
19643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19644         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19645         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19646                 skip "Need MDS version at least 2.11.52"
19647
19648         local MDTIDX=1
19649         local mdt_index
19650         local i
19651         local file
19652         local pid
19653         local stripe_count
19654         local migrate_dir=$DIR/$tdir/migrate_dir
19655         local other_dir=$DIR/$tdir/other_dir
19656
19657         test_mkdir $DIR/$tdir
19658         test_mkdir -i0 -c1 $migrate_dir
19659         test_mkdir -i0 -c1 $other_dir
19660         for ((i=0; i<10; i++)); do
19661                 mkdir -p $migrate_dir/dir_${i}
19662                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19663                         error "create files under remote dir failed $i"
19664         done
19665
19666         cp /etc/passwd $migrate_dir/$tfile
19667         cp /etc/passwd $other_dir/$tfile
19668         chattr +SAD $migrate_dir
19669         chattr +SAD $migrate_dir/$tfile
19670
19671         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19672         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19673         local old_dir_mode=$(stat -c%f $migrate_dir)
19674         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19675
19676         mkdir -p $migrate_dir/dir_default_stripe2
19677         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19678         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19679
19680         mkdir -p $other_dir
19681         ln $migrate_dir/$tfile $other_dir/luna
19682         ln $migrate_dir/$tfile $migrate_dir/sofia
19683         ln $other_dir/$tfile $migrate_dir/david
19684         ln -s $migrate_dir/$tfile $other_dir/zachary
19685         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19686         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19687
19688         local len
19689         local lnktgt
19690
19691         # inline symlink
19692         for len in 58 59 60; do
19693                 lnktgt=$(str_repeat 'l' $len)
19694                 touch $migrate_dir/$lnktgt
19695                 ln -s $lnktgt $migrate_dir/${len}char_ln
19696         done
19697
19698         # PATH_MAX
19699         for len in 4094 4095; do
19700                 lnktgt=$(str_repeat 'l' $len)
19701                 ln -s $lnktgt $migrate_dir/${len}char_ln
19702         done
19703
19704         # NAME_MAX
19705         for len in 254 255; do
19706                 touch $migrate_dir/$(str_repeat 'l' $len)
19707         done
19708
19709         $LFS migrate -m $MDTIDX $migrate_dir ||
19710                 error "fails on migrating remote dir to MDT1"
19711
19712         echo "migratate to MDT1, then checking.."
19713         for ((i = 0; i < 10; i++)); do
19714                 for file in $(find $migrate_dir/dir_${i}); do
19715                         mdt_index=$($LFS getstripe -m $file)
19716                         # broken symlink getstripe will fail
19717                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19718                                 error "$file is not on MDT${MDTIDX}"
19719                 done
19720         done
19721
19722         # the multiple link file should still in MDT0
19723         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19724         [ $mdt_index == 0 ] ||
19725                 error "$file is not on MDT${MDTIDX}"
19726
19727         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19728         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19729                 error " expect $old_dir_flag get $new_dir_flag"
19730
19731         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19732         [ "$old_file_flag" = "$new_file_flag" ] ||
19733                 error " expect $old_file_flag get $new_file_flag"
19734
19735         local new_dir_mode=$(stat -c%f $migrate_dir)
19736         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19737                 error "expect mode $old_dir_mode get $new_dir_mode"
19738
19739         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19740         [ "$old_file_mode" = "$new_file_mode" ] ||
19741                 error "expect mode $old_file_mode get $new_file_mode"
19742
19743         diff /etc/passwd $migrate_dir/$tfile ||
19744                 error "$tfile different after migration"
19745
19746         diff /etc/passwd $other_dir/luna ||
19747                 error "luna different after migration"
19748
19749         diff /etc/passwd $migrate_dir/sofia ||
19750                 error "sofia different after migration"
19751
19752         diff /etc/passwd $migrate_dir/david ||
19753                 error "david different after migration"
19754
19755         diff /etc/passwd $other_dir/zachary ||
19756                 error "zachary different after migration"
19757
19758         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19759                 error "${tfile}_ln different after migration"
19760
19761         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19762                 error "${tfile}_ln_other different after migration"
19763
19764         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19765         [ $stripe_count = 2 ] ||
19766                 error "dir strpe_count $d != 2 after migration."
19767
19768         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19769         [ $stripe_count = 2 ] ||
19770                 error "file strpe_count $d != 2 after migration."
19771
19772         #migrate back to MDT0
19773         MDTIDX=0
19774
19775         $LFS migrate -m $MDTIDX $migrate_dir ||
19776                 error "fails on migrating remote dir to MDT0"
19777
19778         echo "migrate back to MDT0, checking.."
19779         for file in $(find $migrate_dir); do
19780                 mdt_index=$($LFS getstripe -m $file)
19781                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19782                         error "$file is not on MDT${MDTIDX}"
19783         done
19784
19785         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19786         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19787                 error " expect $old_dir_flag get $new_dir_flag"
19788
19789         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19790         [ "$old_file_flag" = "$new_file_flag" ] ||
19791                 error " expect $old_file_flag get $new_file_flag"
19792
19793         local new_dir_mode=$(stat -c%f $migrate_dir)
19794         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19795                 error "expect mode $old_dir_mode get $new_dir_mode"
19796
19797         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19798         [ "$old_file_mode" = "$new_file_mode" ] ||
19799                 error "expect mode $old_file_mode get $new_file_mode"
19800
19801         diff /etc/passwd ${migrate_dir}/$tfile ||
19802                 error "$tfile different after migration"
19803
19804         diff /etc/passwd ${other_dir}/luna ||
19805                 error "luna different after migration"
19806
19807         diff /etc/passwd ${migrate_dir}/sofia ||
19808                 error "sofia different after migration"
19809
19810         diff /etc/passwd ${other_dir}/zachary ||
19811                 error "zachary different after migration"
19812
19813         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19814                 error "${tfile}_ln different after migration"
19815
19816         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19817                 error "${tfile}_ln_other different after migration"
19818
19819         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19820         [ $stripe_count = 2 ] ||
19821                 error "dir strpe_count $d != 2 after migration."
19822
19823         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19824         [ $stripe_count = 2 ] ||
19825                 error "file strpe_count $d != 2 after migration."
19826
19827         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19828 }
19829 run_test 230b "migrate directory"
19830
19831 test_230c() {
19832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19833         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19834         remote_mds_nodsh && skip "remote MDS with nodsh"
19835         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19836                 skip "Need MDS version at least 2.11.52"
19837
19838         local MDTIDX=1
19839         local total=3
19840         local mdt_index
19841         local file
19842         local migrate_dir=$DIR/$tdir/migrate_dir
19843
19844         #If migrating directory fails in the middle, all entries of
19845         #the directory is still accessiable.
19846         test_mkdir $DIR/$tdir
19847         test_mkdir -i0 -c1 $migrate_dir
19848         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19849         stat $migrate_dir
19850         createmany -o $migrate_dir/f $total ||
19851                 error "create files under ${migrate_dir} failed"
19852
19853         # fail after migrating top dir, and this will fail only once, so the
19854         # first sub file migration will fail (currently f3), others succeed.
19855         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19856         do_facet mds1 lctl set_param fail_loc=0x1801
19857         local t=$(ls $migrate_dir | wc -l)
19858         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19859                 error "migrate should fail"
19860         local u=$(ls $migrate_dir | wc -l)
19861         [ "$u" == "$t" ] || error "$u != $t during migration"
19862
19863         # add new dir/file should succeed
19864         mkdir $migrate_dir/dir ||
19865                 error "mkdir failed under migrating directory"
19866         touch $migrate_dir/file ||
19867                 error "create file failed under migrating directory"
19868
19869         # add file with existing name should fail
19870         for file in $migrate_dir/f*; do
19871                 stat $file > /dev/null || error "stat $file failed"
19872                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19873                         error "open(O_CREAT|O_EXCL) $file should fail"
19874                 $MULTIOP $file m && error "create $file should fail"
19875                 touch $DIR/$tdir/remote_dir/$tfile ||
19876                         error "touch $tfile failed"
19877                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19878                         error "link $file should fail"
19879                 mdt_index=$($LFS getstripe -m $file)
19880                 if [ $mdt_index == 0 ]; then
19881                         # file failed to migrate is not allowed to rename to
19882                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19883                                 error "rename to $file should fail"
19884                 else
19885                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19886                                 error "rename to $file failed"
19887                 fi
19888                 echo hello >> $file || error "write $file failed"
19889         done
19890
19891         # resume migration with different options should fail
19892         $LFS migrate -m 0 $migrate_dir &&
19893                 error "migrate -m 0 $migrate_dir should fail"
19894
19895         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19896                 error "migrate -c 2 $migrate_dir should fail"
19897
19898         # resume migration should succeed
19899         $LFS migrate -m $MDTIDX $migrate_dir ||
19900                 error "migrate $migrate_dir failed"
19901
19902         echo "Finish migration, then checking.."
19903         for file in $(find $migrate_dir); do
19904                 mdt_index=$($LFS getstripe -m $file)
19905                 [ $mdt_index == $MDTIDX ] ||
19906                         error "$file is not on MDT${MDTIDX}"
19907         done
19908
19909         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19910 }
19911 run_test 230c "check directory accessiblity if migration failed"
19912
19913 test_230d() {
19914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19915         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19916         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19917                 skip "Need MDS version at least 2.11.52"
19918         # LU-11235
19919         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19920
19921         local migrate_dir=$DIR/$tdir/migrate_dir
19922         local old_index
19923         local new_index
19924         local old_count
19925         local new_count
19926         local new_hash
19927         local mdt_index
19928         local i
19929         local j
19930
19931         old_index=$((RANDOM % MDSCOUNT))
19932         old_count=$((MDSCOUNT - old_index))
19933         new_index=$((RANDOM % MDSCOUNT))
19934         new_count=$((MDSCOUNT - new_index))
19935         new_hash=1 # for all_char
19936
19937         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19938         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19939
19940         test_mkdir $DIR/$tdir
19941         test_mkdir -i $old_index -c $old_count $migrate_dir
19942
19943         for ((i=0; i<100; i++)); do
19944                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19945                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19946                         error "create files under remote dir failed $i"
19947         done
19948
19949         echo -n "Migrate from MDT$old_index "
19950         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19951         echo -n "to MDT$new_index"
19952         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19953         echo
19954
19955         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19956         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19957                 error "migrate remote dir error"
19958
19959         echo "Finish migration, then checking.."
19960         for file in $(find $migrate_dir -maxdepth 1); do
19961                 mdt_index=$($LFS getstripe -m $file)
19962                 if [ $mdt_index -lt $new_index ] ||
19963                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19964                         error "$file is on MDT$mdt_index"
19965                 fi
19966         done
19967
19968         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19969 }
19970 run_test 230d "check migrate big directory"
19971
19972 test_230e() {
19973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19974         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19975         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19976                 skip "Need MDS version at least 2.11.52"
19977
19978         local i
19979         local j
19980         local a_fid
19981         local b_fid
19982
19983         mkdir_on_mdt0 $DIR/$tdir
19984         mkdir $DIR/$tdir/migrate_dir
19985         mkdir $DIR/$tdir/other_dir
19986         touch $DIR/$tdir/migrate_dir/a
19987         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19988         ls $DIR/$tdir/other_dir
19989
19990         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19991                 error "migrate dir fails"
19992
19993         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19994         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19995
19996         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19997         [ $mdt_index == 0 ] || error "a is not on MDT0"
19998
19999         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
20000                 error "migrate dir fails"
20001
20002         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
20003         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
20004
20005         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20006         [ $mdt_index == 1 ] || error "a is not on MDT1"
20007
20008         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
20009         [ $mdt_index == 1 ] || error "b is not on MDT1"
20010
20011         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20012         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
20013
20014         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
20015
20016         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20017 }
20018 run_test 230e "migrate mulitple local link files"
20019
20020 test_230f() {
20021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20022         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20023         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20024                 skip "Need MDS version at least 2.11.52"
20025
20026         local a_fid
20027         local ln_fid
20028
20029         mkdir -p $DIR/$tdir
20030         mkdir $DIR/$tdir/migrate_dir
20031         $LFS mkdir -i1 $DIR/$tdir/other_dir
20032         touch $DIR/$tdir/migrate_dir/a
20033         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20034         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20035         ls $DIR/$tdir/other_dir
20036
20037         # a should be migrated to MDT1, since no other links on MDT0
20038         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20039                 error "#1 migrate dir fails"
20040         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20041         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20042         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20043         [ $mdt_index == 1 ] || error "a is not on MDT1"
20044
20045         # a should stay on MDT1, because it is a mulitple link file
20046         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20047                 error "#2 migrate dir fails"
20048         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20049         [ $mdt_index == 1 ] || error "a is not on MDT1"
20050
20051         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20052                 error "#3 migrate dir fails"
20053
20054         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20055         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20056         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20057
20058         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20059         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20060
20061         # a should be migrated to MDT0, since no other links on MDT1
20062         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20063                 error "#4 migrate dir fails"
20064         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20065         [ $mdt_index == 0 ] || error "a is not on MDT0"
20066
20067         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20068 }
20069 run_test 230f "migrate mulitple remote link files"
20070
20071 test_230g() {
20072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20073         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20074         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20075                 skip "Need MDS version at least 2.11.52"
20076
20077         mkdir -p $DIR/$tdir/migrate_dir
20078
20079         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20080                 error "migrating dir to non-exist MDT succeeds"
20081         true
20082 }
20083 run_test 230g "migrate dir to non-exist MDT"
20084
20085 test_230h() {
20086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20087         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20088         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20089                 skip "Need MDS version at least 2.11.52"
20090
20091         local mdt_index
20092
20093         mkdir -p $DIR/$tdir/migrate_dir
20094
20095         $LFS migrate -m1 $DIR &&
20096                 error "migrating mountpoint1 should fail"
20097
20098         $LFS migrate -m1 $DIR/$tdir/.. &&
20099                 error "migrating mountpoint2 should fail"
20100
20101         # same as mv
20102         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20103                 error "migrating $tdir/migrate_dir/.. should fail"
20104
20105         true
20106 }
20107 run_test 230h "migrate .. and root"
20108
20109 test_230i() {
20110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20111         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20112         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20113                 skip "Need MDS version at least 2.11.52"
20114
20115         mkdir -p $DIR/$tdir/migrate_dir
20116
20117         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20118                 error "migration fails with a tailing slash"
20119
20120         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20121                 error "migration fails with two tailing slashes"
20122 }
20123 run_test 230i "lfs migrate -m tolerates trailing slashes"
20124
20125 test_230j() {
20126         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20127         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20128                 skip "Need MDS version at least 2.11.52"
20129
20130         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20131         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20132                 error "create $tfile failed"
20133         cat /etc/passwd > $DIR/$tdir/$tfile
20134
20135         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20136
20137         cmp /etc/passwd $DIR/$tdir/$tfile ||
20138                 error "DoM file mismatch after migration"
20139 }
20140 run_test 230j "DoM file data not changed after dir migration"
20141
20142 test_230k() {
20143         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20144         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20145                 skip "Need MDS version at least 2.11.56"
20146
20147         local total=20
20148         local files_on_starting_mdt=0
20149
20150         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20151         $LFS getdirstripe $DIR/$tdir
20152         for i in $(seq $total); do
20153                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20154                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20155                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20156         done
20157
20158         echo "$files_on_starting_mdt files on MDT0"
20159
20160         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20161         $LFS getdirstripe $DIR/$tdir
20162
20163         files_on_starting_mdt=0
20164         for i in $(seq $total); do
20165                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20166                         error "file $tfile.$i mismatch after migration"
20167                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20168                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20169         done
20170
20171         echo "$files_on_starting_mdt files on MDT1 after migration"
20172         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20173
20174         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20175         $LFS getdirstripe $DIR/$tdir
20176
20177         files_on_starting_mdt=0
20178         for i in $(seq $total); do
20179                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20180                         error "file $tfile.$i mismatch after 2nd migration"
20181                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20182                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20183         done
20184
20185         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20186         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20187
20188         true
20189 }
20190 run_test 230k "file data not changed after dir migration"
20191
20192 test_230l() {
20193         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20194         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20195                 skip "Need MDS version at least 2.11.56"
20196
20197         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20198         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20199                 error "create files under remote dir failed $i"
20200         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20201 }
20202 run_test 230l "readdir between MDTs won't crash"
20203
20204 test_230m() {
20205         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20206         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20207                 skip "Need MDS version at least 2.11.56"
20208
20209         local MDTIDX=1
20210         local mig_dir=$DIR/$tdir/migrate_dir
20211         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20212         local shortstr="b"
20213         local val
20214
20215         echo "Creating files and dirs with xattrs"
20216         test_mkdir $DIR/$tdir
20217         test_mkdir -i0 -c1 $mig_dir
20218         mkdir $mig_dir/dir
20219         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20220                 error "cannot set xattr attr1 on dir"
20221         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20222                 error "cannot set xattr attr2 on dir"
20223         touch $mig_dir/dir/f0
20224         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20225                 error "cannot set xattr attr1 on file"
20226         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20227                 error "cannot set xattr attr2 on file"
20228         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20229         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20230         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20231         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20232         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20233         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20234         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20235         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20236         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20237
20238         echo "Migrating to MDT1"
20239         $LFS migrate -m $MDTIDX $mig_dir ||
20240                 error "fails on migrating dir to MDT1"
20241
20242         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20243         echo "Checking xattrs"
20244         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20245         [ "$val" = $longstr ] ||
20246                 error "expecting xattr1 $longstr on dir, found $val"
20247         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20248         [ "$val" = $shortstr ] ||
20249                 error "expecting xattr2 $shortstr on dir, found $val"
20250         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20251         [ "$val" = $longstr ] ||
20252                 error "expecting xattr1 $longstr on file, found $val"
20253         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20254         [ "$val" = $shortstr ] ||
20255                 error "expecting xattr2 $shortstr on file, found $val"
20256 }
20257 run_test 230m "xattrs not changed after dir migration"
20258
20259 test_230n() {
20260         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20261         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20262                 skip "Need MDS version at least 2.13.53"
20263
20264         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20265         cat /etc/hosts > $DIR/$tdir/$tfile
20266         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20267         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20268
20269         cmp /etc/hosts $DIR/$tdir/$tfile ||
20270                 error "File data mismatch after migration"
20271 }
20272 run_test 230n "Dir migration with mirrored file"
20273
20274 test_230o() {
20275         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20276         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20277                 skip "Need MDS version at least 2.13.52"
20278
20279         local mdts=$(comma_list $(mdts_nodes))
20280         local timeout=100
20281         local restripe_status
20282         local delta
20283         local i
20284
20285         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20286
20287         # in case "crush" hash type is not set
20288         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20289
20290         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20291                            mdt.*MDT0000.enable_dir_restripe)
20292         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20293         stack_trap "do_nodes $mdts $LCTL set_param \
20294                     mdt.*.enable_dir_restripe=$restripe_status"
20295
20296         mkdir $DIR/$tdir
20297         createmany -m $DIR/$tdir/f 100 ||
20298                 error "create files under remote dir failed $i"
20299         createmany -d $DIR/$tdir/d 100 ||
20300                 error "create dirs under remote dir failed $i"
20301
20302         for i in $(seq 2 $MDSCOUNT); do
20303                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20304                 $LFS setdirstripe -c $i $DIR/$tdir ||
20305                         error "split -c $i $tdir failed"
20306                 wait_update $HOSTNAME \
20307                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20308                         error "dir split not finished"
20309                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20310                         awk '/migrate/ {sum += $2} END { print sum }')
20311                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20312                 # delta is around total_files/stripe_count
20313                 (( $delta < 200 / (i - 1) + 4 )) ||
20314                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20315         done
20316 }
20317 run_test 230o "dir split"
20318
20319 test_230p() {
20320         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20321         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20322                 skip "Need MDS version at least 2.13.52"
20323
20324         local mdts=$(comma_list $(mdts_nodes))
20325         local timeout=100
20326         local restripe_status
20327         local delta
20328         local c
20329
20330         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20331
20332         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20333
20334         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20335                            mdt.*MDT0000.enable_dir_restripe)
20336         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20337         stack_trap "do_nodes $mdts $LCTL set_param \
20338                     mdt.*.enable_dir_restripe=$restripe_status"
20339
20340         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20341         createmany -m $DIR/$tdir/f 100 ||
20342                 error "create files under remote dir failed"
20343         createmany -d $DIR/$tdir/d 100 ||
20344                 error "create dirs under remote dir failed"
20345
20346         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20347                 local mdt_hash="crush"
20348
20349                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20350                 $LFS setdirstripe -c $c $DIR/$tdir ||
20351                         error "split -c $c $tdir failed"
20352                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20353                         mdt_hash="$mdt_hash,fixed"
20354                 elif [ $c -eq 1 ]; then
20355                         mdt_hash="none"
20356                 fi
20357                 wait_update $HOSTNAME \
20358                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20359                         error "dir merge not finished"
20360                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20361                         awk '/migrate/ {sum += $2} END { print sum }')
20362                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20363                 # delta is around total_files/stripe_count
20364                 (( delta < 200 / c + 4 )) ||
20365                         error "$delta files migrated >= $((200 / c + 4))"
20366         done
20367 }
20368 run_test 230p "dir merge"
20369
20370 test_230q() {
20371         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20372         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20373                 skip "Need MDS version at least 2.13.52"
20374
20375         local mdts=$(comma_list $(mdts_nodes))
20376         local saved_threshold=$(do_facet mds1 \
20377                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20378         local saved_delta=$(do_facet mds1 \
20379                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20380         local threshold=100
20381         local delta=2
20382         local total=0
20383         local stripe_count=0
20384         local stripe_index
20385         local nr_files
20386         local create
20387
20388         # test with fewer files on ZFS
20389         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20390
20391         stack_trap "do_nodes $mdts $LCTL set_param \
20392                     mdt.*.dir_split_count=$saved_threshold"
20393         stack_trap "do_nodes $mdts $LCTL set_param \
20394                     mdt.*.dir_split_delta=$saved_delta"
20395         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20396         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20397         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20398         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20399         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20400         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20401
20402         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20403         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20404
20405         create=$((threshold * 3 / 2))
20406         while [ $stripe_count -lt $MDSCOUNT ]; do
20407                 createmany -m $DIR/$tdir/f $total $create ||
20408                         error "create sub files failed"
20409                 stat $DIR/$tdir > /dev/null
20410                 total=$((total + create))
20411                 stripe_count=$((stripe_count + delta))
20412                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20413
20414                 wait_update $HOSTNAME \
20415                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20416                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20417
20418                 wait_update $HOSTNAME \
20419                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20420                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20421
20422                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20423                 echo "$nr_files/$total files on MDT$stripe_index after split"
20424                 # allow 10% margin of imbalance with crush hash
20425                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20426                         error "$nr_files files on MDT$stripe_index after split"
20427
20428                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20429                 [ $nr_files -eq $total ] ||
20430                         error "total sub files $nr_files != $total"
20431         done
20432
20433         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20434
20435         echo "fixed layout directory won't auto split"
20436         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20437         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20438                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20439         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20440                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20441 }
20442 run_test 230q "dir auto split"
20443
20444 test_230r() {
20445         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20446         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20447         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20448                 skip "Need MDS version at least 2.13.54"
20449
20450         # maximum amount of local locks:
20451         # parent striped dir - 2 locks
20452         # new stripe in parent to migrate to - 1 lock
20453         # source and target - 2 locks
20454         # Total 5 locks for regular file
20455         mkdir -p $DIR/$tdir
20456         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20457         touch $DIR/$tdir/dir1/eee
20458
20459         # create 4 hardlink for 4 more locks
20460         # Total: 9 locks > RS_MAX_LOCKS (8)
20461         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20462         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20463         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20464         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20465         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20466         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20467         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20468         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20469
20470         cancel_lru_locks mdc
20471
20472         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20473                 error "migrate dir fails"
20474
20475         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20476 }
20477 run_test 230r "migrate with too many local locks"
20478
20479 test_230s() {
20480         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
20481                 skip "Need MDS version at least 2.14.52"
20482
20483         local mdts=$(comma_list $(mdts_nodes))
20484         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20485                                 mdt.*MDT0000.enable_dir_restripe)
20486
20487         stack_trap "do_nodes $mdts $LCTL set_param \
20488                     mdt.*.enable_dir_restripe=$restripe_status"
20489
20490         local st
20491         for st in 0 1; do
20492                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20493                 test_mkdir $DIR/$tdir
20494                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20495                         error "$LFS mkdir should return EEXIST if target exists"
20496                 rmdir $DIR/$tdir
20497         done
20498 }
20499 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20500
20501 test_230t()
20502 {
20503         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20504         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20505                 skip "Need MDS version at least 2.14.50"
20506
20507         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20508         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20509         $LFS project -p 1 -s $DIR/$tdir ||
20510                 error "set $tdir project id failed"
20511         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20512                 error "set subdir project id failed"
20513         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20514 }
20515 run_test 230t "migrate directory with project ID set"
20516
20517 test_230u()
20518 {
20519         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20520         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20521                 skip "Need MDS version at least 2.14.53"
20522
20523         local count
20524
20525         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20526         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20527         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20528         for i in $(seq 0 $((MDSCOUNT - 1))); do
20529                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20530                 echo "$count dirs migrated to MDT$i"
20531         done
20532         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20533         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20534 }
20535 run_test 230u "migrate directory by QOS"
20536
20537 test_230v()
20538 {
20539         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20540         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20541                 skip "Need MDS version at least 2.14.53"
20542
20543         local count
20544
20545         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20546         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20547         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20548         for i in $(seq 0 $((MDSCOUNT - 1))); do
20549                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20550                 echo "$count subdirs migrated to MDT$i"
20551                 (( i == 3 )) && (( count > 0 )) &&
20552                         error "subdir shouldn't be migrated to MDT3"
20553         done
20554         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20555         (( count == 3 )) || error "dirs migrated to $count MDTs"
20556 }
20557 run_test 230v "subdir migrated to the MDT where its parent is located"
20558
20559 test_230w() {
20560         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20561         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20562                 skip "Need MDS version at least 2.14.53"
20563
20564         mkdir -p $DIR/$tdir/sub || error "mkdir failed"
20565
20566         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
20567                 error "migrate failed"
20568
20569         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
20570                 error "$tdir stripe count mismatch"
20571
20572         (( $($LFS getdirstripe -c $DIR/$tdir/sub) == 0 )) ||
20573                 error "$tdir/sub is striped"
20574 }
20575 run_test 230w "non-recursive mode dir migration"
20576
20577 test_231a()
20578 {
20579         # For simplicity this test assumes that max_pages_per_rpc
20580         # is the same across all OSCs
20581         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20582         local bulk_size=$((max_pages * PAGE_SIZE))
20583         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20584                                        head -n 1)
20585
20586         mkdir -p $DIR/$tdir
20587         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20588                 error "failed to set stripe with -S ${brw_size}M option"
20589
20590         # clear the OSC stats
20591         $LCTL set_param osc.*.stats=0 &>/dev/null
20592         stop_writeback
20593
20594         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20595         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20596                 oflag=direct &>/dev/null || error "dd failed"
20597
20598         sync; sleep 1; sync # just to be safe
20599         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20600         if [ x$nrpcs != "x1" ]; then
20601                 $LCTL get_param osc.*.stats
20602                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20603         fi
20604
20605         start_writeback
20606         # Drop the OSC cache, otherwise we will read from it
20607         cancel_lru_locks osc
20608
20609         # clear the OSC stats
20610         $LCTL set_param osc.*.stats=0 &>/dev/null
20611
20612         # Client reads $bulk_size.
20613         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20614                 iflag=direct &>/dev/null || error "dd failed"
20615
20616         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20617         if [ x$nrpcs != "x1" ]; then
20618                 $LCTL get_param osc.*.stats
20619                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20620         fi
20621 }
20622 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20623
20624 test_231b() {
20625         mkdir -p $DIR/$tdir
20626         local i
20627         for i in {0..1023}; do
20628                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20629                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20630                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20631         done
20632         sync
20633 }
20634 run_test 231b "must not assert on fully utilized OST request buffer"
20635
20636 test_232a() {
20637         mkdir -p $DIR/$tdir
20638         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20639
20640         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20641         do_facet ost1 $LCTL set_param fail_loc=0x31c
20642
20643         # ignore dd failure
20644         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20645
20646         do_facet ost1 $LCTL set_param fail_loc=0
20647         umount_client $MOUNT || error "umount failed"
20648         mount_client $MOUNT || error "mount failed"
20649         stop ost1 || error "cannot stop ost1"
20650         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20651 }
20652 run_test 232a "failed lock should not block umount"
20653
20654 test_232b() {
20655         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20656                 skip "Need MDS version at least 2.10.58"
20657
20658         mkdir -p $DIR/$tdir
20659         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20660         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20661         sync
20662         cancel_lru_locks osc
20663
20664         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20665         do_facet ost1 $LCTL set_param fail_loc=0x31c
20666
20667         # ignore failure
20668         $LFS data_version $DIR/$tdir/$tfile || true
20669
20670         do_facet ost1 $LCTL set_param fail_loc=0
20671         umount_client $MOUNT || error "umount failed"
20672         mount_client $MOUNT || error "mount failed"
20673         stop ost1 || error "cannot stop ost1"
20674         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20675 }
20676 run_test 232b "failed data version lock should not block umount"
20677
20678 test_233a() {
20679         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20680                 skip "Need MDS version at least 2.3.64"
20681         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20682
20683         local fid=$($LFS path2fid $MOUNT)
20684
20685         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20686                 error "cannot access $MOUNT using its FID '$fid'"
20687 }
20688 run_test 233a "checking that OBF of the FS root succeeds"
20689
20690 test_233b() {
20691         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20692                 skip "Need MDS version at least 2.5.90"
20693         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20694
20695         local fid=$($LFS path2fid $MOUNT/.lustre)
20696
20697         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20698                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20699
20700         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20701         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20702                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20703 }
20704 run_test 233b "checking that OBF of the FS .lustre succeeds"
20705
20706 test_234() {
20707         local p="$TMP/sanityN-$TESTNAME.parameters"
20708         save_lustre_params client "llite.*.xattr_cache" > $p
20709         lctl set_param llite.*.xattr_cache 1 ||
20710                 skip_env "xattr cache is not supported"
20711
20712         mkdir -p $DIR/$tdir || error "mkdir failed"
20713         touch $DIR/$tdir/$tfile || error "touch failed"
20714         # OBD_FAIL_LLITE_XATTR_ENOMEM
20715         $LCTL set_param fail_loc=0x1405
20716         getfattr -n user.attr $DIR/$tdir/$tfile &&
20717                 error "getfattr should have failed with ENOMEM"
20718         $LCTL set_param fail_loc=0x0
20719         rm -rf $DIR/$tdir
20720
20721         restore_lustre_params < $p
20722         rm -f $p
20723 }
20724 run_test 234 "xattr cache should not crash on ENOMEM"
20725
20726 test_235() {
20727         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20728                 skip "Need MDS version at least 2.4.52"
20729
20730         flock_deadlock $DIR/$tfile
20731         local RC=$?
20732         case $RC in
20733                 0)
20734                 ;;
20735                 124) error "process hangs on a deadlock"
20736                 ;;
20737                 *) error "error executing flock_deadlock $DIR/$tfile"
20738                 ;;
20739         esac
20740 }
20741 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20742
20743 #LU-2935
20744 test_236() {
20745         check_swap_layouts_support
20746
20747         local ref1=/etc/passwd
20748         local ref2=/etc/group
20749         local file1=$DIR/$tdir/f1
20750         local file2=$DIR/$tdir/f2
20751
20752         test_mkdir -c1 $DIR/$tdir
20753         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20754         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20755         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20756         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20757         local fd=$(free_fd)
20758         local cmd="exec $fd<>$file2"
20759         eval $cmd
20760         rm $file2
20761         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20762                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20763         cmd="exec $fd>&-"
20764         eval $cmd
20765         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20766
20767         #cleanup
20768         rm -rf $DIR/$tdir
20769 }
20770 run_test 236 "Layout swap on open unlinked file"
20771
20772 # LU-4659 linkea consistency
20773 test_238() {
20774         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20775                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20776                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20777                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20778
20779         touch $DIR/$tfile
20780         ln $DIR/$tfile $DIR/$tfile.lnk
20781         touch $DIR/$tfile.new
20782         mv $DIR/$tfile.new $DIR/$tfile
20783         local fid1=$($LFS path2fid $DIR/$tfile)
20784         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20785         local path1=$($LFS fid2path $FSNAME "$fid1")
20786         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20787         local path2=$($LFS fid2path $FSNAME "$fid2")
20788         [ $tfile.lnk == $path2 ] ||
20789                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20790         rm -f $DIR/$tfile*
20791 }
20792 run_test 238 "Verify linkea consistency"
20793
20794 test_239A() { # was test_239
20795         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20796                 skip "Need MDS version at least 2.5.60"
20797
20798         local list=$(comma_list $(mdts_nodes))
20799
20800         mkdir -p $DIR/$tdir
20801         createmany -o $DIR/$tdir/f- 5000
20802         unlinkmany $DIR/$tdir/f- 5000
20803         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20804                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20805         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20806                         osp.*MDT*.sync_in_flight" | calc_sum)
20807         [ "$changes" -eq 0 ] || error "$changes not synced"
20808 }
20809 run_test 239A "osp_sync test"
20810
20811 test_239a() { #LU-5297
20812         remote_mds_nodsh && skip "remote MDS with nodsh"
20813
20814         touch $DIR/$tfile
20815         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20816         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20817         chgrp $RUNAS_GID $DIR/$tfile
20818         wait_delete_completed
20819 }
20820 run_test 239a "process invalid osp sync record correctly"
20821
20822 test_239b() { #LU-5297
20823         remote_mds_nodsh && skip "remote MDS with nodsh"
20824
20825         touch $DIR/$tfile1
20826         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20827         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20828         chgrp $RUNAS_GID $DIR/$tfile1
20829         wait_delete_completed
20830         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20831         touch $DIR/$tfile2
20832         chgrp $RUNAS_GID $DIR/$tfile2
20833         wait_delete_completed
20834 }
20835 run_test 239b "process osp sync record with ENOMEM error correctly"
20836
20837 test_240() {
20838         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20839         remote_mds_nodsh && skip "remote MDS with nodsh"
20840
20841         mkdir -p $DIR/$tdir
20842
20843         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20844                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20845         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20846                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20847
20848         umount_client $MOUNT || error "umount failed"
20849         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20850         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20851         mount_client $MOUNT || error "failed to mount client"
20852
20853         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20854         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20855 }
20856 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20857
20858 test_241_bio() {
20859         local count=$1
20860         local bsize=$2
20861
20862         for LOOP in $(seq $count); do
20863                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20864                 cancel_lru_locks $OSC || true
20865         done
20866 }
20867
20868 test_241_dio() {
20869         local count=$1
20870         local bsize=$2
20871
20872         for LOOP in $(seq $1); do
20873                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20874                         2>/dev/null
20875         done
20876 }
20877
20878 test_241a() { # was test_241
20879         local bsize=$PAGE_SIZE
20880
20881         (( bsize < 40960 )) && bsize=40960
20882         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20883         ls -la $DIR/$tfile
20884         cancel_lru_locks $OSC
20885         test_241_bio 1000 $bsize &
20886         PID=$!
20887         test_241_dio 1000 $bsize
20888         wait $PID
20889 }
20890 run_test 241a "bio vs dio"
20891
20892 test_241b() {
20893         local bsize=$PAGE_SIZE
20894
20895         (( bsize < 40960 )) && bsize=40960
20896         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20897         ls -la $DIR/$tfile
20898         test_241_dio 1000 $bsize &
20899         PID=$!
20900         test_241_dio 1000 $bsize
20901         wait $PID
20902 }
20903 run_test 241b "dio vs dio"
20904
20905 test_242() {
20906         remote_mds_nodsh && skip "remote MDS with nodsh"
20907
20908         mkdir_on_mdt0 $DIR/$tdir
20909         touch $DIR/$tdir/$tfile
20910
20911         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20912         do_facet mds1 lctl set_param fail_loc=0x105
20913         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20914
20915         do_facet mds1 lctl set_param fail_loc=0
20916         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20917 }
20918 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20919
20920 test_243()
20921 {
20922         test_mkdir $DIR/$tdir
20923         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20924 }
20925 run_test 243 "various group lock tests"
20926
20927 test_244a()
20928 {
20929         test_mkdir $DIR/$tdir
20930         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20931         sendfile_grouplock $DIR/$tdir/$tfile || \
20932                 error "sendfile+grouplock failed"
20933         rm -rf $DIR/$tdir
20934 }
20935 run_test 244a "sendfile with group lock tests"
20936
20937 test_244b()
20938 {
20939         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20940
20941         local threads=50
20942         local size=$((1024*1024))
20943
20944         test_mkdir $DIR/$tdir
20945         for i in $(seq 1 $threads); do
20946                 local file=$DIR/$tdir/file_$((i / 10))
20947                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20948                 local pids[$i]=$!
20949         done
20950         for i in $(seq 1 $threads); do
20951                 wait ${pids[$i]}
20952         done
20953 }
20954 run_test 244b "multi-threaded write with group lock"
20955
20956 test_245a() {
20957         local flagname="multi_mod_rpcs"
20958         local connect_data_name="max_mod_rpcs"
20959         local out
20960
20961         # check if multiple modify RPCs flag is set
20962         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20963                 grep "connect_flags:")
20964         echo "$out"
20965
20966         echo "$out" | grep -qw $flagname
20967         if [ $? -ne 0 ]; then
20968                 echo "connect flag $flagname is not set"
20969                 return
20970         fi
20971
20972         # check if multiple modify RPCs data is set
20973         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20974         echo "$out"
20975
20976         echo "$out" | grep -qw $connect_data_name ||
20977                 error "import should have connect data $connect_data_name"
20978 }
20979 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
20980
20981 test_245b() {
20982         local flagname="multi_mod_rpcs"
20983         local connect_data_name="max_mod_rpcs"
20984         local out
20985
20986         remote_mds_nodsh && skip "remote MDS with nodsh" && return
20987         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
20988
20989         # check if multiple modify RPCs flag is set
20990         out=$(do_facet mds1 \
20991                 $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
20992                 grep "connect_flags:")
20993         echo "$out"
20994
20995         if [[ "$out" =~ $flagname ]]; then
20996                 echo "connect flag $flagname is not set"
20997                 return 0
20998         fi
20999
21000         # check if multiple modify RPCs data is set
21001         out=$(do_facet mds1 \
21002                 $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
21003
21004         [[ "$out" =~ $connect_data_name ]] ||
21005                 error "import should have connect data $connect_data_name"
21006 }
21007 run_test 245b "check osp connection flag/data: multiple modify RPCs"
21008
21009 cleanup_247() {
21010         local submount=$1
21011
21012         trap 0
21013         umount_client $submount
21014         rmdir $submount
21015 }
21016
21017 test_247a() {
21018         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21019                 grep -q subtree ||
21020                 skip_env "Fileset feature is not supported"
21021
21022         local submount=${MOUNT}_$tdir
21023
21024         mkdir $MOUNT/$tdir
21025         mkdir -p $submount || error "mkdir $submount failed"
21026         FILESET="$FILESET/$tdir" mount_client $submount ||
21027                 error "mount $submount failed"
21028         trap "cleanup_247 $submount" EXIT
21029         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21030         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21031                 error "read $MOUNT/$tdir/$tfile failed"
21032         cleanup_247 $submount
21033 }
21034 run_test 247a "mount subdir as fileset"
21035
21036 test_247b() {
21037         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21038                 skip_env "Fileset feature is not supported"
21039
21040         local submount=${MOUNT}_$tdir
21041
21042         rm -rf $MOUNT/$tdir
21043         mkdir -p $submount || error "mkdir $submount failed"
21044         SKIP_FILESET=1
21045         FILESET="$FILESET/$tdir" mount_client $submount &&
21046                 error "mount $submount should fail"
21047         rmdir $submount
21048 }
21049 run_test 247b "mount subdir that dose not exist"
21050
21051 test_247c() {
21052         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21053                 skip_env "Fileset feature is not supported"
21054
21055         local submount=${MOUNT}_$tdir
21056
21057         mkdir -p $MOUNT/$tdir/dir1
21058         mkdir -p $submount || error "mkdir $submount failed"
21059         trap "cleanup_247 $submount" EXIT
21060         FILESET="$FILESET/$tdir" mount_client $submount ||
21061                 error "mount $submount failed"
21062         local fid=$($LFS path2fid $MOUNT/)
21063         $LFS fid2path $submount $fid && error "fid2path should fail"
21064         cleanup_247 $submount
21065 }
21066 run_test 247c "running fid2path outside subdirectory root"
21067
21068 test_247d() {
21069         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21070                 skip "Fileset feature is not supported"
21071
21072         local submount=${MOUNT}_$tdir
21073
21074         mkdir -p $MOUNT/$tdir/dir1
21075         mkdir -p $submount || error "mkdir $submount failed"
21076         FILESET="$FILESET/$tdir" mount_client $submount ||
21077                 error "mount $submount failed"
21078         trap "cleanup_247 $submount" EXIT
21079
21080         local td=$submount/dir1
21081         local fid=$($LFS path2fid $td)
21082         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21083
21084         # check that we get the same pathname back
21085         local rootpath
21086         local found
21087         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21088                 echo "$rootpath $fid"
21089                 found=$($LFS fid2path $rootpath "$fid")
21090                 [ -n "$found" ] || error "fid2path should succeed"
21091                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21092         done
21093         # check wrong root path format
21094         rootpath=$submount"_wrong"
21095         found=$($LFS fid2path $rootpath "$fid")
21096         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21097
21098         cleanup_247 $submount
21099 }
21100 run_test 247d "running fid2path inside subdirectory root"
21101
21102 # LU-8037
21103 test_247e() {
21104         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21105                 grep -q subtree ||
21106                 skip "Fileset feature is not supported"
21107
21108         local submount=${MOUNT}_$tdir
21109
21110         mkdir $MOUNT/$tdir
21111         mkdir -p $submount || error "mkdir $submount failed"
21112         FILESET="$FILESET/.." mount_client $submount &&
21113                 error "mount $submount should fail"
21114         rmdir $submount
21115 }
21116 run_test 247e "mount .. as fileset"
21117
21118 test_247f() {
21119         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21120         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21121                 skip "Need at least version 2.13.52"
21122         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21123                 skip "Need at least version 2.14.50"
21124         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21125                 grep -q subtree ||
21126                 skip "Fileset feature is not supported"
21127
21128         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21129         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21130                 error "mkdir remote failed"
21131         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21132                 error "mkdir remote/subdir failed"
21133         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21134                 error "mkdir striped failed"
21135         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21136
21137         local submount=${MOUNT}_$tdir
21138
21139         mkdir -p $submount || error "mkdir $submount failed"
21140         stack_trap "rmdir $submount"
21141
21142         local dir
21143         local stat
21144         local fileset=$FILESET
21145         local mdts=$(comma_list $(mdts_nodes))
21146
21147         stat=$(do_facet mds1 $LCTL get_param -n \
21148                 mdt.*MDT0000.enable_remote_subdir_mount)
21149         stack_trap "do_nodes $mdts $LCTL set_param \
21150                 mdt.*.enable_remote_subdir_mount=$stat"
21151
21152         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21153         stack_trap "umount_client $submount"
21154         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21155                 error "mount remote dir $dir should fail"
21156
21157         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21158                 $tdir/striped/. ; do
21159                 FILESET="$fileset/$dir" mount_client $submount ||
21160                         error "mount $dir failed"
21161                 umount_client $submount
21162         done
21163
21164         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21165         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21166                 error "mount $tdir/remote failed"
21167 }
21168 run_test 247f "mount striped or remote directory as fileset"
21169
21170 test_247g() {
21171         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21172         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21173                 skip "Need at least version 2.14.50"
21174
21175         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21176                 error "mkdir $tdir failed"
21177         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21178
21179         local submount=${MOUNT}_$tdir
21180
21181         mkdir -p $submount || error "mkdir $submount failed"
21182         stack_trap "rmdir $submount"
21183
21184         FILESET="$fileset/$tdir" mount_client $submount ||
21185                 error "mount $dir failed"
21186         stack_trap "umount $submount"
21187
21188         local mdts=$(comma_list $(mdts_nodes))
21189
21190         local nrpcs
21191
21192         stat $submount > /dev/null
21193         cancel_lru_locks $MDC
21194         stat $submount > /dev/null
21195         stat $submount/$tfile > /dev/null
21196         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21197         stat $submount/$tfile > /dev/null
21198         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21199                 awk '/getattr/ {sum += $2} END {print sum}')
21200
21201         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21202 }
21203 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21204
21205 test_248a() {
21206         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21207         [ -z "$fast_read_sav" ] && skip "no fast read support"
21208
21209         # create a large file for fast read verification
21210         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21211
21212         # make sure the file is created correctly
21213         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21214                 { rm -f $DIR/$tfile; skip "file creation error"; }
21215
21216         echo "Test 1: verify that fast read is 4 times faster on cache read"
21217
21218         # small read with fast read enabled
21219         $LCTL set_param -n llite.*.fast_read=1
21220         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21221                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21222                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21223         # small read with fast read disabled
21224         $LCTL set_param -n llite.*.fast_read=0
21225         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21226                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21227                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21228
21229         # verify that fast read is 4 times faster for cache read
21230         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21231                 error_not_in_vm "fast read was not 4 times faster: " \
21232                            "$t_fast vs $t_slow"
21233
21234         echo "Test 2: verify the performance between big and small read"
21235         $LCTL set_param -n llite.*.fast_read=1
21236
21237         # 1k non-cache read
21238         cancel_lru_locks osc
21239         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21240                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21241                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21242
21243         # 1M non-cache read
21244         cancel_lru_locks osc
21245         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21246                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21247                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21248
21249         # verify that big IO is not 4 times faster than small IO
21250         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21251                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21252
21253         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21254         rm -f $DIR/$tfile
21255 }
21256 run_test 248a "fast read verification"
21257
21258 test_248b() {
21259         # Default short_io_bytes=16384, try both smaller and larger sizes.
21260         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21261         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21262         echo "bs=53248 count=113 normal buffered write"
21263         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21264                 error "dd of initial data file failed"
21265         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21266
21267         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21268         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21269                 error "dd with sync normal writes failed"
21270         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21271
21272         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21273         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21274                 error "dd with sync small writes failed"
21275         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21276
21277         cancel_lru_locks osc
21278
21279         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21280         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21281         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21282         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21283                 iflag=direct || error "dd with O_DIRECT small read failed"
21284         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21285         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21286                 error "compare $TMP/$tfile.1 failed"
21287
21288         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21289         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21290
21291         # just to see what the maximum tunable value is, and test parsing
21292         echo "test invalid parameter 2MB"
21293         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21294                 error "too-large short_io_bytes allowed"
21295         echo "test maximum parameter 512KB"
21296         # if we can set a larger short_io_bytes, run test regardless of version
21297         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21298                 # older clients may not allow setting it this large, that's OK
21299                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21300                         skip "Need at least client version 2.13.50"
21301                 error "medium short_io_bytes failed"
21302         fi
21303         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21304         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21305
21306         echo "test large parameter 64KB"
21307         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21308         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21309
21310         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21311         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21312                 error "dd with sync large writes failed"
21313         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21314
21315         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21316         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21317         num=$((113 * 4096 / PAGE_SIZE))
21318         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21319         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21320                 error "dd with O_DIRECT large writes failed"
21321         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21322                 error "compare $DIR/$tfile.3 failed"
21323
21324         cancel_lru_locks osc
21325
21326         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21327         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21328                 error "dd with O_DIRECT large read failed"
21329         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21330                 error "compare $TMP/$tfile.2 failed"
21331
21332         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21333         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21334                 error "dd with O_DIRECT large read failed"
21335         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21336                 error "compare $TMP/$tfile.3 failed"
21337 }
21338 run_test 248b "test short_io read and write for both small and large sizes"
21339
21340 test_249() { # LU-7890
21341         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21342                 skip "Need at least version 2.8.54"
21343
21344         rm -f $DIR/$tfile
21345         $LFS setstripe -c 1 $DIR/$tfile
21346         # Offset 2T == 4k * 512M
21347         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21348                 error "dd to 2T offset failed"
21349 }
21350 run_test 249 "Write above 2T file size"
21351
21352 test_250() {
21353         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21354          && skip "no 16TB file size limit on ZFS"
21355
21356         $LFS setstripe -c 1 $DIR/$tfile
21357         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21358         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21359         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21360         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21361                 conv=notrunc,fsync && error "append succeeded"
21362         return 0
21363 }
21364 run_test 250 "Write above 16T limit"
21365
21366 test_251() {
21367         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21368
21369         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21370         #Skip once - writing the first stripe will succeed
21371         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21372         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21373                 error "short write happened"
21374
21375         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21376         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21377                 error "short read happened"
21378
21379         rm -f $DIR/$tfile
21380 }
21381 run_test 251 "Handling short read and write correctly"
21382
21383 test_252() {
21384         remote_mds_nodsh && skip "remote MDS with nodsh"
21385         remote_ost_nodsh && skip "remote OST with nodsh"
21386         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21387                 skip_env "ldiskfs only test"
21388         fi
21389
21390         local tgt
21391         local dev
21392         local out
21393         local uuid
21394         local num
21395         local gen
21396
21397         # check lr_reader on OST0000
21398         tgt=ost1
21399         dev=$(facet_device $tgt)
21400         out=$(do_facet $tgt $LR_READER $dev)
21401         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21402         echo "$out"
21403         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21404         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21405                 error "Invalid uuid returned by $LR_READER on target $tgt"
21406         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21407
21408         # check lr_reader -c on MDT0000
21409         tgt=mds1
21410         dev=$(facet_device $tgt)
21411         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21412                 skip "$LR_READER does not support additional options"
21413         fi
21414         out=$(do_facet $tgt $LR_READER -c $dev)
21415         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21416         echo "$out"
21417         num=$(echo "$out" | grep -c "mdtlov")
21418         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21419                 error "Invalid number of mdtlov clients returned by $LR_READER"
21420         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21421
21422         # check lr_reader -cr on MDT0000
21423         out=$(do_facet $tgt $LR_READER -cr $dev)
21424         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21425         echo "$out"
21426         echo "$out" | grep -q "^reply_data:$" ||
21427                 error "$LR_READER should have returned 'reply_data' section"
21428         num=$(echo "$out" | grep -c "client_generation")
21429         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21430 }
21431 run_test 252 "check lr_reader tool"
21432
21433 test_253() {
21434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21435         remote_mds_nodsh && skip "remote MDS with nodsh"
21436         remote_mgs_nodsh && skip "remote MGS with nodsh"
21437
21438         local ostidx=0
21439         local rc=0
21440         local ost_name=$(ostname_from_index $ostidx)
21441
21442         # on the mdt's osc
21443         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21444         do_facet $SINGLEMDS $LCTL get_param -n \
21445                 osp.$mdtosc_proc1.reserved_mb_high ||
21446                 skip  "remote MDS does not support reserved_mb_high"
21447
21448         rm -rf $DIR/$tdir
21449         wait_mds_ost_sync
21450         wait_delete_completed
21451         mkdir $DIR/$tdir
21452
21453         pool_add $TESTNAME || error "Pool creation failed"
21454         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21455
21456         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21457                 error "Setstripe failed"
21458
21459         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21460
21461         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21462                     grep "watermarks")
21463         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21464
21465         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21466                         osp.$mdtosc_proc1.prealloc_status)
21467         echo "prealloc_status $oa_status"
21468
21469         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21470                 error "File creation should fail"
21471
21472         #object allocation was stopped, but we still able to append files
21473         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21474                 oflag=append || error "Append failed"
21475
21476         rm -f $DIR/$tdir/$tfile.0
21477
21478         # For this test, we want to delete the files we created to go out of
21479         # space but leave the watermark, so we remain nearly out of space
21480         ost_watermarks_enospc_delete_files $tfile $ostidx
21481
21482         wait_delete_completed
21483
21484         sleep_maxage
21485
21486         for i in $(seq 10 12); do
21487                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21488                         2>/dev/null || error "File creation failed after rm"
21489         done
21490
21491         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21492                         osp.$mdtosc_proc1.prealloc_status)
21493         echo "prealloc_status $oa_status"
21494
21495         if (( oa_status != 0 )); then
21496                 error "Object allocation still disable after rm"
21497         fi
21498 }
21499 run_test 253 "Check object allocation limit"
21500
21501 test_254() {
21502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21503         remote_mds_nodsh && skip "remote MDS with nodsh"
21504
21505         local mdt=$(facet_svc $SINGLEMDS)
21506
21507         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21508                 skip "MDS does not support changelog_size"
21509
21510         local cl_user
21511
21512         changelog_register || error "changelog_register failed"
21513
21514         changelog_clear 0 || error "changelog_clear failed"
21515
21516         local size1=$(do_facet $SINGLEMDS \
21517                       $LCTL get_param -n mdd.$mdt.changelog_size)
21518         echo "Changelog size $size1"
21519
21520         rm -rf $DIR/$tdir
21521         $LFS mkdir -i 0 $DIR/$tdir
21522         # change something
21523         mkdir -p $DIR/$tdir/pics/2008/zachy
21524         touch $DIR/$tdir/pics/2008/zachy/timestamp
21525         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21526         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21527         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21528         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21529         rm $DIR/$tdir/pics/desktop.jpg
21530
21531         local size2=$(do_facet $SINGLEMDS \
21532                       $LCTL get_param -n mdd.$mdt.changelog_size)
21533         echo "Changelog size after work $size2"
21534
21535         (( $size2 > $size1 )) ||
21536                 error "new Changelog size=$size2 less than old size=$size1"
21537 }
21538 run_test 254 "Check changelog size"
21539
21540 ladvise_no_type()
21541 {
21542         local type=$1
21543         local file=$2
21544
21545         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21546                 awk -F: '{print $2}' | grep $type > /dev/null
21547         if [ $? -ne 0 ]; then
21548                 return 0
21549         fi
21550         return 1
21551 }
21552
21553 ladvise_no_ioctl()
21554 {
21555         local file=$1
21556
21557         lfs ladvise -a willread $file > /dev/null 2>&1
21558         if [ $? -eq 0 ]; then
21559                 return 1
21560         fi
21561
21562         lfs ladvise -a willread $file 2>&1 |
21563                 grep "Inappropriate ioctl for device" > /dev/null
21564         if [ $? -eq 0 ]; then
21565                 return 0
21566         fi
21567         return 1
21568 }
21569
21570 percent() {
21571         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21572 }
21573
21574 # run a random read IO workload
21575 # usage: random_read_iops <filename> <filesize> <iosize>
21576 random_read_iops() {
21577         local file=$1
21578         local fsize=$2
21579         local iosize=${3:-4096}
21580
21581         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21582                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21583 }
21584
21585 drop_file_oss_cache() {
21586         local file="$1"
21587         local nodes="$2"
21588
21589         $LFS ladvise -a dontneed $file 2>/dev/null ||
21590                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21591 }
21592
21593 ladvise_willread_performance()
21594 {
21595         local repeat=10
21596         local average_origin=0
21597         local average_cache=0
21598         local average_ladvise=0
21599
21600         for ((i = 1; i <= $repeat; i++)); do
21601                 echo "Iter $i/$repeat: reading without willread hint"
21602                 cancel_lru_locks osc
21603                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21604                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21605                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21606                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21607
21608                 cancel_lru_locks osc
21609                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21610                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21611                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21612
21613                 cancel_lru_locks osc
21614                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21615                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21616                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21617                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21618                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21619         done
21620         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21621         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21622         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21623
21624         speedup_cache=$(percent $average_cache $average_origin)
21625         speedup_ladvise=$(percent $average_ladvise $average_origin)
21626
21627         echo "Average uncached read: $average_origin"
21628         echo "Average speedup with OSS cached read: " \
21629                 "$average_cache = +$speedup_cache%"
21630         echo "Average speedup with ladvise willread: " \
21631                 "$average_ladvise = +$speedup_ladvise%"
21632
21633         local lowest_speedup=20
21634         if (( ${average_cache%.*} < $lowest_speedup )); then
21635                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
21636                      " got $average_cache%. Skipping ladvise willread check."
21637                 return 0
21638         fi
21639
21640         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21641         # it is still good to run until then to exercise 'ladvise willread'
21642         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21643                 [ "$ost1_FSTYPE" = "zfs" ] &&
21644                 echo "osd-zfs does not support dontneed or drop_caches" &&
21645                 return 0
21646
21647         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21648         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
21649                 error_not_in_vm "Speedup with willread is less than " \
21650                         "$lowest_speedup%, got $average_ladvise%"
21651 }
21652
21653 test_255a() {
21654         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21655                 skip "lustre < 2.8.54 does not support ladvise "
21656         remote_ost_nodsh && skip "remote OST with nodsh"
21657
21658         stack_trap "rm -f $DIR/$tfile"
21659         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21660
21661         ladvise_no_type willread $DIR/$tfile &&
21662                 skip "willread ladvise is not supported"
21663
21664         ladvise_no_ioctl $DIR/$tfile &&
21665                 skip "ladvise ioctl is not supported"
21666
21667         local size_mb=100
21668         local size=$((size_mb * 1048576))
21669         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21670                 error "dd to $DIR/$tfile failed"
21671
21672         lfs ladvise -a willread $DIR/$tfile ||
21673                 error "Ladvise failed with no range argument"
21674
21675         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21676                 error "Ladvise failed with no -l or -e argument"
21677
21678         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21679                 error "Ladvise failed with only -e argument"
21680
21681         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21682                 error "Ladvise failed with only -l argument"
21683
21684         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21685                 error "End offset should not be smaller than start offset"
21686
21687         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21688                 error "End offset should not be equal to start offset"
21689
21690         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21691                 error "Ladvise failed with overflowing -s argument"
21692
21693         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21694                 error "Ladvise failed with overflowing -e argument"
21695
21696         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21697                 error "Ladvise failed with overflowing -l argument"
21698
21699         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21700                 error "Ladvise succeeded with conflicting -l and -e arguments"
21701
21702         echo "Synchronous ladvise should wait"
21703         local delay=4
21704 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21705         do_nodes $(comma_list $(osts_nodes)) \
21706                 $LCTL set_param fail_val=$delay fail_loc=0x237
21707
21708         local start_ts=$SECONDS
21709         lfs ladvise -a willread $DIR/$tfile ||
21710                 error "Ladvise failed with no range argument"
21711         local end_ts=$SECONDS
21712         local inteval_ts=$((end_ts - start_ts))
21713
21714         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21715                 error "Synchronous advice didn't wait reply"
21716         fi
21717
21718         echo "Asynchronous ladvise shouldn't wait"
21719         local start_ts=$SECONDS
21720         lfs ladvise -a willread -b $DIR/$tfile ||
21721                 error "Ladvise failed with no range argument"
21722         local end_ts=$SECONDS
21723         local inteval_ts=$((end_ts - start_ts))
21724
21725         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21726                 error "Asynchronous advice blocked"
21727         fi
21728
21729         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21730         ladvise_willread_performance
21731 }
21732 run_test 255a "check 'lfs ladvise -a willread'"
21733
21734 facet_meminfo() {
21735         local facet=$1
21736         local info=$2
21737
21738         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21739 }
21740
21741 test_255b() {
21742         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21743                 skip "lustre < 2.8.54 does not support ladvise "
21744         remote_ost_nodsh && skip "remote OST with nodsh"
21745
21746         stack_trap "rm -f $DIR/$tfile"
21747         lfs setstripe -c 1 -i 0 $DIR/$tfile
21748
21749         ladvise_no_type dontneed $DIR/$tfile &&
21750                 skip "dontneed ladvise is not supported"
21751
21752         ladvise_no_ioctl $DIR/$tfile &&
21753                 skip "ladvise ioctl is not supported"
21754
21755         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21756                 [ "$ost1_FSTYPE" = "zfs" ] &&
21757                 skip "zfs-osd does not support 'ladvise dontneed'"
21758
21759         local size_mb=100
21760         local size=$((size_mb * 1048576))
21761         # In order to prevent disturbance of other processes, only check 3/4
21762         # of the memory usage
21763         local kibibytes=$((size_mb * 1024 * 3 / 4))
21764
21765         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21766                 error "dd to $DIR/$tfile failed"
21767
21768         #force write to complete before dropping OST cache & checking memory
21769         sync
21770
21771         local total=$(facet_meminfo ost1 MemTotal)
21772         echo "Total memory: $total KiB"
21773
21774         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21775         local before_read=$(facet_meminfo ost1 Cached)
21776         echo "Cache used before read: $before_read KiB"
21777
21778         lfs ladvise -a willread $DIR/$tfile ||
21779                 error "Ladvise willread failed"
21780         local after_read=$(facet_meminfo ost1 Cached)
21781         echo "Cache used after read: $after_read KiB"
21782
21783         lfs ladvise -a dontneed $DIR/$tfile ||
21784                 error "Ladvise dontneed again failed"
21785         local no_read=$(facet_meminfo ost1 Cached)
21786         echo "Cache used after dontneed ladvise: $no_read KiB"
21787
21788         if [ $total -lt $((before_read + kibibytes)) ]; then
21789                 echo "Memory is too small, abort checking"
21790                 return 0
21791         fi
21792
21793         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21794                 error "Ladvise willread should use more memory" \
21795                         "than $kibibytes KiB"
21796         fi
21797
21798         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21799                 error "Ladvise dontneed should release more memory" \
21800                         "than $kibibytes KiB"
21801         fi
21802 }
21803 run_test 255b "check 'lfs ladvise -a dontneed'"
21804
21805 test_255c() {
21806         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21807                 skip "lustre < 2.10.50 does not support lockahead"
21808
21809         local ost1_imp=$(get_osc_import_name client ost1)
21810         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21811                          cut -d'.' -f2)
21812         local count
21813         local new_count
21814         local difference
21815         local i
21816         local rc
21817
21818         test_mkdir -p $DIR/$tdir
21819         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21820
21821         #test 10 returns only success/failure
21822         i=10
21823         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21824         rc=$?
21825         if [ $rc -eq 255 ]; then
21826                 error "Ladvise test${i} failed, ${rc}"
21827         fi
21828
21829         #test 11 counts lock enqueue requests, all others count new locks
21830         i=11
21831         count=$(do_facet ost1 \
21832                 $LCTL get_param -n ost.OSS.ost.stats)
21833         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21834
21835         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21836         rc=$?
21837         if [ $rc -eq 255 ]; then
21838                 error "Ladvise test${i} failed, ${rc}"
21839         fi
21840
21841         new_count=$(do_facet ost1 \
21842                 $LCTL get_param -n ost.OSS.ost.stats)
21843         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21844                    awk '{ print $2 }')
21845
21846         difference="$((new_count - count))"
21847         if [ $difference -ne $rc ]; then
21848                 error "Ladvise test${i}, bad enqueue count, returned " \
21849                       "${rc}, actual ${difference}"
21850         fi
21851
21852         for i in $(seq 12 21); do
21853                 # If we do not do this, we run the risk of having too many
21854                 # locks and starting lock cancellation while we are checking
21855                 # lock counts.
21856                 cancel_lru_locks osc
21857
21858                 count=$($LCTL get_param -n \
21859                        ldlm.namespaces.$imp_name.lock_unused_count)
21860
21861                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21862                 rc=$?
21863                 if [ $rc -eq 255 ]; then
21864                         error "Ladvise test ${i} failed, ${rc}"
21865                 fi
21866
21867                 new_count=$($LCTL get_param -n \
21868                        ldlm.namespaces.$imp_name.lock_unused_count)
21869                 difference="$((new_count - count))"
21870
21871                 # Test 15 output is divided by 100 to map down to valid return
21872                 if [ $i -eq 15 ]; then
21873                         rc="$((rc * 100))"
21874                 fi
21875
21876                 if [ $difference -ne $rc ]; then
21877                         error "Ladvise test ${i}, bad lock count, returned " \
21878                               "${rc}, actual ${difference}"
21879                 fi
21880         done
21881
21882         #test 22 returns only success/failure
21883         i=22
21884         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21885         rc=$?
21886         if [ $rc -eq 255 ]; then
21887                 error "Ladvise test${i} failed, ${rc}"
21888         fi
21889 }
21890 run_test 255c "suite of ladvise lockahead tests"
21891
21892 test_256() {
21893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21894         remote_mds_nodsh && skip "remote MDS with nodsh"
21895         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21896         changelog_users $SINGLEMDS | grep "^cl" &&
21897                 skip "active changelog user"
21898
21899         local cl_user
21900         local cat_sl
21901         local mdt_dev
21902
21903         mdt_dev=$(facet_device $SINGLEMDS)
21904         echo $mdt_dev
21905
21906         changelog_register || error "changelog_register failed"
21907
21908         rm -rf $DIR/$tdir
21909         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
21910
21911         changelog_clear 0 || error "changelog_clear failed"
21912
21913         # change something
21914         touch $DIR/$tdir/{1..10}
21915
21916         # stop the MDT
21917         stop $SINGLEMDS || error "Fail to stop MDT"
21918
21919         # remount the MDT
21920         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21921                 error "Fail to start MDT"
21922
21923         #after mount new plainllog is used
21924         touch $DIR/$tdir/{11..19}
21925         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21926         stack_trap "rm -f $tmpfile"
21927         cat_sl=$(do_facet $SINGLEMDS "sync; \
21928                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21929                  llog_reader $tmpfile | grep -c type=1064553b")
21930         do_facet $SINGLEMDS llog_reader $tmpfile
21931
21932         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21933
21934         changelog_clear 0 || error "changelog_clear failed"
21935
21936         cat_sl=$(do_facet $SINGLEMDS "sync; \
21937                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21938                  llog_reader $tmpfile | grep -c type=1064553b")
21939
21940         if (( cat_sl == 2 )); then
21941                 error "Empty plain llog was not deleted from changelog catalog"
21942         elif (( cat_sl != 1 )); then
21943                 error "Active plain llog shouldn't be deleted from catalog"
21944         fi
21945 }
21946 run_test 256 "Check llog delete for empty and not full state"
21947
21948 test_257() {
21949         remote_mds_nodsh && skip "remote MDS with nodsh"
21950         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21951                 skip "Need MDS version at least 2.8.55"
21952
21953         test_mkdir $DIR/$tdir
21954
21955         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21956                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21957         stat $DIR/$tdir
21958
21959 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21960         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21961         local facet=mds$((mdtidx + 1))
21962         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21963         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21964
21965         stop $facet || error "stop MDS failed"
21966         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21967                 error "start MDS fail"
21968         wait_recovery_complete $facet
21969 }
21970 run_test 257 "xattr locks are not lost"
21971
21972 # Verify we take the i_mutex when security requires it
21973 test_258a() {
21974 #define OBD_FAIL_IMUTEX_SEC 0x141c
21975         $LCTL set_param fail_loc=0x141c
21976         touch $DIR/$tfile
21977         chmod u+s $DIR/$tfile
21978         chmod a+rwx $DIR/$tfile
21979         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21980         RC=$?
21981         if [ $RC -ne 0 ]; then
21982                 error "error, failed to take i_mutex, rc=$?"
21983         fi
21984         rm -f $DIR/$tfile
21985 }
21986 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21987
21988 # Verify we do NOT take the i_mutex in the normal case
21989 test_258b() {
21990 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21991         $LCTL set_param fail_loc=0x141d
21992         touch $DIR/$tfile
21993         chmod a+rwx $DIR
21994         chmod a+rw $DIR/$tfile
21995         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21996         RC=$?
21997         if [ $RC -ne 0 ]; then
21998                 error "error, took i_mutex unnecessarily, rc=$?"
21999         fi
22000         rm -f $DIR/$tfile
22001
22002 }
22003 run_test 258b "verify i_mutex security behavior"
22004
22005 test_259() {
22006         local file=$DIR/$tfile
22007         local before
22008         local after
22009
22010         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22011
22012         stack_trap "rm -f $file" EXIT
22013
22014         wait_delete_completed
22015         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22016         echo "before: $before"
22017
22018         $LFS setstripe -i 0 -c 1 $file
22019         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
22020         sync_all_data
22021         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22022         echo "after write: $after"
22023
22024 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22025         do_facet ost1 $LCTL set_param fail_loc=0x2301
22026         $TRUNCATE $file 0
22027         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22028         echo "after truncate: $after"
22029
22030         stop ost1
22031         do_facet ost1 $LCTL set_param fail_loc=0
22032         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22033         sleep 2
22034         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22035         echo "after restart: $after"
22036         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22037                 error "missing truncate?"
22038
22039         return 0
22040 }
22041 run_test 259 "crash at delayed truncate"
22042
22043 test_260() {
22044 #define OBD_FAIL_MDC_CLOSE               0x806
22045         $LCTL set_param fail_loc=0x80000806
22046         touch $DIR/$tfile
22047
22048 }
22049 run_test 260 "Check mdc_close fail"
22050
22051 ### Data-on-MDT sanity tests ###
22052 test_270a() {
22053         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22054                 skip "Need MDS version at least 2.10.55 for DoM"
22055
22056         # create DoM file
22057         local dom=$DIR/$tdir/dom_file
22058         local tmp=$DIR/$tdir/tmp_file
22059
22060         mkdir_on_mdt0 $DIR/$tdir
22061
22062         # basic checks for DoM component creation
22063         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22064                 error "Can set MDT layout to non-first entry"
22065
22066         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22067                 error "Can define multiple entries as MDT layout"
22068
22069         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22070
22071         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22072         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22073         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22074
22075         local mdtidx=$($LFS getstripe -m $dom)
22076         local mdtname=MDT$(printf %04x $mdtidx)
22077         local facet=mds$((mdtidx + 1))
22078         local space_check=1
22079
22080         # Skip free space checks with ZFS
22081         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22082
22083         # write
22084         sync
22085         local size_tmp=$((65536 * 3))
22086         local mdtfree1=$(do_facet $facet \
22087                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22088
22089         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22090         # check also direct IO along write
22091         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22092         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22093         sync
22094         cmp $tmp $dom || error "file data is different"
22095         [ $(stat -c%s $dom) == $size_tmp ] ||
22096                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22097         if [ $space_check == 1 ]; then
22098                 local mdtfree2=$(do_facet $facet \
22099                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22100
22101                 # increase in usage from by $size_tmp
22102                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22103                         error "MDT free space wrong after write: " \
22104                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22105         fi
22106
22107         # truncate
22108         local size_dom=10000
22109
22110         $TRUNCATE $dom $size_dom
22111         [ $(stat -c%s $dom) == $size_dom ] ||
22112                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22113         if [ $space_check == 1 ]; then
22114                 mdtfree1=$(do_facet $facet \
22115                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22116                 # decrease in usage from $size_tmp to new $size_dom
22117                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22118                   $(((size_tmp - size_dom) / 1024)) ] ||
22119                         error "MDT free space is wrong after truncate: " \
22120                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22121         fi
22122
22123         # append
22124         cat $tmp >> $dom
22125         sync
22126         size_dom=$((size_dom + size_tmp))
22127         [ $(stat -c%s $dom) == $size_dom ] ||
22128                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22129         if [ $space_check == 1 ]; then
22130                 mdtfree2=$(do_facet $facet \
22131                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22132                 # increase in usage by $size_tmp from previous
22133                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22134                         error "MDT free space is wrong after append: " \
22135                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22136         fi
22137
22138         # delete
22139         rm $dom
22140         if [ $space_check == 1 ]; then
22141                 mdtfree1=$(do_facet $facet \
22142                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22143                 # decrease in usage by $size_dom from previous
22144                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22145                         error "MDT free space is wrong after removal: " \
22146                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22147         fi
22148
22149         # combined striping
22150         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22151                 error "Can't create DoM + OST striping"
22152
22153         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22154         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22155         # check also direct IO along write
22156         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22157         sync
22158         cmp $tmp $dom || error "file data is different"
22159         [ $(stat -c%s $dom) == $size_tmp ] ||
22160                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22161         rm $dom $tmp
22162
22163         return 0
22164 }
22165 run_test 270a "DoM: basic functionality tests"
22166
22167 test_270b() {
22168         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22169                 skip "Need MDS version at least 2.10.55"
22170
22171         local dom=$DIR/$tdir/dom_file
22172         local max_size=1048576
22173
22174         mkdir -p $DIR/$tdir
22175         $LFS setstripe -E $max_size -L mdt $dom
22176
22177         # truncate over the limit
22178         $TRUNCATE $dom $(($max_size + 1)) &&
22179                 error "successful truncate over the maximum size"
22180         # write over the limit
22181         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22182                 error "successful write over the maximum size"
22183         # append over the limit
22184         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22185         echo "12345" >> $dom && error "successful append over the maximum size"
22186         rm $dom
22187
22188         return 0
22189 }
22190 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22191
22192 test_270c() {
22193         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22194                 skip "Need MDS version at least 2.10.55"
22195
22196         mkdir -p $DIR/$tdir
22197         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22198
22199         # check files inherit DoM EA
22200         touch $DIR/$tdir/first
22201         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22202                 error "bad pattern"
22203         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22204                 error "bad stripe count"
22205         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22206                 error "bad stripe size"
22207
22208         # check directory inherits DoM EA and uses it as default
22209         mkdir $DIR/$tdir/subdir
22210         touch $DIR/$tdir/subdir/second
22211         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22212                 error "bad pattern in sub-directory"
22213         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22214                 error "bad stripe count in sub-directory"
22215         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22216                 error "bad stripe size in sub-directory"
22217         return 0
22218 }
22219 run_test 270c "DoM: DoM EA inheritance tests"
22220
22221 test_270d() {
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
22226         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22227
22228         # inherit default DoM striping
22229         mkdir $DIR/$tdir/subdir
22230         touch $DIR/$tdir/subdir/f1
22231
22232         # change default directory striping
22233         $LFS setstripe -c 1 $DIR/$tdir/subdir
22234         touch $DIR/$tdir/subdir/f2
22235         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22236                 error "wrong default striping in file 2"
22237         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22238                 error "bad pattern in file 2"
22239         return 0
22240 }
22241 run_test 270d "DoM: change striping from DoM to RAID0"
22242
22243 test_270e() {
22244         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22245                 skip "Need MDS version at least 2.10.55"
22246
22247         mkdir -p $DIR/$tdir/dom
22248         mkdir -p $DIR/$tdir/norm
22249         DOMFILES=20
22250         NORMFILES=10
22251         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22252         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22253
22254         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22255         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22256
22257         # find DoM files by layout
22258         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22259         [ $NUM -eq  $DOMFILES ] ||
22260                 error "lfs find -L: found $NUM, expected $DOMFILES"
22261         echo "Test 1: lfs find 20 DOM files by layout: OK"
22262
22263         # there should be 1 dir with default DOM striping
22264         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22265         [ $NUM -eq  1 ] ||
22266                 error "lfs find -L: found $NUM, expected 1 dir"
22267         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22268
22269         # find DoM files by stripe size
22270         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22271         [ $NUM -eq  $DOMFILES ] ||
22272                 error "lfs find -S: found $NUM, expected $DOMFILES"
22273         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22274
22275         # find files by stripe offset except DoM files
22276         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22277         [ $NUM -eq  $NORMFILES ] ||
22278                 error "lfs find -i: found $NUM, expected $NORMFILES"
22279         echo "Test 5: lfs find no DOM files by stripe index: OK"
22280         return 0
22281 }
22282 run_test 270e "DoM: lfs find with DoM files test"
22283
22284 test_270f() {
22285         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22286                 skip "Need MDS version at least 2.10.55"
22287
22288         local mdtname=${FSNAME}-MDT0000-mdtlov
22289         local dom=$DIR/$tdir/dom_file
22290         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22291                                                 lod.$mdtname.dom_stripesize)
22292         local dom_limit=131072
22293
22294         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22295         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22296                                                 lod.$mdtname.dom_stripesize)
22297         [ ${dom_limit} -eq ${dom_current} ] ||
22298                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22299
22300         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22301         $LFS setstripe -d $DIR/$tdir
22302         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22303                 error "Can't set directory default striping"
22304
22305         # exceed maximum stripe size
22306         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22307                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22308         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22309                 error "Able to create DoM component size more than LOD limit"
22310
22311         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22312         dom_current=$(do_facet mds1 $LCTL get_param -n \
22313                                                 lod.$mdtname.dom_stripesize)
22314         [ 0 -eq ${dom_current} ] ||
22315                 error "Can't set zero DoM stripe limit"
22316         rm $dom
22317
22318         # attempt to create DoM file on server with disabled DoM should
22319         # remove DoM entry from layout and be succeed
22320         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22321                 error "Can't create DoM file (DoM is disabled)"
22322         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22323                 error "File has DoM component while DoM is disabled"
22324         rm $dom
22325
22326         # attempt to create DoM file with only DoM stripe should return error
22327         $LFS setstripe -E $dom_limit -L mdt $dom &&
22328                 error "Able to create DoM-only file while DoM is disabled"
22329
22330         # too low values to be aligned with smallest stripe size 64K
22331         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22332         dom_current=$(do_facet mds1 $LCTL get_param -n \
22333                                                 lod.$mdtname.dom_stripesize)
22334         [ 30000 -eq ${dom_current} ] &&
22335                 error "Can set too small DoM stripe limit"
22336
22337         # 64K is a minimal stripe size in Lustre, expect limit of that size
22338         [ 65536 -eq ${dom_current} ] ||
22339                 error "Limit is not set to 64K but ${dom_current}"
22340
22341         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22342         dom_current=$(do_facet mds1 $LCTL get_param -n \
22343                                                 lod.$mdtname.dom_stripesize)
22344         echo $dom_current
22345         [ 2147483648 -eq ${dom_current} ] &&
22346                 error "Can set too large DoM stripe limit"
22347
22348         do_facet mds1 $LCTL set_param -n \
22349                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22350         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22351                 error "Can't create DoM component size after limit change"
22352         do_facet mds1 $LCTL set_param -n \
22353                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22354         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22355                 error "Can't create DoM file after limit decrease"
22356         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22357                 error "Can create big DoM component after limit decrease"
22358         touch ${dom}_def ||
22359                 error "Can't create file with old default layout"
22360
22361         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22362         return 0
22363 }
22364 run_test 270f "DoM: maximum DoM stripe size checks"
22365
22366 test_270g() {
22367         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22368                 skip "Need MDS version at least 2.13.52"
22369         local dom=$DIR/$tdir/$tfile
22370
22371         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22372         local lodname=${FSNAME}-MDT0000-mdtlov
22373
22374         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22375         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22376         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22377         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22378
22379         local dom_limit=1024
22380         local dom_threshold="50%"
22381
22382         $LFS setstripe -d $DIR/$tdir
22383         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22384                 error "Can't set directory default striping"
22385
22386         do_facet mds1 $LCTL set_param -n \
22387                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22388         # set 0 threshold and create DOM file to change tunable stripesize
22389         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22390         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22391                 error "Failed to create $dom file"
22392         # now tunable dom_cur_stripesize should reach maximum
22393         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22394                                         lod.${lodname}.dom_stripesize_cur_kb)
22395         [[ $dom_current == $dom_limit ]] ||
22396                 error "Current DOM stripesize is not maximum"
22397         rm $dom
22398
22399         # set threshold for further tests
22400         do_facet mds1 $LCTL set_param -n \
22401                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22402         echo "DOM threshold is $dom_threshold free space"
22403         local dom_def
22404         local dom_set
22405         # Spoof bfree to exceed threshold
22406         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22407         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22408         for spfree in 40 20 0 15 30 55; do
22409                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22410                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22411                         error "Failed to create $dom file"
22412                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22413                                         lod.${lodname}.dom_stripesize_cur_kb)
22414                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22415                 [[ $dom_def != $dom_current ]] ||
22416                         error "Default stripe size was not changed"
22417                 if (( spfree > 0 )) ; then
22418                         dom_set=$($LFS getstripe -S $dom)
22419                         (( dom_set == dom_def * 1024 )) ||
22420                                 error "DOM component size is still old"
22421                 else
22422                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22423                                 error "DoM component is set with no free space"
22424                 fi
22425                 rm $dom
22426                 dom_current=$dom_def
22427         done
22428 }
22429 run_test 270g "DoM: default DoM stripe size depends on free space"
22430
22431 test_270h() {
22432         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22433                 skip "Need MDS version at least 2.13.53"
22434
22435         local mdtname=${FSNAME}-MDT0000-mdtlov
22436         local dom=$DIR/$tdir/$tfile
22437         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22438
22439         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22440         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22441
22442         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22443         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22444                 error "can't create OST file"
22445         # mirrored file with DOM entry in the second mirror
22446         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22447                 error "can't create mirror with DoM component"
22448
22449         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22450
22451         # DOM component in the middle and has other enries in the same mirror,
22452         # should succeed but lost DoM component
22453         $LFS setstripe --copy=${dom}_1 $dom ||
22454                 error "Can't create file from OST|DOM mirror layout"
22455         # check new file has no DoM layout after all
22456         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22457                 error "File has DoM component while DoM is disabled"
22458 }
22459 run_test 270h "DoM: DoM stripe removal when disabled on server"
22460
22461 test_270i() {
22462         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22463                 skip "Need MDS version at least 2.14.54"
22464
22465         mkdir $DIR/$tdir
22466         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22467                 error "setstripe should fail" || true
22468 }
22469 run_test 270i "DoM: setting invalid DoM striping should fail"
22470
22471 test_271a() {
22472         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22473                 skip "Need MDS version at least 2.10.55"
22474
22475         local dom=$DIR/$tdir/dom
22476
22477         mkdir -p $DIR/$tdir
22478
22479         $LFS setstripe -E 1024K -L mdt $dom
22480
22481         lctl set_param -n mdc.*.stats=clear
22482         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22483         cat $dom > /dev/null
22484         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22485         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22486         ls $dom
22487         rm -f $dom
22488 }
22489 run_test 271a "DoM: data is cached for read after write"
22490
22491 test_271b() {
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         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22503         cancel_lru_locks mdc
22504         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22505         # second stat to check size is cached on client
22506         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22507         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22508         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22509         rm -f $dom
22510 }
22511 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22512
22513 test_271ba() {
22514         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22515                 skip "Need MDS version at least 2.10.55"
22516
22517         local dom=$DIR/$tdir/dom
22518
22519         mkdir -p $DIR/$tdir
22520
22521         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22522
22523         lctl set_param -n mdc.*.stats=clear
22524         lctl set_param -n osc.*.stats=clear
22525         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22526         cancel_lru_locks mdc
22527         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22528         # second stat to check size is cached on client
22529         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22530         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22531         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22532         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22533         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22534         rm -f $dom
22535 }
22536 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22537
22538
22539 get_mdc_stats() {
22540         local mdtidx=$1
22541         local param=$2
22542         local mdt=MDT$(printf %04x $mdtidx)
22543
22544         if [ -z $param ]; then
22545                 lctl get_param -n mdc.*$mdt*.stats
22546         else
22547                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22548         fi
22549 }
22550
22551 test_271c() {
22552         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22553                 skip "Need MDS version at least 2.10.55"
22554
22555         local dom=$DIR/$tdir/dom
22556
22557         mkdir -p $DIR/$tdir
22558
22559         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22560
22561         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22562         local facet=mds$((mdtidx + 1))
22563
22564         cancel_lru_locks mdc
22565         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22566         createmany -o $dom 1000
22567         lctl set_param -n mdc.*.stats=clear
22568         smalliomany -w $dom 1000 200
22569         get_mdc_stats $mdtidx
22570         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22571         # Each file has 1 open, 1 IO enqueues, total 2000
22572         # but now we have also +1 getxattr for security.capability, total 3000
22573         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22574         unlinkmany $dom 1000
22575
22576         cancel_lru_locks mdc
22577         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22578         createmany -o $dom 1000
22579         lctl set_param -n mdc.*.stats=clear
22580         smalliomany -w $dom 1000 200
22581         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22582         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22583         # for OPEN and IO lock.
22584         [ $((enq - enq_2)) -ge 1000 ] ||
22585                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22586         unlinkmany $dom 1000
22587         return 0
22588 }
22589 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22590
22591 cleanup_271def_tests() {
22592         trap 0
22593         rm -f $1
22594 }
22595
22596 test_271d() {
22597         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22598                 skip "Need MDS version at least 2.10.57"
22599
22600         local dom=$DIR/$tdir/dom
22601         local tmp=$TMP/$tfile
22602         trap "cleanup_271def_tests $tmp" EXIT
22603
22604         mkdir -p $DIR/$tdir
22605
22606         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22607
22608         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22609
22610         cancel_lru_locks mdc
22611         dd if=/dev/urandom of=$tmp bs=1000 count=1
22612         dd if=$tmp of=$dom bs=1000 count=1
22613         cancel_lru_locks mdc
22614
22615         cat /etc/hosts >> $tmp
22616         lctl set_param -n mdc.*.stats=clear
22617
22618         # append data to the same file it should update local page
22619         echo "Append to the same page"
22620         cat /etc/hosts >> $dom
22621         local num=$(get_mdc_stats $mdtidx ost_read)
22622         local ra=$(get_mdc_stats $mdtidx req_active)
22623         local rw=$(get_mdc_stats $mdtidx req_waittime)
22624
22625         [ -z $num ] || error "$num READ RPC occured"
22626         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22627         echo "... DONE"
22628
22629         # compare content
22630         cmp $tmp $dom || error "file miscompare"
22631
22632         cancel_lru_locks mdc
22633         lctl set_param -n mdc.*.stats=clear
22634
22635         echo "Open and read file"
22636         cat $dom > /dev/null
22637         local num=$(get_mdc_stats $mdtidx ost_read)
22638         local ra=$(get_mdc_stats $mdtidx req_active)
22639         local rw=$(get_mdc_stats $mdtidx req_waittime)
22640
22641         [ -z $num ] || error "$num READ RPC occured"
22642         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22643         echo "... DONE"
22644
22645         # compare content
22646         cmp $tmp $dom || error "file miscompare"
22647
22648         return 0
22649 }
22650 run_test 271d "DoM: read on open (1K file in reply buffer)"
22651
22652 test_271f() {
22653         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22654                 skip "Need MDS version at least 2.10.57"
22655
22656         local dom=$DIR/$tdir/dom
22657         local tmp=$TMP/$tfile
22658         trap "cleanup_271def_tests $tmp" EXIT
22659
22660         mkdir -p $DIR/$tdir
22661
22662         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22663
22664         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22665
22666         cancel_lru_locks mdc
22667         dd if=/dev/urandom of=$tmp bs=265000 count=1
22668         dd if=$tmp of=$dom bs=265000 count=1
22669         cancel_lru_locks mdc
22670         cat /etc/hosts >> $tmp
22671         lctl set_param -n mdc.*.stats=clear
22672
22673         echo "Append to the same page"
22674         cat /etc/hosts >> $dom
22675         local num=$(get_mdc_stats $mdtidx ost_read)
22676         local ra=$(get_mdc_stats $mdtidx req_active)
22677         local rw=$(get_mdc_stats $mdtidx req_waittime)
22678
22679         [ -z $num ] || error "$num READ RPC occured"
22680         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22681         echo "... DONE"
22682
22683         # compare content
22684         cmp $tmp $dom || error "file miscompare"
22685
22686         cancel_lru_locks mdc
22687         lctl set_param -n mdc.*.stats=clear
22688
22689         echo "Open and read file"
22690         cat $dom > /dev/null
22691         local num=$(get_mdc_stats $mdtidx ost_read)
22692         local ra=$(get_mdc_stats $mdtidx req_active)
22693         local rw=$(get_mdc_stats $mdtidx req_waittime)
22694
22695         [ -z $num ] && num=0
22696         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22697         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22698         echo "... DONE"
22699
22700         # compare content
22701         cmp $tmp $dom || error "file miscompare"
22702
22703         return 0
22704 }
22705 run_test 271f "DoM: read on open (200K file and read tail)"
22706
22707 test_271g() {
22708         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22709                 skip "Skipping due to old client or server version"
22710
22711         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22712         # to get layout
22713         $CHECKSTAT -t file $DIR1/$tfile
22714
22715         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22716         MULTIOP_PID=$!
22717         sleep 1
22718         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22719         $LCTL set_param fail_loc=0x80000314
22720         rm $DIR1/$tfile || error "Unlink fails"
22721         RC=$?
22722         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22723         [ $RC -eq 0 ] || error "Failed write to stale object"
22724 }
22725 run_test 271g "Discard DoM data vs client flush race"
22726
22727 test_272a() {
22728         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22729                 skip "Need MDS version at least 2.11.50"
22730
22731         local dom=$DIR/$tdir/dom
22732         mkdir -p $DIR/$tdir
22733
22734         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22735         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22736                 error "failed to write data into $dom"
22737         local old_md5=$(md5sum $dom)
22738
22739         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22740                 error "failed to migrate to the same DoM component"
22741
22742         local new_md5=$(md5sum $dom)
22743
22744         [ "$old_md5" == "$new_md5" ] ||
22745                 error "md5sum differ: $old_md5, $new_md5"
22746
22747         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22748                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22749 }
22750 run_test 272a "DoM migration: new layout with the same DOM component"
22751
22752 test_272b() {
22753         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22754                 skip "Need MDS version at least 2.11.50"
22755
22756         local dom=$DIR/$tdir/dom
22757         mkdir -p $DIR/$tdir
22758         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22759
22760         local mdtidx=$($LFS getstripe -m $dom)
22761         local mdtname=MDT$(printf %04x $mdtidx)
22762         local facet=mds$((mdtidx + 1))
22763
22764         local mdtfree1=$(do_facet $facet \
22765                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22766         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22767                 error "failed to write data into $dom"
22768         local old_md5=$(md5sum $dom)
22769         cancel_lru_locks mdc
22770         local mdtfree1=$(do_facet $facet \
22771                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22772
22773         $LFS migrate -c2 $dom ||
22774                 error "failed to migrate to the new composite layout"
22775         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22776                 error "MDT stripe was not removed"
22777
22778         cancel_lru_locks mdc
22779         local new_md5=$(md5sum $dom)
22780         [ "$old_md5" == "$new_md5" ] ||
22781                 error "$old_md5 != $new_md5"
22782
22783         # Skip free space checks with ZFS
22784         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22785                 local mdtfree2=$(do_facet $facet \
22786                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22787                 [ $mdtfree2 -gt $mdtfree1 ] ||
22788                         error "MDT space is not freed after migration"
22789         fi
22790         return 0
22791 }
22792 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22793
22794 test_272c() {
22795         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22796                 skip "Need MDS version at least 2.11.50"
22797
22798         local dom=$DIR/$tdir/$tfile
22799         mkdir -p $DIR/$tdir
22800         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22801
22802         local mdtidx=$($LFS getstripe -m $dom)
22803         local mdtname=MDT$(printf %04x $mdtidx)
22804         local facet=mds$((mdtidx + 1))
22805
22806         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22807                 error "failed to write data into $dom"
22808         local old_md5=$(md5sum $dom)
22809         cancel_lru_locks mdc
22810         local mdtfree1=$(do_facet $facet \
22811                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22812
22813         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22814                 error "failed to migrate to the new composite layout"
22815         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22816                 error "MDT stripe was not removed"
22817
22818         cancel_lru_locks mdc
22819         local new_md5=$(md5sum $dom)
22820         [ "$old_md5" == "$new_md5" ] ||
22821                 error "$old_md5 != $new_md5"
22822
22823         # Skip free space checks with ZFS
22824         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22825                 local mdtfree2=$(do_facet $facet \
22826                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22827                 [ $mdtfree2 -gt $mdtfree1 ] ||
22828                         error "MDS space is not freed after migration"
22829         fi
22830         return 0
22831 }
22832 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22833
22834 test_272d() {
22835         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22836                 skip "Need MDS version at least 2.12.55"
22837
22838         local dom=$DIR/$tdir/$tfile
22839         mkdir -p $DIR/$tdir
22840         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22841
22842         local mdtidx=$($LFS getstripe -m $dom)
22843         local mdtname=MDT$(printf %04x $mdtidx)
22844         local facet=mds$((mdtidx + 1))
22845
22846         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22847                 error "failed to write data into $dom"
22848         local old_md5=$(md5sum $dom)
22849         cancel_lru_locks mdc
22850         local mdtfree1=$(do_facet $facet \
22851                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22852
22853         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22854                 error "failed mirroring to the new composite layout"
22855         $LFS mirror resync $dom ||
22856                 error "failed mirror resync"
22857         $LFS mirror split --mirror-id 1 -d $dom ||
22858                 error "failed mirror split"
22859
22860         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22861                 error "MDT stripe was not removed"
22862
22863         cancel_lru_locks mdc
22864         local new_md5=$(md5sum $dom)
22865         [ "$old_md5" == "$new_md5" ] ||
22866                 error "$old_md5 != $new_md5"
22867
22868         # Skip free space checks with ZFS
22869         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22870                 local mdtfree2=$(do_facet $facet \
22871                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22872                 [ $mdtfree2 -gt $mdtfree1 ] ||
22873                         error "MDS space is not freed after DOM mirror deletion"
22874         fi
22875         return 0
22876 }
22877 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22878
22879 test_272e() {
22880         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22881                 skip "Need MDS version at least 2.12.55"
22882
22883         local dom=$DIR/$tdir/$tfile
22884         mkdir -p $DIR/$tdir
22885         $LFS setstripe -c 2 $dom
22886
22887         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22888                 error "failed to write data into $dom"
22889         local old_md5=$(md5sum $dom)
22890         cancel_lru_locks
22891
22892         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22893                 error "failed mirroring to the DOM layout"
22894         $LFS mirror resync $dom ||
22895                 error "failed mirror resync"
22896         $LFS mirror split --mirror-id 1 -d $dom ||
22897                 error "failed mirror split"
22898
22899         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22900                 error "MDT stripe wasn't set"
22901
22902         cancel_lru_locks
22903         local new_md5=$(md5sum $dom)
22904         [ "$old_md5" == "$new_md5" ] ||
22905                 error "$old_md5 != $new_md5"
22906
22907         return 0
22908 }
22909 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22910
22911 test_272f() {
22912         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22913                 skip "Need MDS version at least 2.12.55"
22914
22915         local dom=$DIR/$tdir/$tfile
22916         mkdir -p $DIR/$tdir
22917         $LFS setstripe -c 2 $dom
22918
22919         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22920                 error "failed to write data into $dom"
22921         local old_md5=$(md5sum $dom)
22922         cancel_lru_locks
22923
22924         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22925                 error "failed migrating to the DOM file"
22926
22927         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22928                 error "MDT stripe wasn't set"
22929
22930         cancel_lru_locks
22931         local new_md5=$(md5sum $dom)
22932         [ "$old_md5" != "$new_md5" ] &&
22933                 error "$old_md5 != $new_md5"
22934
22935         return 0
22936 }
22937 run_test 272f "DoM migration: OST-striped file to DOM file"
22938
22939 test_273a() {
22940         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22941                 skip "Need MDS version at least 2.11.50"
22942
22943         # Layout swap cannot be done if either file has DOM component,
22944         # this will never be supported, migration should be used instead
22945
22946         local dom=$DIR/$tdir/$tfile
22947         mkdir -p $DIR/$tdir
22948
22949         $LFS setstripe -c2 ${dom}_plain
22950         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22951         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22952                 error "can swap layout with DoM component"
22953         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22954                 error "can swap layout with DoM component"
22955
22956         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22957         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22958                 error "can swap layout with DoM component"
22959         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22960                 error "can swap layout with DoM component"
22961         return 0
22962 }
22963 run_test 273a "DoM: layout swapping should fail with DOM"
22964
22965 test_273b() {
22966         mkdir -p $DIR/$tdir
22967         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22968
22969 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22970         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22971
22972         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22973 }
22974 run_test 273b "DoM: race writeback and object destroy"
22975
22976 test_275() {
22977         remote_ost_nodsh && skip "remote OST with nodsh"
22978         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22979                 skip "Need OST version >= 2.10.57"
22980
22981         local file=$DIR/$tfile
22982         local oss
22983
22984         oss=$(comma_list $(osts_nodes))
22985
22986         dd if=/dev/urandom of=$file bs=1M count=2 ||
22987                 error "failed to create a file"
22988         cancel_lru_locks osc
22989
22990         #lock 1
22991         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22992                 error "failed to read a file"
22993
22994 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22995         $LCTL set_param fail_loc=0x8000031f
22996
22997         cancel_lru_locks osc &
22998         sleep 1
22999
23000 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
23001         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
23002         #IO takes another lock, but matches the PENDING one
23003         #and places it to the IO RPC
23004         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23005                 error "failed to read a file with PENDING lock"
23006 }
23007 run_test 275 "Read on a canceled duplicate lock"
23008
23009 test_276() {
23010         remote_ost_nodsh && skip "remote OST with nodsh"
23011         local pid
23012
23013         do_facet ost1 "(while true; do \
23014                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
23015                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
23016         pid=$!
23017
23018         for LOOP in $(seq 20); do
23019                 stop ost1
23020                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
23021         done
23022         kill -9 $pid
23023         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23024                 rm $TMP/sanity_276_pid"
23025 }
23026 run_test 276 "Race between mount and obd_statfs"
23027
23028 test_277() {
23029         $LCTL set_param ldlm.namespaces.*.lru_size=0
23030         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23031         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23032                         grep ^used_mb | awk '{print $2}')
23033         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23034         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23035                 oflag=direct conv=notrunc
23036         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23037                         grep ^used_mb | awk '{print $2}')
23038         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23039 }
23040 run_test 277 "Direct IO shall drop page cache"
23041
23042 test_278() {
23043         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23044         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23045         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23046                 skip "needs the same host for mdt1 mdt2" && return
23047
23048         local pid1
23049         local pid2
23050
23051 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
23052         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
23053         stop mds2 &
23054         pid2=$!
23055
23056         stop mds1
23057
23058         echo "Starting MDTs"
23059         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23060         wait $pid2
23061 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23062 #will return NULL
23063         do_facet mds2 $LCTL set_param fail_loc=0
23064
23065         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23066         wait_recovery_complete mds2
23067 }
23068 run_test 278 "Race starting MDS between MDTs stop/start"
23069
23070 test_280() {
23071         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23072                 skip "Need MGS version at least 2.13.52"
23073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23074         combined_mgs_mds || skip "needs combined MGS/MDT"
23075
23076         umount_client $MOUNT
23077 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23078         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23079
23080         mount_client $MOUNT &
23081         sleep 1
23082         stop mgs || error "stop mgs failed"
23083         #for a race mgs would crash
23084         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23085         # make sure we unmount client before remounting
23086         wait
23087         umount_client $MOUNT
23088         mount_client $MOUNT || error "mount client failed"
23089 }
23090 run_test 280 "Race between MGS umount and client llog processing"
23091
23092 cleanup_test_300() {
23093         trap 0
23094         umask $SAVE_UMASK
23095 }
23096 test_striped_dir() {
23097         local mdt_index=$1
23098         local stripe_count
23099         local stripe_index
23100
23101         mkdir -p $DIR/$tdir
23102
23103         SAVE_UMASK=$(umask)
23104         trap cleanup_test_300 RETURN EXIT
23105
23106         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23107                                                 $DIR/$tdir/striped_dir ||
23108                 error "set striped dir error"
23109
23110         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23111         [ "$mode" = "755" ] || error "expect 755 got $mode"
23112
23113         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23114                 error "getdirstripe failed"
23115         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23116         if [ "$stripe_count" != "2" ]; then
23117                 error "1:stripe_count is $stripe_count, expect 2"
23118         fi
23119         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23120         if [ "$stripe_count" != "2" ]; then
23121                 error "2:stripe_count is $stripe_count, expect 2"
23122         fi
23123
23124         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23125         if [ "$stripe_index" != "$mdt_index" ]; then
23126                 error "stripe_index is $stripe_index, expect $mdt_index"
23127         fi
23128
23129         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23130                 error "nlink error after create striped dir"
23131
23132         mkdir $DIR/$tdir/striped_dir/a
23133         mkdir $DIR/$tdir/striped_dir/b
23134
23135         stat $DIR/$tdir/striped_dir/a ||
23136                 error "create dir under striped dir failed"
23137         stat $DIR/$tdir/striped_dir/b ||
23138                 error "create dir under striped dir failed"
23139
23140         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23141                 error "nlink error after mkdir"
23142
23143         rmdir $DIR/$tdir/striped_dir/a
23144         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23145                 error "nlink error after rmdir"
23146
23147         rmdir $DIR/$tdir/striped_dir/b
23148         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23149                 error "nlink error after rmdir"
23150
23151         chattr +i $DIR/$tdir/striped_dir
23152         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23153                 error "immutable flags not working under striped dir!"
23154         chattr -i $DIR/$tdir/striped_dir
23155
23156         rmdir $DIR/$tdir/striped_dir ||
23157                 error "rmdir striped dir error"
23158
23159         cleanup_test_300
23160
23161         true
23162 }
23163
23164 test_300a() {
23165         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23166                 skip "skipped for lustre < 2.7.0"
23167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23168         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23169
23170         test_striped_dir 0 || error "failed on striped dir on MDT0"
23171         test_striped_dir 1 || error "failed on striped dir on MDT0"
23172 }
23173 run_test 300a "basic striped dir sanity test"
23174
23175 test_300b() {
23176         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23177                 skip "skipped for lustre < 2.7.0"
23178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23179         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23180
23181         local i
23182         local mtime1
23183         local mtime2
23184         local mtime3
23185
23186         test_mkdir $DIR/$tdir || error "mkdir fail"
23187         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23188                 error "set striped dir error"
23189         for i in {0..9}; do
23190                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23191                 sleep 1
23192                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23193                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23194                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23195                 sleep 1
23196                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23197                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23198                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23199         done
23200         true
23201 }
23202 run_test 300b "check ctime/mtime for striped dir"
23203
23204 test_300c() {
23205         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23206                 skip "skipped for lustre < 2.7.0"
23207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23208         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23209
23210         local file_count
23211
23212         mkdir_on_mdt0 $DIR/$tdir
23213         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23214                 error "set striped dir error"
23215
23216         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23217                 error "chown striped dir failed"
23218
23219         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23220                 error "create 5k files failed"
23221
23222         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23223
23224         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23225
23226         rm -rf $DIR/$tdir
23227 }
23228 run_test 300c "chown && check ls under striped directory"
23229
23230 test_300d() {
23231         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23232                 skip "skipped for lustre < 2.7.0"
23233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23234         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23235
23236         local stripe_count
23237         local file
23238
23239         mkdir -p $DIR/$tdir
23240         $LFS setstripe -c 2 $DIR/$tdir
23241
23242         #local striped directory
23243         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23244                 error "set striped dir error"
23245         #look at the directories for debug purposes
23246         ls -l $DIR/$tdir
23247         $LFS getdirstripe $DIR/$tdir
23248         ls -l $DIR/$tdir/striped_dir
23249         $LFS getdirstripe $DIR/$tdir/striped_dir
23250         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23251                 error "create 10 files failed"
23252
23253         #remote striped directory
23254         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23255                 error "set striped dir error"
23256         #look at the directories for debug purposes
23257         ls -l $DIR/$tdir
23258         $LFS getdirstripe $DIR/$tdir
23259         ls -l $DIR/$tdir/remote_striped_dir
23260         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23261         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23262                 error "create 10 files failed"
23263
23264         for file in $(find $DIR/$tdir); do
23265                 stripe_count=$($LFS getstripe -c $file)
23266                 [ $stripe_count -eq 2 ] ||
23267                         error "wrong stripe $stripe_count for $file"
23268         done
23269
23270         rm -rf $DIR/$tdir
23271 }
23272 run_test 300d "check default stripe under striped directory"
23273
23274 test_300e() {
23275         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23276                 skip "Need MDS version at least 2.7.55"
23277         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23278         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23279
23280         local stripe_count
23281         local file
23282
23283         mkdir -p $DIR/$tdir
23284
23285         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23286                 error "set striped dir error"
23287
23288         touch $DIR/$tdir/striped_dir/a
23289         touch $DIR/$tdir/striped_dir/b
23290         touch $DIR/$tdir/striped_dir/c
23291
23292         mkdir $DIR/$tdir/striped_dir/dir_a
23293         mkdir $DIR/$tdir/striped_dir/dir_b
23294         mkdir $DIR/$tdir/striped_dir/dir_c
23295
23296         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23297                 error "set striped adir under striped dir error"
23298
23299         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23300                 error "set striped bdir under striped dir error"
23301
23302         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23303                 error "set striped cdir under striped dir error"
23304
23305         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23306                 error "rename dir under striped dir fails"
23307
23308         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23309                 error "rename dir under different stripes fails"
23310
23311         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23312                 error "rename file under striped dir should succeed"
23313
23314         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23315                 error "rename dir under striped dir should succeed"
23316
23317         rm -rf $DIR/$tdir
23318 }
23319 run_test 300e "check rename under striped directory"
23320
23321 test_300f() {
23322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23323         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23324         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23325                 skip "Need MDS version at least 2.7.55"
23326
23327         local stripe_count
23328         local file
23329
23330         rm -rf $DIR/$tdir
23331         mkdir -p $DIR/$tdir
23332
23333         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23334                 error "set striped dir error"
23335
23336         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23337                 error "set striped dir error"
23338
23339         touch $DIR/$tdir/striped_dir/a
23340         mkdir $DIR/$tdir/striped_dir/dir_a
23341         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23342                 error "create striped dir under striped dir fails"
23343
23344         touch $DIR/$tdir/striped_dir1/b
23345         mkdir $DIR/$tdir/striped_dir1/dir_b
23346         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23347                 error "create striped dir under striped dir fails"
23348
23349         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23350                 error "rename dir under different striped dir should fail"
23351
23352         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23353                 error "rename striped dir under diff striped dir should fail"
23354
23355         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23356                 error "rename file under diff striped dirs fails"
23357
23358         rm -rf $DIR/$tdir
23359 }
23360 run_test 300f "check rename cross striped directory"
23361
23362 test_300_check_default_striped_dir()
23363 {
23364         local dirname=$1
23365         local default_count=$2
23366         local default_index=$3
23367         local stripe_count
23368         local stripe_index
23369         local dir_stripe_index
23370         local dir
23371
23372         echo "checking $dirname $default_count $default_index"
23373         $LFS setdirstripe -D -c $default_count -i $default_index \
23374                                 -H all_char $DIR/$tdir/$dirname ||
23375                 error "set default stripe on striped dir error"
23376         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23377         [ $stripe_count -eq $default_count ] ||
23378                 error "expect $default_count get $stripe_count for $dirname"
23379
23380         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23381         [ $stripe_index -eq $default_index ] ||
23382                 error "expect $default_index get $stripe_index for $dirname"
23383
23384         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23385                                                 error "create dirs failed"
23386
23387         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23388         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23389         for dir in $(find $DIR/$tdir/$dirname/*); do
23390                 stripe_count=$($LFS getdirstripe -c $dir)
23391                 (( $stripe_count == $default_count )) ||
23392                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23393                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23394                 error "stripe count $default_count != $stripe_count for $dir"
23395
23396                 stripe_index=$($LFS getdirstripe -i $dir)
23397                 [ $default_index -eq -1 ] ||
23398                         [ $stripe_index -eq $default_index ] ||
23399                         error "$stripe_index != $default_index for $dir"
23400
23401                 #check default stripe
23402                 stripe_count=$($LFS getdirstripe -D -c $dir)
23403                 [ $stripe_count -eq $default_count ] ||
23404                 error "default count $default_count != $stripe_count for $dir"
23405
23406                 stripe_index=$($LFS getdirstripe -D -i $dir)
23407                 [ $stripe_index -eq $default_index ] ||
23408                 error "default index $default_index != $stripe_index for $dir"
23409         done
23410         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23411 }
23412
23413 test_300g() {
23414         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23415         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23416                 skip "Need MDS version at least 2.7.55"
23417
23418         local dir
23419         local stripe_count
23420         local stripe_index
23421
23422         mkdir_on_mdt0 $DIR/$tdir
23423         mkdir $DIR/$tdir/normal_dir
23424
23425         #Checking when client cache stripe index
23426         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23427         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23428                 error "create striped_dir failed"
23429
23430         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23431                 error "create dir0 fails"
23432         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23433         [ $stripe_index -eq 0 ] ||
23434                 error "dir0 expect index 0 got $stripe_index"
23435
23436         mkdir $DIR/$tdir/striped_dir/dir1 ||
23437                 error "create dir1 fails"
23438         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23439         [ $stripe_index -eq 1 ] ||
23440                 error "dir1 expect index 1 got $stripe_index"
23441
23442         #check default stripe count/stripe index
23443         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23444         test_300_check_default_striped_dir normal_dir 1 0
23445         test_300_check_default_striped_dir normal_dir -1 1
23446         test_300_check_default_striped_dir normal_dir 2 -1
23447
23448         #delete default stripe information
23449         echo "delete default stripeEA"
23450         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23451                 error "set default stripe on striped dir error"
23452
23453         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23454         for dir in $(find $DIR/$tdir/normal_dir/*); do
23455                 stripe_count=$($LFS getdirstripe -c $dir)
23456                 [ $stripe_count -eq 0 ] ||
23457                         error "expect 1 get $stripe_count for $dir"
23458         done
23459 }
23460 run_test 300g "check default striped directory for normal directory"
23461
23462 test_300h() {
23463         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23464         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23465                 skip "Need MDS version at least 2.7.55"
23466
23467         local dir
23468         local stripe_count
23469
23470         mkdir $DIR/$tdir
23471         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23472                 error "set striped dir error"
23473
23474         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23475         test_300_check_default_striped_dir striped_dir 1 0
23476         test_300_check_default_striped_dir striped_dir -1 1
23477         test_300_check_default_striped_dir striped_dir 2 -1
23478
23479         #delete default stripe information
23480         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23481                 error "set default stripe on striped dir error"
23482
23483         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23484         for dir in $(find $DIR/$tdir/striped_dir/*); do
23485                 stripe_count=$($LFS getdirstripe -c $dir)
23486                 [ $stripe_count -eq 0 ] ||
23487                         error "expect 1 get $stripe_count for $dir"
23488         done
23489 }
23490 run_test 300h "check default striped directory for striped directory"
23491
23492 test_300i() {
23493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23494         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23495         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23496                 skip "Need MDS version at least 2.7.55"
23497
23498         local stripe_count
23499         local file
23500
23501         mkdir $DIR/$tdir
23502
23503         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23504                 error "set striped dir error"
23505
23506         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23507                 error "create files under striped dir failed"
23508
23509         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23510                 error "set striped hashdir error"
23511
23512         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23513                 error "create dir0 under hash dir failed"
23514         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23515                 error "create dir1 under hash dir failed"
23516         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23517                 error "create dir2 under hash dir failed"
23518
23519         # unfortunately, we need to umount to clear dir layout cache for now
23520         # once we fully implement dir layout, we can drop this
23521         umount_client $MOUNT || error "umount failed"
23522         mount_client $MOUNT || error "mount failed"
23523
23524         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23525         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23526         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
23527
23528         #set the stripe to be unknown hash type
23529         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
23530         $LCTL set_param fail_loc=0x1901
23531         for ((i = 0; i < 10; i++)); do
23532                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23533                         error "stat f-$i failed"
23534                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23535         done
23536
23537         touch $DIR/$tdir/striped_dir/f0 &&
23538                 error "create under striped dir with unknown hash should fail"
23539
23540         $LCTL set_param fail_loc=0
23541
23542         umount_client $MOUNT || error "umount failed"
23543         mount_client $MOUNT || error "mount failed"
23544
23545         return 0
23546 }
23547 run_test 300i "client handle unknown hash type striped directory"
23548
23549 test_300j() {
23550         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23552         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23553                 skip "Need MDS version at least 2.7.55"
23554
23555         local stripe_count
23556         local file
23557
23558         mkdir $DIR/$tdir
23559
23560         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23561         $LCTL set_param fail_loc=0x1702
23562         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23563                 error "set striped dir error"
23564
23565         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23566                 error "create files under striped dir failed"
23567
23568         $LCTL set_param fail_loc=0
23569
23570         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23571
23572         return 0
23573 }
23574 run_test 300j "test large update record"
23575
23576 test_300k() {
23577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23578         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23579         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23580                 skip "Need MDS version at least 2.7.55"
23581
23582         # this test needs a huge transaction
23583         local kb
23584         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23585              osd*.$FSNAME-MDT0000.kbytestotal")
23586         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23587
23588         local stripe_count
23589         local file
23590
23591         mkdir $DIR/$tdir
23592
23593         #define OBD_FAIL_LARGE_STRIPE   0x1703
23594         $LCTL set_param fail_loc=0x1703
23595         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23596                 error "set striped dir error"
23597         $LCTL set_param fail_loc=0
23598
23599         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23600                 error "getstripeddir fails"
23601         rm -rf $DIR/$tdir/striped_dir ||
23602                 error "unlink striped dir fails"
23603
23604         return 0
23605 }
23606 run_test 300k "test large striped directory"
23607
23608 test_300l() {
23609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23610         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23611         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23612                 skip "Need MDS version at least 2.7.55"
23613
23614         local stripe_index
23615
23616         test_mkdir -p $DIR/$tdir/striped_dir
23617         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23618                         error "chown $RUNAS_ID failed"
23619         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23620                 error "set default striped dir failed"
23621
23622         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23623         $LCTL set_param fail_loc=0x80000158
23624         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23625
23626         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23627         [ $stripe_index -eq 1 ] ||
23628                 error "expect 1 get $stripe_index for $dir"
23629 }
23630 run_test 300l "non-root user to create dir under striped dir with stale layout"
23631
23632 test_300m() {
23633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23634         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23635         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23636                 skip "Need MDS version at least 2.7.55"
23637
23638         mkdir -p $DIR/$tdir/striped_dir
23639         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23640                 error "set default stripes dir error"
23641
23642         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23643
23644         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23645         [ $stripe_count -eq 0 ] ||
23646                         error "expect 0 get $stripe_count for a"
23647
23648         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23649                 error "set default stripes dir error"
23650
23651         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23652
23653         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23654         [ $stripe_count -eq 0 ] ||
23655                         error "expect 0 get $stripe_count for b"
23656
23657         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23658                 error "set default stripes dir error"
23659
23660         mkdir $DIR/$tdir/striped_dir/c &&
23661                 error "default stripe_index is invalid, mkdir c should fails"
23662
23663         rm -rf $DIR/$tdir || error "rmdir fails"
23664 }
23665 run_test 300m "setstriped directory on single MDT FS"
23666
23667 cleanup_300n() {
23668         local list=$(comma_list $(mdts_nodes))
23669
23670         trap 0
23671         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23672 }
23673
23674 test_300n() {
23675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23676         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23677         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23678                 skip "Need MDS version at least 2.7.55"
23679         remote_mds_nodsh && skip "remote MDS with nodsh"
23680
23681         local stripe_index
23682         local list=$(comma_list $(mdts_nodes))
23683
23684         trap cleanup_300n RETURN EXIT
23685         mkdir -p $DIR/$tdir
23686         chmod 777 $DIR/$tdir
23687         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23688                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23689                 error "create striped dir succeeds with gid=0"
23690
23691         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23692         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23693                 error "create striped dir fails with gid=-1"
23694
23695         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23696         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23697                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23698                 error "set default striped dir succeeds with gid=0"
23699
23700
23701         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23702         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23703                 error "set default striped dir fails with gid=-1"
23704
23705
23706         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23707         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23708                                         error "create test_dir fails"
23709         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23710                                         error "create test_dir1 fails"
23711         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23712                                         error "create test_dir2 fails"
23713         cleanup_300n
23714 }
23715 run_test 300n "non-root user to create dir under striped dir with default EA"
23716
23717 test_300o() {
23718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23719         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23720         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23721                 skip "Need MDS version at least 2.7.55"
23722
23723         local numfree1
23724         local numfree2
23725
23726         mkdir -p $DIR/$tdir
23727
23728         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23729         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23730         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23731                 skip "not enough free inodes $numfree1 $numfree2"
23732         fi
23733
23734         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23735         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23736         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23737                 skip "not enough free space $numfree1 $numfree2"
23738         fi
23739
23740         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23741                 error "setdirstripe fails"
23742
23743         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23744                 error "create dirs fails"
23745
23746         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23747         ls $DIR/$tdir/striped_dir > /dev/null ||
23748                 error "ls striped dir fails"
23749         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23750                 error "unlink big striped dir fails"
23751 }
23752 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23753
23754 test_300p() {
23755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23756         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23757         remote_mds_nodsh && skip "remote MDS with nodsh"
23758
23759         mkdir_on_mdt0 $DIR/$tdir
23760
23761         #define OBD_FAIL_OUT_ENOSPC     0x1704
23762         do_facet mds2 lctl set_param fail_loc=0x80001704
23763         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23764                  && error "create striped directory should fail"
23765
23766         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23767
23768         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23769         true
23770 }
23771 run_test 300p "create striped directory without space"
23772
23773 test_300q() {
23774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23775         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23776
23777         local fd=$(free_fd)
23778         local cmd="exec $fd<$tdir"
23779         cd $DIR
23780         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23781         eval $cmd
23782         cmd="exec $fd<&-"
23783         trap "eval $cmd" EXIT
23784         cd $tdir || error "cd $tdir fails"
23785         rmdir  ../$tdir || error "rmdir $tdir fails"
23786         mkdir local_dir && error "create dir succeeds"
23787         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23788         eval $cmd
23789         return 0
23790 }
23791 run_test 300q "create remote directory under orphan directory"
23792
23793 test_300r() {
23794         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23795                 skip "Need MDS version at least 2.7.55" && return
23796         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23797
23798         mkdir $DIR/$tdir
23799
23800         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23801                 error "set striped dir error"
23802
23803         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23804                 error "getstripeddir fails"
23805
23806         local stripe_count
23807         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23808                       awk '/lmv_stripe_count:/ { print $2 }')
23809
23810         [ $MDSCOUNT -ne $stripe_count ] &&
23811                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23812
23813         rm -rf $DIR/$tdir/striped_dir ||
23814                 error "unlink striped dir fails"
23815 }
23816 run_test 300r "test -1 striped directory"
23817
23818 test_300s_helper() {
23819         local count=$1
23820
23821         local stripe_dir=$DIR/$tdir/striped_dir.$count
23822
23823         $LFS mkdir -c $count $stripe_dir ||
23824                 error "lfs mkdir -c error"
23825
23826         $LFS getdirstripe $stripe_dir ||
23827                 error "lfs getdirstripe fails"
23828
23829         local stripe_count
23830         stripe_count=$($LFS getdirstripe $stripe_dir |
23831                       awk '/lmv_stripe_count:/ { print $2 }')
23832
23833         [ $count -ne $stripe_count ] &&
23834                 error_noexit "bad stripe count $stripe_count expected $count"
23835
23836         local dupe_stripes
23837         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23838                 awk '/0x/ {count[$1] += 1}; END {
23839                         for (idx in count) {
23840                                 if (count[idx]>1) {
23841                                         print "index " idx " count " count[idx]
23842                                 }
23843                         }
23844                 }')
23845
23846         if [[ -n "$dupe_stripes" ]] ; then
23847                 lfs getdirstripe $stripe_dir
23848                 error_noexit "Dupe MDT above: $dupe_stripes "
23849         fi
23850
23851         rm -rf $stripe_dir ||
23852                 error_noexit "unlink $stripe_dir fails"
23853 }
23854
23855 test_300s() {
23856         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23857                 skip "Need MDS version at least 2.7.55" && return
23858         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23859
23860         mkdir $DIR/$tdir
23861         for count in $(seq 2 $MDSCOUNT); do
23862                 test_300s_helper $count
23863         done
23864 }
23865 run_test 300s "test lfs mkdir -c without -i"
23866
23867 test_300t() {
23868         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
23869                 skip "need MDS 2.14.55 or later"
23870         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
23871
23872         local testdir="$DIR/$tdir/striped_dir"
23873         local dir1=$testdir/dir1
23874         local dir2=$testdir/dir2
23875
23876         mkdir -p $testdir
23877
23878         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
23879                 error "failed to set default stripe count for $testdir"
23880
23881         mkdir $dir1
23882         local stripe_count=$($LFS getdirstripe -c $dir1)
23883
23884         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
23885
23886         local max_count=$((MDSCOUNT - 1))
23887         local mdts=$(comma_list $(mdts_nodes))
23888
23889         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
23890         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
23891
23892         mkdir $dir2
23893         stripe_count=$($LFS getdirstripe -c $dir2)
23894
23895         (( $stripe_count == $max_count )) || error "wrong stripe count"
23896 }
23897 run_test 300t "test max_mdt_stripecount"
23898
23899 prepare_remote_file() {
23900         mkdir $DIR/$tdir/src_dir ||
23901                 error "create remote source failed"
23902
23903         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23904                  error "cp to remote source failed"
23905         touch $DIR/$tdir/src_dir/a
23906
23907         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23908                 error "create remote target dir failed"
23909
23910         touch $DIR/$tdir/tgt_dir/b
23911
23912         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23913                 error "rename dir cross MDT failed!"
23914
23915         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23916                 error "src_child still exists after rename"
23917
23918         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23919                 error "missing file(a) after rename"
23920
23921         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
23922                 error "diff after rename"
23923 }
23924
23925 test_310a() {
23926         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23928
23929         local remote_file=$DIR/$tdir/tgt_dir/b
23930
23931         mkdir -p $DIR/$tdir
23932
23933         prepare_remote_file || error "prepare remote file failed"
23934
23935         #open-unlink file
23936         $OPENUNLINK $remote_file $remote_file ||
23937                 error "openunlink $remote_file failed"
23938         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23939 }
23940 run_test 310a "open unlink remote file"
23941
23942 test_310b() {
23943         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23945
23946         local remote_file=$DIR/$tdir/tgt_dir/b
23947
23948         mkdir -p $DIR/$tdir
23949
23950         prepare_remote_file || error "prepare remote file failed"
23951
23952         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23953         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23954         $CHECKSTAT -t file $remote_file || error "check file failed"
23955 }
23956 run_test 310b "unlink remote file with multiple links while open"
23957
23958 test_310c() {
23959         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23960         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23961
23962         local remote_file=$DIR/$tdir/tgt_dir/b
23963
23964         mkdir -p $DIR/$tdir
23965
23966         prepare_remote_file || error "prepare remote file failed"
23967
23968         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23969         multiop_bg_pause $remote_file O_uc ||
23970                         error "mulitop failed for remote file"
23971         MULTIPID=$!
23972         $MULTIOP $DIR/$tfile Ouc
23973         kill -USR1 $MULTIPID
23974         wait $MULTIPID
23975 }
23976 run_test 310c "open-unlink remote file with multiple links"
23977
23978 #LU-4825
23979 test_311() {
23980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23981         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23982         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23983                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23984         remote_mds_nodsh && skip "remote MDS with nodsh"
23985
23986         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23987         local mdts=$(comma_list $(mdts_nodes))
23988
23989         mkdir -p $DIR/$tdir
23990         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23991         createmany -o $DIR/$tdir/$tfile. 1000
23992
23993         # statfs data is not real time, let's just calculate it
23994         old_iused=$((old_iused + 1000))
23995
23996         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23997                         osp.*OST0000*MDT0000.create_count")
23998         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23999                                 osp.*OST0000*MDT0000.max_create_count")
24000         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
24001
24002         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
24003         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
24004         [ $index -ne 0 ] || error "$tfile stripe index is 0"
24005
24006         unlinkmany $DIR/$tdir/$tfile. 1000
24007
24008         do_nodes $mdts "$LCTL set_param -n \
24009                         osp.*OST0000*.max_create_count=$max_count"
24010         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
24011                 do_nodes $mdts "$LCTL set_param -n \
24012                                 osp.*OST0000*.create_count=$count"
24013         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
24014                         grep "=0" && error "create_count is zero"
24015
24016         local new_iused
24017         for i in $(seq 120); do
24018                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24019                 # system may be too busy to destroy all objs in time, use
24020                 # a somewhat small value to not fail autotest
24021                 [ $((old_iused - new_iused)) -gt 400 ] && break
24022                 sleep 1
24023         done
24024
24025         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24026         [ $((old_iused - new_iused)) -gt 400 ] ||
24027                 error "objs not destroyed after unlink"
24028 }
24029 run_test 311 "disable OSP precreate, and unlink should destroy objs"
24030
24031 zfs_oid_to_objid()
24032 {
24033         local ost=$1
24034         local objid=$2
24035
24036         local vdevdir=$(dirname $(facet_vdevice $ost))
24037         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
24038         local zfs_zapid=$(do_facet $ost $cmd |
24039                           grep -w "/O/0/d$((objid%32))" -C 5 |
24040                           awk '/Object/{getline; print $1}')
24041         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
24042                           awk "/$objid = /"'{printf $3}')
24043
24044         echo $zfs_objid
24045 }
24046
24047 zfs_object_blksz() {
24048         local ost=$1
24049         local objid=$2
24050
24051         local vdevdir=$(dirname $(facet_vdevice $ost))
24052         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
24053         local blksz=$(do_facet $ost $cmd $objid |
24054                       awk '/dblk/{getline; printf $4}')
24055
24056         case "${blksz: -1}" in
24057                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24058                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24059                 *) ;;
24060         esac
24061
24062         echo $blksz
24063 }
24064
24065 test_312() { # LU-4856
24066         remote_ost_nodsh && skip "remote OST with nodsh"
24067         [ "$ost1_FSTYPE" = "zfs" ] ||
24068                 skip_env "the test only applies to zfs"
24069
24070         local max_blksz=$(do_facet ost1 \
24071                           $ZFS get -p recordsize $(facet_device ost1) |
24072                           awk '!/VALUE/{print $3}')
24073
24074         # to make life a little bit easier
24075         $LFS mkdir -c 1 -i 0 $DIR/$tdir
24076         $LFS setstripe -c 1 -i 0 $DIR/$tdir
24077
24078         local tf=$DIR/$tdir/$tfile
24079         touch $tf
24080         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24081
24082         # Get ZFS object id
24083         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24084         # block size change by sequential overwrite
24085         local bs
24086
24087         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24088                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24089
24090                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
24091                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
24092         done
24093         rm -f $tf
24094
24095         # block size change by sequential append write
24096         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24097         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24098         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24099         local count
24100
24101         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24102                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24103                         oflag=sync conv=notrunc
24104
24105                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
24106                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
24107                         error "blksz error, actual $blksz, " \
24108                                 "expected: 2 * $count * $PAGE_SIZE"
24109         done
24110         rm -f $tf
24111
24112         # random write
24113         touch $tf
24114         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24115         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24116
24117         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24118         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24119         [ $blksz -eq $PAGE_SIZE ] ||
24120                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24121
24122         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24123         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24124         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
24125
24126         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24127         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24128         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
24129 }
24130 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24131
24132 test_313() {
24133         remote_ost_nodsh && skip "remote OST with nodsh"
24134
24135         local file=$DIR/$tfile
24136
24137         rm -f $file
24138         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24139
24140         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24141         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24142         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24143                 error "write should failed"
24144         do_facet ost1 "$LCTL set_param fail_loc=0"
24145         rm -f $file
24146 }
24147 run_test 313 "io should fail after last_rcvd update fail"
24148
24149 test_314() {
24150         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24151
24152         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24153         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24154         rm -f $DIR/$tfile
24155         wait_delete_completed
24156         do_facet ost1 "$LCTL set_param fail_loc=0"
24157 }
24158 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24159
24160 test_315() { # LU-618
24161         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24162
24163         local file=$DIR/$tfile
24164         rm -f $file
24165
24166         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24167                 error "multiop file write failed"
24168         $MULTIOP $file oO_RDONLY:r4063232_c &
24169         PID=$!
24170
24171         sleep 2
24172
24173         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24174         kill -USR1 $PID
24175
24176         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24177         rm -f $file
24178 }
24179 run_test 315 "read should be accounted"
24180
24181 test_316() {
24182         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24183         large_xattr_enabled || skip "ea_inode feature disabled"
24184
24185         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
24186         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
24187         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
24188         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
24189
24190         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
24191 }
24192 run_test 316 "lfs migrate of file with large_xattr enabled"
24193
24194 test_317() {
24195         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24196                 skip "Need MDS version at least 2.11.53"
24197         if [ "$ost1_FSTYPE" == "zfs" ]; then
24198                 skip "LU-10370: no implementation for ZFS"
24199         fi
24200
24201         local trunc_sz
24202         local grant_blk_size
24203
24204         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24205                         awk '/grant_block_size:/ { print $2; exit; }')
24206         #
24207         # Create File of size 5M. Truncate it to below size's and verify
24208         # blocks count.
24209         #
24210         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24211                 error "Create file $DIR/$tfile failed"
24212         stack_trap "rm -f $DIR/$tfile" EXIT
24213
24214         for trunc_sz in 2097152 4097 4000 509 0; do
24215                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24216                         error "truncate $tfile to $trunc_sz failed"
24217                 local sz=$(stat --format=%s $DIR/$tfile)
24218                 local blk=$(stat --format=%b $DIR/$tfile)
24219                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24220                                      grant_blk_size) * 8))
24221
24222                 if [[ $blk -ne $trunc_blk ]]; then
24223                         $(which stat) $DIR/$tfile
24224                         error "Expected Block $trunc_blk got $blk for $tfile"
24225                 fi
24226
24227                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24228                         error "Expected Size $trunc_sz got $sz for $tfile"
24229         done
24230
24231         #
24232         # sparse file test
24233         # Create file with a hole and write actual 65536 bytes which aligned
24234         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24235         #
24236         local bs=65536
24237         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24238                 error "Create file : $DIR/$tfile"
24239
24240         #
24241         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24242         # blocks. The block count must drop to 8.
24243         #
24244         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
24245                 ((bs - grant_blk_size) + 1)))
24246         $TRUNCATE $DIR/$tfile $trunc_sz ||
24247                 error "truncate $tfile to $trunc_sz failed"
24248
24249         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24250         sz=$(stat --format=%s $DIR/$tfile)
24251         blk=$(stat --format=%b $DIR/$tfile)
24252
24253         if [[ $blk -ne $trunc_bsz ]]; then
24254                 $(which stat) $DIR/$tfile
24255                 error "Expected Block $trunc_bsz got $blk for $tfile"
24256         fi
24257
24258         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24259                 error "Expected Size $trunc_sz got $sz for $tfile"
24260 }
24261 run_test 317 "Verify blocks get correctly update after truncate"
24262
24263 test_318() {
24264         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24265         local old_max_active=$($LCTL get_param -n \
24266                             ${llite_name}.max_read_ahead_async_active \
24267                             2>/dev/null)
24268
24269         $LCTL set_param llite.*.max_read_ahead_async_active=256
24270         local max_active=$($LCTL get_param -n \
24271                            ${llite_name}.max_read_ahead_async_active \
24272                            2>/dev/null)
24273         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24274
24275         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24276                 error "set max_read_ahead_async_active should succeed"
24277
24278         $LCTL set_param llite.*.max_read_ahead_async_active=512
24279         max_active=$($LCTL get_param -n \
24280                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24281         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24282
24283         # restore @max_active
24284         [ $old_max_active -ne 0 ] && $LCTL set_param \
24285                 llite.*.max_read_ahead_async_active=$old_max_active
24286
24287         local old_threshold=$($LCTL get_param -n \
24288                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24289         local max_per_file_mb=$($LCTL get_param -n \
24290                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24291
24292         local invalid=$(($max_per_file_mb + 1))
24293         $LCTL set_param \
24294                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24295                         && error "set $invalid should fail"
24296
24297         local valid=$(($invalid - 1))
24298         $LCTL set_param \
24299                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24300                         error "set $valid should succeed"
24301         local threshold=$($LCTL get_param -n \
24302                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24303         [ $threshold -eq $valid ] || error \
24304                 "expect threshold $valid got $threshold"
24305         $LCTL set_param \
24306                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24307 }
24308 run_test 318 "Verify async readahead tunables"
24309
24310 test_319() {
24311         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24312
24313         local before=$(date +%s)
24314         local evict
24315         local mdir=$DIR/$tdir
24316         local file=$mdir/xxx
24317
24318         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24319         touch $file
24320
24321 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24322         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24323         $LFS migrate -m1 $mdir &
24324
24325         sleep 1
24326         dd if=$file of=/dev/null
24327         wait
24328         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24329           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24330
24331         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24332 }
24333 run_test 319 "lost lease lock on migrate error"
24334
24335 test_398a() { # LU-4198
24336         local ost1_imp=$(get_osc_import_name client ost1)
24337         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24338                          cut -d'.' -f2)
24339
24340         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24341         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24342
24343         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
24344         # request a new lock on client
24345         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24346
24347         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24348         #local lock_count=$($LCTL get_param -n \
24349         #                  ldlm.namespaces.$imp_name.lru_size)
24350         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24351
24352         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24353
24354         # no lock cached, should use lockless DIO and not enqueue new lock
24355         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
24356                 conv=notrunc ||
24357                 error "dio write failed"
24358         lock_count=$($LCTL get_param -n \
24359                      ldlm.namespaces.$imp_name.lru_size)
24360         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24361
24362         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24363
24364         # no lock cached, should use locked DIO append
24365         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
24366                 conv=notrunc || error "DIO append failed"
24367         lock_count=$($LCTL get_param -n \
24368                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
24369         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
24370 }
24371 run_test 398a "direct IO should cancel lock otherwise lockless"
24372
24373 test_398b() { # LU-4198
24374         which fio || skip_env "no fio installed"
24375         $LFS setstripe -c -1 -S 1M $DIR/$tfile
24376
24377         local size=48
24378         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24379
24380         local njobs=4
24381         # Single page, multiple pages, stripe size, 4*stripe size
24382         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
24383                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
24384                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
24385                         --numjobs=$njobs --fallocate=none \
24386                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24387                         --filename=$DIR/$tfile &
24388                 bg_pid=$!
24389
24390                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
24391                 fio --name=rand-rw --rw=randrw --bs=$bsize \
24392                         --numjobs=$njobs --fallocate=none \
24393                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24394                         --filename=$DIR/$tfile || true
24395                 wait $bg_pid
24396         done
24397
24398         evict=$(do_facet client $LCTL get_param \
24399                 osc.$FSNAME-OST*-osc-*/state |
24400             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
24401
24402         [ -z "$evict" ] || [[ $evict -le $before ]] ||
24403                 (do_facet client $LCTL get_param \
24404                         osc.$FSNAME-OST*-osc-*/state;
24405                     error "eviction happened: $evict before:$before")
24406
24407         rm -f $DIR/$tfile
24408 }
24409 run_test 398b "DIO and buffer IO race"
24410
24411 test_398c() { # LU-4198
24412         local ost1_imp=$(get_osc_import_name client ost1)
24413         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24414                          cut -d'.' -f2)
24415
24416         which fio || skip_env "no fio installed"
24417
24418         saved_debug=$($LCTL get_param -n debug)
24419         $LCTL set_param debug=0
24420
24421         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24422         ((size /= 1024)) # by megabytes
24423         ((size /= 2)) # write half of the OST at most
24424         [ $size -gt 40 ] && size=40 #reduce test time anyway
24425
24426         $LFS setstripe -c 1 $DIR/$tfile
24427
24428         # it seems like ldiskfs reserves more space than necessary if the
24429         # writing blocks are not mapped, so it extends the file firstly
24430         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24431         cancel_lru_locks osc
24432
24433         # clear and verify rpc_stats later
24434         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24435
24436         local njobs=4
24437         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24438         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24439                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24440                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24441                 --filename=$DIR/$tfile
24442         [ $? -eq 0 ] || error "fio write error"
24443
24444         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24445                 error "Locks were requested while doing AIO"
24446
24447         # get the percentage of 1-page I/O
24448         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24449                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24450                 awk '{print $7}')
24451         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24452
24453         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24454         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24455                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24456                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24457                 --filename=$DIR/$tfile
24458         [ $? -eq 0 ] || error "fio mixed read write error"
24459
24460         echo "AIO with large block size ${size}M"
24461         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24462                 --numjobs=1 --fallocate=none --ioengine=libaio \
24463                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24464                 --filename=$DIR/$tfile
24465         [ $? -eq 0 ] || error "fio large block size failed"
24466
24467         rm -f $DIR/$tfile
24468         $LCTL set_param debug="$saved_debug"
24469 }
24470 run_test 398c "run fio to test AIO"
24471
24472 test_398d() { #  LU-13846
24473         which aiocp || skip_env "no aiocp installed"
24474         local aio_file=$DIR/$tfile.aio
24475
24476         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24477
24478         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24479         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24480         stack_trap "rm -f $DIR/$tfile $aio_file"
24481
24482         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24483
24484         # make sure we don't crash and fail properly
24485         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24486                 error "aio not aligned with PAGE SIZE should fail"
24487
24488         rm -f $DIR/$tfile $aio_file
24489 }
24490 run_test 398d "run aiocp to verify block size > stripe size"
24491
24492 test_398e() {
24493         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24494         touch $DIR/$tfile.new
24495         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24496 }
24497 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24498
24499 test_398f() { #  LU-14687
24500         which aiocp || skip_env "no aiocp installed"
24501         local aio_file=$DIR/$tfile.aio
24502
24503         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24504
24505         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24506         stack_trap "rm -f $DIR/$tfile $aio_file"
24507
24508         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24509         $LCTL set_param fail_loc=0x1418
24510         # make sure we don't crash and fail properly
24511         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24512                 error "aio with page allocation failure succeeded"
24513         $LCTL set_param fail_loc=0
24514         diff $DIR/$tfile $aio_file
24515         [[ $? != 0 ]] || error "no diff after failed aiocp"
24516 }
24517 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24518
24519 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24520 # stripe and i/o size must be > stripe size
24521 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24522 # single RPC in flight.  This test shows async DIO submission is working by
24523 # showing multiple RPCs in flight.
24524 test_398g() { #  LU-13798
24525         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24526
24527         # We need to do some i/o first to acquire enough grant to put our RPCs
24528         # in flight; otherwise a new connection may not have enough grant
24529         # available
24530         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24531                 error "parallel dio failed"
24532         stack_trap "rm -f $DIR/$tfile"
24533
24534         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24535         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24536         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24537         stack_trap "$LCTL set_param -n $pages_per_rpc"
24538
24539         # Recreate file so it's empty
24540         rm -f $DIR/$tfile
24541         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24542         #Pause rpc completion to guarantee we see multiple rpcs in flight
24543         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24544         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24545         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24546
24547         # Clear rpc stats
24548         $LCTL set_param osc.*.rpc_stats=c
24549
24550         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24551                 error "parallel dio failed"
24552         stack_trap "rm -f $DIR/$tfile"
24553
24554         $LCTL get_param osc.*-OST0000-*.rpc_stats
24555         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24556                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24557                 grep "8:" | awk '{print $8}')
24558         # We look at the "8 rpcs in flight" field, and verify A) it is present
24559         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24560         # as expected for an 8M DIO to a file with 1M stripes.
24561         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24562
24563         # Verify turning off parallel dio works as expected
24564         # Clear rpc stats
24565         $LCTL set_param osc.*.rpc_stats=c
24566         $LCTL set_param llite.*.parallel_dio=0
24567         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24568
24569         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24570                 error "dio with parallel dio disabled failed"
24571
24572         # Ideally, we would see only one RPC in flight here, but there is an
24573         # unavoidable race between i/o completion and RPC in flight counting,
24574         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24575         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24576         # So instead we just verify it's always < 8.
24577         $LCTL get_param osc.*-OST0000-*.rpc_stats
24578         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24579                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24580                 grep '^$' -B1 | grep . | awk '{print $1}')
24581         [ $ret != "8:" ] ||
24582                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24583 }
24584 run_test 398g "verify parallel dio async RPC submission"
24585
24586 test_398h() { #  LU-13798
24587         local dio_file=$DIR/$tfile.dio
24588
24589         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24590
24591         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24592         stack_trap "rm -f $DIR/$tfile $dio_file"
24593
24594         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24595                 error "parallel dio failed"
24596         diff $DIR/$tfile $dio_file
24597         [[ $? == 0 ]] || error "file diff after aiocp"
24598 }
24599 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24600
24601 test_398i() { #  LU-13798
24602         local dio_file=$DIR/$tfile.dio
24603
24604         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24605
24606         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24607         stack_trap "rm -f $DIR/$tfile $dio_file"
24608
24609         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24610         $LCTL set_param fail_loc=0x1418
24611         # make sure we don't crash and fail properly
24612         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24613                 error "parallel dio page allocation failure succeeded"
24614         diff $DIR/$tfile $dio_file
24615         [[ $? != 0 ]] || error "no diff after failed aiocp"
24616 }
24617 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24618
24619 test_398j() { #  LU-13798
24620         # Stripe size > RPC size but less than i/o size tests split across
24621         # stripes and RPCs for individual i/o op
24622         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24623
24624         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24625         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24626         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24627         stack_trap "$LCTL set_param -n $pages_per_rpc"
24628
24629         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24630                 error "parallel dio write failed"
24631         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24632
24633         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24634                 error "parallel dio read failed"
24635         diff $DIR/$tfile $DIR/$tfile.2
24636         [[ $? == 0 ]] || error "file diff after parallel dio read"
24637 }
24638 run_test 398j "test parallel dio where stripe size > rpc_size"
24639
24640 test_398k() { #  LU-13798
24641         wait_delete_completed
24642         wait_mds_ost_sync
24643
24644         # 4 stripe file; we will cause out of space on OST0
24645         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24646
24647         # Fill OST0 (if it's not too large)
24648         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24649                    head -n1)
24650         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24651                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24652         fi
24653         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24654         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24655                 error "dd should fill OST0"
24656         stack_trap "rm -f $DIR/$tfile.1"
24657
24658         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24659         err=$?
24660
24661         ls -la $DIR/$tfile
24662         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24663                 error "file is not 0 bytes in size"
24664
24665         # dd above should not succeed, but don't error until here so we can
24666         # get debug info above
24667         [[ $err != 0 ]] ||
24668                 error "parallel dio write with enospc succeeded"
24669         stack_trap "rm -f $DIR/$tfile"
24670 }
24671 run_test 398k "test enospc on first stripe"
24672
24673 test_398l() { #  LU-13798
24674         wait_delete_completed
24675         wait_mds_ost_sync
24676
24677         # 4 stripe file; we will cause out of space on OST0
24678         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24679         # happens on the second i/o chunk we issue
24680         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24681
24682         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24683         stack_trap "rm -f $DIR/$tfile"
24684
24685         # Fill OST0 (if it's not too large)
24686         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24687                    head -n1)
24688         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24689                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24690         fi
24691         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24692         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24693                 error "dd should fill OST0"
24694         stack_trap "rm -f $DIR/$tfile.1"
24695
24696         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24697         err=$?
24698         stack_trap "rm -f $DIR/$tfile.2"
24699
24700         # Check that short write completed as expected
24701         ls -la $DIR/$tfile.2
24702         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24703                 error "file is not 1M in size"
24704
24705         # dd above should not succeed, but don't error until here so we can
24706         # get debug info above
24707         [[ $err != 0 ]] ||
24708                 error "parallel dio write with enospc succeeded"
24709
24710         # Truncate source file to same length as output file and diff them
24711         $TRUNCATE $DIR/$tfile 1048576
24712         diff $DIR/$tfile $DIR/$tfile.2
24713         [[ $? == 0 ]] || error "data incorrect after short write"
24714 }
24715 run_test 398l "test enospc on intermediate stripe/RPC"
24716
24717 test_398m() { #  LU-13798
24718         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24719
24720         # Set up failure on OST0, the first stripe:
24721         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24722         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24723         # So this fail_val specifies OST0
24724         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24725         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24726
24727         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24728                 error "parallel dio write with failure on first stripe succeeded"
24729         stack_trap "rm -f $DIR/$tfile"
24730         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24731
24732         # Place data in file for read
24733         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24734                 error "parallel dio write failed"
24735
24736         # Fail read on OST0, first stripe
24737         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24738         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24739         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24740                 error "parallel dio read with error on first stripe succeeded"
24741         rm -f $DIR/$tfile.2
24742         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24743
24744         # Switch to testing on OST1, second stripe
24745         # Clear file contents, maintain striping
24746         echo > $DIR/$tfile
24747         # Set up failure on OST1, second stripe:
24748         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24749         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24750
24751         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24752                 error "parallel dio write with failure on first stripe succeeded"
24753         stack_trap "rm -f $DIR/$tfile"
24754         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24755
24756         # Place data in file for read
24757         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24758                 error "parallel dio write failed"
24759
24760         # Fail read on OST1, second stripe
24761         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24762         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24763         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24764                 error "parallel dio read with error on first stripe succeeded"
24765         rm -f $DIR/$tfile.2
24766         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24767 }
24768 run_test 398m "test RPC failures with parallel dio"
24769
24770 # Parallel submission of DIO should not cause problems for append, but it's
24771 # important to verify.
24772 test_398n() { #  LU-13798
24773         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24774
24775         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24776                 error "dd to create source file failed"
24777         stack_trap "rm -f $DIR/$tfile"
24778
24779         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24780                 error "parallel dio write with failure on second stripe succeeded"
24781         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24782         diff $DIR/$tfile $DIR/$tfile.1
24783         [[ $? == 0 ]] || error "data incorrect after append"
24784
24785 }
24786 run_test 398n "test append with parallel DIO"
24787
24788 test_fake_rw() {
24789         local read_write=$1
24790         if [ "$read_write" = "write" ]; then
24791                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24792         elif [ "$read_write" = "read" ]; then
24793                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24794         else
24795                 error "argument error"
24796         fi
24797
24798         # turn off debug for performance testing
24799         local saved_debug=$($LCTL get_param -n debug)
24800         $LCTL set_param debug=0
24801
24802         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24803
24804         # get ost1 size - $FSNAME-OST0000
24805         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24806         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
24807         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
24808
24809         if [ "$read_write" = "read" ]; then
24810                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
24811         fi
24812
24813         local start_time=$(date +%s.%N)
24814         $dd_cmd bs=1M count=$blocks oflag=sync ||
24815                 error "real dd $read_write error"
24816         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
24817
24818         if [ "$read_write" = "write" ]; then
24819                 rm -f $DIR/$tfile
24820         fi
24821
24822         # define OBD_FAIL_OST_FAKE_RW           0x238
24823         do_facet ost1 $LCTL set_param fail_loc=0x238
24824
24825         local start_time=$(date +%s.%N)
24826         $dd_cmd bs=1M count=$blocks oflag=sync ||
24827                 error "fake dd $read_write error"
24828         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
24829
24830         if [ "$read_write" = "write" ]; then
24831                 # verify file size
24832                 cancel_lru_locks osc
24833                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
24834                         error "$tfile size not $blocks MB"
24835         fi
24836         do_facet ost1 $LCTL set_param fail_loc=0
24837
24838         echo "fake $read_write $duration_fake vs. normal $read_write" \
24839                 "$duration in seconds"
24840         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
24841                 error_not_in_vm "fake write is slower"
24842
24843         $LCTL set_param -n debug="$saved_debug"
24844         rm -f $DIR/$tfile
24845 }
24846 test_399a() { # LU-7655 for OST fake write
24847         remote_ost_nodsh && skip "remote OST with nodsh"
24848
24849         test_fake_rw write
24850 }
24851 run_test 399a "fake write should not be slower than normal write"
24852
24853 test_399b() { # LU-8726 for OST fake read
24854         remote_ost_nodsh && skip "remote OST with nodsh"
24855         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
24856                 skip_env "ldiskfs only test"
24857         fi
24858
24859         test_fake_rw read
24860 }
24861 run_test 399b "fake read should not be slower than normal read"
24862
24863 test_400a() { # LU-1606, was conf-sanity test_74
24864         if ! which $CC > /dev/null 2>&1; then
24865                 skip_env "$CC is not installed"
24866         fi
24867
24868         local extra_flags=''
24869         local out=$TMP/$tfile
24870         local prefix=/usr/include/lustre
24871         local prog
24872
24873         # Oleg removes c files in his test rig so test if any c files exist
24874         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24875                 skip_env "Needed c test files are missing"
24876
24877         if ! [[ -d $prefix ]]; then
24878                 # Assume we're running in tree and fixup the include path.
24879                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24880                 extra_flags+=" -L$LUSTRE/utils/.lib"
24881         fi
24882
24883         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24884                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24885                         error "client api broken"
24886         done
24887         rm -f $out
24888 }
24889 run_test 400a "Lustre client api program can compile and link"
24890
24891 test_400b() { # LU-1606, LU-5011
24892         local header
24893         local out=$TMP/$tfile
24894         local prefix=/usr/include/linux/lustre
24895
24896         # We use a hard coded prefix so that this test will not fail
24897         # when run in tree. There are headers in lustre/include/lustre/
24898         # that are not packaged (like lustre_idl.h) and have more
24899         # complicated include dependencies (like config.h and lnet/types.h).
24900         # Since this test about correct packaging we just skip them when
24901         # they don't exist (see below) rather than try to fixup cppflags.
24902
24903         if ! which $CC > /dev/null 2>&1; then
24904                 skip_env "$CC is not installed"
24905         fi
24906
24907         for header in $prefix/*.h; do
24908                 if ! [[ -f "$header" ]]; then
24909                         continue
24910                 fi
24911
24912                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24913                         continue # lustre_ioctl.h is internal header
24914                 fi
24915
24916                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24917                         error "cannot compile '$header'"
24918         done
24919         rm -f $out
24920 }
24921 run_test 400b "packaged headers can be compiled"
24922
24923 test_401a() { #LU-7437
24924         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
24925         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
24926
24927         #count the number of parameters by "list_param -R"
24928         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
24929         #count the number of parameters by listing proc files
24930         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
24931         echo "proc_dirs='$proc_dirs'"
24932         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
24933         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
24934                       sort -u | wc -l)
24935
24936         [ $params -eq $procs ] ||
24937                 error "found $params parameters vs. $procs proc files"
24938
24939         # test the list_param -D option only returns directories
24940         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
24941         #count the number of parameters by listing proc directories
24942         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
24943                 sort -u | wc -l)
24944
24945         [ $params -eq $procs ] ||
24946                 error "found $params parameters vs. $procs proc files"
24947 }
24948 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
24949
24950 test_401b() {
24951         # jobid_var may not allow arbitrary values, so use jobid_name
24952         # if available
24953         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24954                 local testname=jobid_name tmp='testing%p'
24955         else
24956                 local testname=jobid_var tmp=testing
24957         fi
24958
24959         local save=$($LCTL get_param -n $testname)
24960
24961         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
24962                 error "no error returned when setting bad parameters"
24963
24964         local jobid_new=$($LCTL get_param -n foe $testname baz)
24965         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
24966
24967         $LCTL set_param -n fog=bam $testname=$save bat=fog
24968         local jobid_old=$($LCTL get_param -n foe $testname bag)
24969         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
24970 }
24971 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
24972
24973 test_401c() {
24974         # jobid_var may not allow arbitrary values, so use jobid_name
24975         # if available
24976         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24977                 local testname=jobid_name
24978         else
24979                 local testname=jobid_var
24980         fi
24981
24982         local jobid_var_old=$($LCTL get_param -n $testname)
24983         local jobid_var_new
24984
24985         $LCTL set_param $testname= &&
24986                 error "no error returned for 'set_param a='"
24987
24988         jobid_var_new=$($LCTL get_param -n $testname)
24989         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24990                 error "$testname was changed by setting without value"
24991
24992         $LCTL set_param $testname &&
24993                 error "no error returned for 'set_param a'"
24994
24995         jobid_var_new=$($LCTL get_param -n $testname)
24996         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24997                 error "$testname was changed by setting without value"
24998 }
24999 run_test 401c "Verify 'lctl set_param' without value fails in either format."
25000
25001 test_401d() {
25002         # jobid_var may not allow arbitrary values, so use jobid_name
25003         # if available
25004         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25005                 local testname=jobid_name new_value='foo=bar%p'
25006         else
25007                 local testname=jobid_var new_valuie=foo=bar
25008         fi
25009
25010         local jobid_var_old=$($LCTL get_param -n $testname)
25011         local jobid_var_new
25012
25013         $LCTL set_param $testname=$new_value ||
25014                 error "'set_param a=b' did not accept a value containing '='"
25015
25016         jobid_var_new=$($LCTL get_param -n $testname)
25017         [[ "$jobid_var_new" == "$new_value" ]] ||
25018                 error "'set_param a=b' failed on a value containing '='"
25019
25020         # Reset the $testname to test the other format
25021         $LCTL set_param $testname=$jobid_var_old
25022         jobid_var_new=$($LCTL get_param -n $testname)
25023         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25024                 error "failed to reset $testname"
25025
25026         $LCTL set_param $testname $new_value ||
25027                 error "'set_param a b' did not accept a value containing '='"
25028
25029         jobid_var_new=$($LCTL get_param -n $testname)
25030         [[ "$jobid_var_new" == "$new_value" ]] ||
25031                 error "'set_param a b' failed on a value containing '='"
25032
25033         $LCTL set_param $testname $jobid_var_old
25034         jobid_var_new=$($LCTL get_param -n $testname)
25035         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25036                 error "failed to reset $testname"
25037 }
25038 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
25039
25040 test_401e() { # LU-14779
25041         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
25042                 error "lctl list_param MGC* failed"
25043         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
25044         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
25045                 error "lctl get_param lru_size failed"
25046 }
25047 run_test 401e "verify 'lctl get_param' works with NID in parameter"
25048
25049 test_402() {
25050         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
25051         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
25052                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
25053         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
25054                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
25055                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
25056         remote_mds_nodsh && skip "remote MDS with nodsh"
25057
25058         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
25059 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
25060         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
25061         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
25062                 echo "Touch failed - OK"
25063 }
25064 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
25065
25066 test_403() {
25067         local file1=$DIR/$tfile.1
25068         local file2=$DIR/$tfile.2
25069         local tfile=$TMP/$tfile
25070
25071         rm -f $file1 $file2 $tfile
25072
25073         touch $file1
25074         ln $file1 $file2
25075
25076         # 30 sec OBD_TIMEOUT in ll_getattr()
25077         # right before populating st_nlink
25078         $LCTL set_param fail_loc=0x80001409
25079         stat -c %h $file1 > $tfile &
25080
25081         # create an alias, drop all locks and reclaim the dentry
25082         < $file2
25083         cancel_lru_locks mdc
25084         cancel_lru_locks osc
25085         sysctl -w vm.drop_caches=2
25086
25087         wait
25088
25089         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25090
25091         rm -f $tfile $file1 $file2
25092 }
25093 run_test 403 "i_nlink should not drop to zero due to aliasing"
25094
25095 test_404() { # LU-6601
25096         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25097                 skip "Need server version newer than 2.8.52"
25098         remote_mds_nodsh && skip "remote MDS with nodsh"
25099
25100         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25101                 awk '/osp .*-osc-MDT/ { print $4}')
25102
25103         local osp
25104         for osp in $mosps; do
25105                 echo "Deactivate: " $osp
25106                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25107                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25108                         awk -vp=$osp '$4 == p { print $2 }')
25109                 [ $stat = IN ] || {
25110                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25111                         error "deactivate error"
25112                 }
25113                 echo "Activate: " $osp
25114                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25115                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25116                         awk -vp=$osp '$4 == p { print $2 }')
25117                 [ $stat = UP ] || {
25118                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25119                         error "activate error"
25120                 }
25121         done
25122 }
25123 run_test 404 "validate manual {de}activated works properly for OSPs"
25124
25125 test_405() {
25126         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25127         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25128                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25129                         skip "Layout swap lock is not supported"
25130
25131         check_swap_layouts_support
25132         check_swap_layout_no_dom $DIR
25133
25134         test_mkdir $DIR/$tdir
25135         swap_lock_test -d $DIR/$tdir ||
25136                 error "One layout swap locked test failed"
25137 }
25138 run_test 405 "Various layout swap lock tests"
25139
25140 test_406() {
25141         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25142         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25143         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25145         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25146                 skip "Need MDS version at least 2.8.50"
25147
25148         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25149         local test_pool=$TESTNAME
25150
25151         pool_add $test_pool || error "pool_add failed"
25152         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25153                 error "pool_add_targets failed"
25154
25155         save_layout_restore_at_exit $MOUNT
25156
25157         # parent set default stripe count only, child will stripe from both
25158         # parent and fs default
25159         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25160                 error "setstripe $MOUNT failed"
25161         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25162         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25163         for i in $(seq 10); do
25164                 local f=$DIR/$tdir/$tfile.$i
25165                 touch $f || error "touch failed"
25166                 local count=$($LFS getstripe -c $f)
25167                 [ $count -eq $OSTCOUNT ] ||
25168                         error "$f stripe count $count != $OSTCOUNT"
25169                 local offset=$($LFS getstripe -i $f)
25170                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25171                 local size=$($LFS getstripe -S $f)
25172                 [ $size -eq $((def_stripe_size * 2)) ] ||
25173                         error "$f stripe size $size != $((def_stripe_size * 2))"
25174                 local pool=$($LFS getstripe -p $f)
25175                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25176         done
25177
25178         # change fs default striping, delete parent default striping, now child
25179         # will stripe from new fs default striping only
25180         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25181                 error "change $MOUNT default stripe failed"
25182         $LFS setstripe -c 0 $DIR/$tdir ||
25183                 error "delete $tdir default stripe failed"
25184         for i in $(seq 11 20); do
25185                 local f=$DIR/$tdir/$tfile.$i
25186                 touch $f || error "touch $f failed"
25187                 local count=$($LFS getstripe -c $f)
25188                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25189                 local offset=$($LFS getstripe -i $f)
25190                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25191                 local size=$($LFS getstripe -S $f)
25192                 [ $size -eq $def_stripe_size ] ||
25193                         error "$f stripe size $size != $def_stripe_size"
25194                 local pool=$($LFS getstripe -p $f)
25195                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25196         done
25197
25198         unlinkmany $DIR/$tdir/$tfile. 1 20
25199
25200         local f=$DIR/$tdir/$tfile
25201         pool_remove_all_targets $test_pool $f
25202         pool_remove $test_pool $f
25203 }
25204 run_test 406 "DNE support fs default striping"
25205
25206 test_407() {
25207         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25208         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25209                 skip "Need MDS version at least 2.8.55"
25210         remote_mds_nodsh && skip "remote MDS with nodsh"
25211
25212         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25213                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25214         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25215                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25216         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25217
25218         #define OBD_FAIL_DT_TXN_STOP    0x2019
25219         for idx in $(seq $MDSCOUNT); do
25220                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25221         done
25222         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25223         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25224                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25225         true
25226 }
25227 run_test 407 "transaction fail should cause operation fail"
25228
25229 test_408() {
25230         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25231
25232         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25233         lctl set_param fail_loc=0x8000040a
25234         # let ll_prepare_partial_page() fail
25235         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25236
25237         rm -f $DIR/$tfile
25238
25239         # create at least 100 unused inodes so that
25240         # shrink_icache_memory(0) should not return 0
25241         touch $DIR/$tfile-{0..100}
25242         rm -f $DIR/$tfile-{0..100}
25243         sync
25244
25245         echo 2 > /proc/sys/vm/drop_caches
25246 }
25247 run_test 408 "drop_caches should not hang due to page leaks"
25248
25249 test_409()
25250 {
25251         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25252
25253         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25254         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25255         touch $DIR/$tdir/guard || error "(2) Fail to create"
25256
25257         local PREFIX=$(str_repeat 'A' 128)
25258         echo "Create 1K hard links start at $(date)"
25259         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25260                 error "(3) Fail to hard link"
25261
25262         echo "Links count should be right although linkEA overflow"
25263         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25264         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25265         [ $linkcount -eq 1001 ] ||
25266                 error "(5) Unexpected hard links count: $linkcount"
25267
25268         echo "List all links start at $(date)"
25269         ls -l $DIR/$tdir/foo > /dev/null ||
25270                 error "(6) Fail to list $DIR/$tdir/foo"
25271
25272         echo "Unlink hard links start at $(date)"
25273         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25274                 error "(7) Fail to unlink"
25275         echo "Unlink hard links finished at $(date)"
25276 }
25277 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25278
25279 test_410()
25280 {
25281         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25282                 skip "Need client version at least 2.9.59"
25283         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25284                 skip "Need MODULES build"
25285
25286         # Create a file, and stat it from the kernel
25287         local testfile=$DIR/$tfile
25288         touch $testfile
25289
25290         local run_id=$RANDOM
25291         local my_ino=$(stat --format "%i" $testfile)
25292
25293         # Try to insert the module. This will always fail as the
25294         # module is designed to not be inserted.
25295         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25296             &> /dev/null
25297
25298         # Anything but success is a test failure
25299         dmesg | grep -q \
25300             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25301             error "no inode match"
25302 }
25303 run_test 410 "Test inode number returned from kernel thread"
25304
25305 cleanup_test411_cgroup() {
25306         trap 0
25307         rmdir "$1"
25308 }
25309
25310 test_411() {
25311         local cg_basedir=/sys/fs/cgroup/memory
25312         # LU-9966
25313         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25314                 skip "no setup for cgroup"
25315
25316         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25317                 error "test file creation failed"
25318         cancel_lru_locks osc
25319
25320         # Create a very small memory cgroup to force a slab allocation error
25321         local cgdir=$cg_basedir/osc_slab_alloc
25322         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25323         trap "cleanup_test411_cgroup $cgdir" EXIT
25324         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25325         echo 1M > $cgdir/memory.limit_in_bytes
25326
25327         # Should not LBUG, just be killed by oom-killer
25328         # dd will return 0 even allocation failure in some environment.
25329         # So don't check return value
25330         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25331         cleanup_test411_cgroup $cgdir
25332
25333         return 0
25334 }
25335 run_test 411 "Slab allocation error with cgroup does not LBUG"
25336
25337 test_412() {
25338         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25339         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25340                 skip "Need server version at least 2.10.55"
25341
25342         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25343                 error "mkdir failed"
25344         $LFS getdirstripe $DIR/$tdir
25345         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25346         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25347                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25348         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25349         [ $stripe_count -eq 2 ] ||
25350                 error "expect 2 get $stripe_count"
25351
25352         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25353
25354         local index
25355         local index2
25356
25357         # subdirs should be on the same MDT as parent
25358         for i in $(seq 0 $((MDSCOUNT - 1))); do
25359                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25360                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25361                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25362                 (( index == i )) || error "mdt$i/sub on MDT$index"
25363         done
25364
25365         # stripe offset -1, ditto
25366         for i in {1..10}; do
25367                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25368                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25369                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25370                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25371                 (( index == index2 )) ||
25372                         error "qos$i on MDT$index, sub on MDT$index2"
25373         done
25374
25375         local testdir=$DIR/$tdir/inherit
25376
25377         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25378         # inherit 2 levels
25379         for i in 1 2; do
25380                 testdir=$testdir/s$i
25381                 mkdir $testdir || error "mkdir $testdir failed"
25382                 index=$($LFS getstripe -m $testdir)
25383                 (( index == 1 )) ||
25384                         error "$testdir on MDT$index"
25385         done
25386
25387         # not inherit any more
25388         testdir=$testdir/s3
25389         mkdir $testdir || error "mkdir $testdir failed"
25390         getfattr -d -m dmv $testdir | grep dmv &&
25391                 error "default LMV set on $testdir" || true
25392 }
25393 run_test 412 "mkdir on specific MDTs"
25394
25395 generate_uneven_mdts() {
25396         local threshold=$1
25397         local lmv_qos_maxage
25398         local lod_qos_maxage
25399         local ffree
25400         local bavail
25401         local max
25402         local min
25403         local max_index
25404         local min_index
25405         local tmp
25406         local i
25407
25408         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25409         $LCTL set_param lmv.*.qos_maxage=1
25410         stack_trap "$LCTL set_param \
25411                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25412         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25413                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25414         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25415                 lod.*.mdt_qos_maxage=1
25416         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25417                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25418
25419         echo
25420         echo "Check for uneven MDTs: "
25421
25422         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25423         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25424         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25425
25426         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25427         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25428         max_index=0
25429         min_index=0
25430         for ((i = 1; i < ${#ffree[@]}; i++)); do
25431                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25432                 if [ $tmp -gt $max ]; then
25433                         max=$tmp
25434                         max_index=$i
25435                 fi
25436                 if [ $tmp -lt $min ]; then
25437                         min=$tmp
25438                         min_index=$i
25439                 fi
25440         done
25441
25442         (( ${ffree[min_index]} > 0 )) ||
25443                 skip "no free files in MDT$min_index"
25444         (( ${ffree[min_index]} < 10000000 )) ||
25445                 skip "too many free files in MDT$min_index"
25446
25447         # Check if we need to generate uneven MDTs
25448         local diff=$(((max - min) * 100 / min))
25449         local testdir=$DIR/$tdir-fillmdt
25450         local start
25451
25452         mkdir -p $testdir
25453
25454         i=0
25455         while (( diff < threshold )); do
25456                 # generate uneven MDTs, create till $threshold% diff
25457                 echo -n "weight diff=$diff% must be > $threshold% ..."
25458                 echo "Fill MDT$min_index with 1000 files: loop $i"
25459                 testdir=$DIR/$tdir-fillmdt/$i
25460                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
25461                         error "mkdir $testdir failed"
25462                 $LFS setstripe -E 1M -L mdt $testdir ||
25463                         error "setstripe $testdir failed"
25464                 start=$SECONDS
25465                 for F in f.{0..999}; do
25466                         dd if=/dev/zero of=$testdir/$F bs=64K count=1 > \
25467                                 /dev/null 2>&1 || error "dd $F failed"
25468                 done
25469
25470                 # wait for QOS to update
25471                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25472
25473                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25474                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25475                 max=$(((${ffree[max_index]} >> 8) *
25476                         (${bavail[max_index]} * bsize >> 16)))
25477                 min=$(((${ffree[min_index]} >> 8) *
25478                         (${bavail[min_index]} * bsize >> 16)))
25479                 diff=$(((max - min) * 100 / min))
25480                 i=$((i + 1))
25481         done
25482
25483         echo "MDT filesfree available: ${ffree[*]}"
25484         echo "MDT blocks available: ${bavail[*]}"
25485         echo "weight diff=$diff%"
25486 }
25487
25488 test_qos_mkdir() {
25489         local mkdir_cmd=$1
25490         local stripe_count=$2
25491         local mdts=$(comma_list $(mdts_nodes))
25492
25493         local testdir
25494         local lmv_qos_prio_free
25495         local lmv_qos_threshold_rr
25496         local lmv_qos_maxage
25497         local lod_qos_prio_free
25498         local lod_qos_threshold_rr
25499         local lod_qos_maxage
25500         local count
25501         local i
25502
25503         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25504         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25505         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25506                 head -n1)
25507         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25508         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25509         stack_trap "$LCTL set_param \
25510                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25511         stack_trap "$LCTL set_param \
25512                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25513         stack_trap "$LCTL set_param \
25514                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25515
25516         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25517                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25518         lod_qos_prio_free=${lod_qos_prio_free%%%}
25519         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25520                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25521         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25522         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25523                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25524         stack_trap "do_nodes $mdts $LCTL set_param \
25525                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25526         stack_trap "do_nodes $mdts $LCTL set_param \
25527                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25528         stack_trap "do_nodes $mdts $LCTL set_param \
25529                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25530
25531         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25532         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25533
25534         testdir=$DIR/$tdir-s$stripe_count/rr
25535
25536         local stripe_index=$($LFS getstripe -m $testdir)
25537         local test_mkdir_rr=true
25538
25539         getfattr -d -m dmv -e hex $testdir | grep dmv
25540         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25541                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25542                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25543                         test_mkdir_rr=false
25544         fi
25545
25546         echo
25547         $test_mkdir_rr &&
25548                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25549                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25550
25551         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25552         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25553                 eval $mkdir_cmd $testdir/subdir$i ||
25554                         error "$mkdir_cmd subdir$i failed"
25555         done
25556
25557         for (( i = 0; i < $MDSCOUNT; i++ )); do
25558                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25559                 echo "$count directories created on MDT$i"
25560                 if $test_mkdir_rr; then
25561                         (( $count == 100 )) ||
25562                                 error "subdirs are not evenly distributed"
25563                 elif (( $i == $stripe_index )); then
25564                         (( $count == 100 * MDSCOUNT )) ||
25565                                 error "$count subdirs created on MDT$i"
25566                 else
25567                         (( $count == 0 )) ||
25568                                 error "$count subdirs created on MDT$i"
25569                 fi
25570
25571                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25572                         count=$($LFS getdirstripe $testdir/* |
25573                                 grep -c -P "^\s+$i\t")
25574                         echo "$count stripes created on MDT$i"
25575                         # deviation should < 5% of average
25576                         (( $count >= 95 * stripe_count &&
25577                            $count <= 105 * stripe_count)) ||
25578                                 error "stripes are not evenly distributed"
25579                 fi
25580         done
25581
25582         echo
25583         echo "Check for uneven MDTs: "
25584
25585         local ffree
25586         local bavail
25587         local max
25588         local min
25589         local max_index
25590         local min_index
25591         local tmp
25592
25593         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25594         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25595         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25596
25597         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25598         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25599         max_index=0
25600         min_index=0
25601         for ((i = 1; i < ${#ffree[@]}; i++)); do
25602                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25603                 if [ $tmp -gt $max ]; then
25604                         max=$tmp
25605                         max_index=$i
25606                 fi
25607                 if [ $tmp -lt $min ]; then
25608                         min=$tmp
25609                         min_index=$i
25610                 fi
25611         done
25612
25613         (( ${ffree[min_index]} > 0 )) ||
25614                 skip "no free files in MDT$min_index"
25615         (( ${ffree[min_index]} < 10000000 )) ||
25616                 skip "too many free files in MDT$min_index"
25617
25618         echo "MDT filesfree available: ${ffree[*]}"
25619         echo "MDT blocks available: ${bavail[*]}"
25620         echo "weight diff=$(((max - min) * 100 / min))%"
25621         echo
25622         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25623
25624         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25625         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25626         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25627         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25628         # decrease statfs age, so that it can be updated in time
25629         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25630         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25631
25632         sleep 1
25633
25634         testdir=$DIR/$tdir-s$stripe_count/qos
25635         local num=200
25636
25637         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25638         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25639                 eval $mkdir_cmd $testdir/subdir$i ||
25640                         error "$mkdir_cmd subdir$i failed"
25641         done
25642
25643         max=0
25644         for (( i = 0; i < $MDSCOUNT; i++ )); do
25645                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25646                 (( count > max )) && max=$count
25647                 echo "$count directories created on MDT$i"
25648         done
25649
25650         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25651
25652         # D-value should > 10% of averge
25653         (( max - min > num / 10 )) ||
25654                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25655
25656         # ditto for stripes
25657         if (( stripe_count > 1 )); then
25658                 max=0
25659                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25660                         count=$($LFS getdirstripe $testdir/* |
25661                                 grep -c -P "^\s+$i\t")
25662                         (( count > max )) && max=$count
25663                         echo "$count stripes created on MDT$i"
25664                 done
25665
25666                 min=$($LFS getdirstripe $testdir/* |
25667                         grep -c -P "^\s+$min_index\t")
25668                 (( max - min > num * stripe_count / 10 )) ||
25669                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25670         fi
25671 }
25672
25673 most_full_mdt() {
25674         local ffree
25675         local bavail
25676         local bsize
25677         local min
25678         local min_index
25679         local tmp
25680
25681         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25682         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25683         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25684
25685         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25686         min_index=0
25687         for ((i = 1; i < ${#ffree[@]}; i++)); do
25688                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25689                 (( tmp < min )) && min=$tmp && min_index=$i
25690         done
25691
25692         echo -n $min_index
25693 }
25694
25695 test_413a() {
25696         [ $MDSCOUNT -lt 2 ] &&
25697                 skip "We need at least 2 MDTs for this test"
25698
25699         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25700                 skip "Need server version at least 2.12.52"
25701
25702         local stripe_count
25703
25704         generate_uneven_mdts 100
25705         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25706                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25707                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25708                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25709                         error "mkdir failed"
25710                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25711         done
25712 }
25713 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25714
25715 test_413b() {
25716         [ $MDSCOUNT -lt 2 ] &&
25717                 skip "We need at least 2 MDTs for this test"
25718
25719         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25720                 skip "Need server version at least 2.12.52"
25721
25722         local testdir
25723         local stripe_count
25724
25725         generate_uneven_mdts 100
25726         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25727                 testdir=$DIR/$tdir-s$stripe_count
25728                 mkdir $testdir || error "mkdir $testdir failed"
25729                 mkdir $testdir/rr || error "mkdir rr failed"
25730                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25731                         error "mkdir qos failed"
25732                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25733                         $testdir/rr || error "setdirstripe rr failed"
25734                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25735                         error "setdirstripe failed"
25736                 test_qos_mkdir "mkdir" $stripe_count
25737         done
25738 }
25739 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25740
25741 test_413c() {
25742         (( $MDSCOUNT >= 2 )) ||
25743                 skip "We need at least 2 MDTs for this test"
25744
25745         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25746                 skip "Need server version at least 2.14.51"
25747
25748         local testdir
25749         local inherit
25750         local inherit_rr
25751
25752         testdir=$DIR/${tdir}-s1
25753         mkdir $testdir || error "mkdir $testdir failed"
25754         mkdir $testdir/rr || error "mkdir rr failed"
25755         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25756         # default max_inherit is -1, default max_inherit_rr is 0
25757         $LFS setdirstripe -D -c 1 $testdir/rr ||
25758                 error "setdirstripe rr failed"
25759         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25760                 error "setdirstripe qos failed"
25761         test_qos_mkdir "mkdir" 1
25762
25763         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25764         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25765         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25766         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25767         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25768
25769         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25770         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25771         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25772         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25773         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25774         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25775         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25776                 error "level2 shouldn't have default LMV" || true
25777 }
25778 run_test 413c "mkdir with default LMV max inherit rr"
25779
25780 test_413d() {
25781         (( MDSCOUNT >= 2 )) ||
25782                 skip "We need at least 2 MDTs for this test"
25783
25784         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25785                 skip "Need server version at least 2.14.51"
25786
25787         local lmv_qos_threshold_rr
25788
25789         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25790                 head -n1)
25791         stack_trap "$LCTL set_param \
25792                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
25793
25794         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25795         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25796         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
25797                 error "$tdir shouldn't have default LMV"
25798         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
25799                 error "mkdir sub failed"
25800
25801         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
25802
25803         (( count == 100 )) || error "$count subdirs on MDT0"
25804 }
25805 run_test 413d "inherit ROOT default LMV"
25806
25807 test_413e() {
25808         (( MDSCOUNT >= 2 )) ||
25809                 skip "We need at least 2 MDTs for this test"
25810         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25811                 skip "Need server version at least 2.14.55"
25812
25813         local testdir=$DIR/$tdir
25814         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
25815         local max_inherit
25816         local sub_max_inherit
25817
25818         mkdir -p $testdir || error "failed to create $testdir"
25819
25820         # set default max-inherit to -1 if stripe count is 0 or 1
25821         $LFS setdirstripe -D -c 1 $testdir ||
25822                 error "failed to set default LMV"
25823         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25824         (( max_inherit == -1 )) ||
25825                 error "wrong max_inherit value $max_inherit"
25826
25827         # set default max_inherit to a fixed value if stripe count is not 0 or 1
25828         $LFS setdirstripe -D -c -1 $testdir ||
25829                 error "failed to set default LMV"
25830         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25831         (( max_inherit > 0 )) ||
25832                 error "wrong max_inherit value $max_inherit"
25833
25834         # and the subdir will decrease the max_inherit by 1
25835         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
25836         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
25837         (( sub_max_inherit == max_inherit - 1)) ||
25838                 error "wrong max-inherit of subdir $sub_max_inherit"
25839
25840         # check specified --max-inherit and warning message
25841         stack_trap "rm -f $tmpfile"
25842         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
25843                 error "failed to set default LMV"
25844         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25845         (( max_inherit == -1 )) ||
25846                 error "wrong max_inherit value $max_inherit"
25847
25848         # check the warning messages
25849         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
25850                 error "failed to detect warning string"
25851         fi
25852 }
25853 run_test 413e "check default max-inherit value"
25854
25855 test_413f() {
25856         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
25857
25858         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25859                 skip "Need server version at least 2.14.55"
25860
25861         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
25862                 error "dump $DIR default LMV failed"
25863         stack_trap "setfattr --restore=$TMP/dmv.ea"
25864
25865         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
25866                 error "set $DIR default LMV failed"
25867
25868         local testdir=$DIR/$tdir
25869
25870         local count
25871         local inherit
25872         local inherit_rr
25873
25874         for i in $(seq 3); do
25875                 mkdir $testdir || error "mkdir $testdir failed"
25876                 count=$($LFS getdirstripe -D -c $testdir)
25877                 (( count == 1 )) ||
25878                         error "$testdir default LMV count mismatch $count != 1"
25879                 inherit=$($LFS getdirstripe -D -X $testdir)
25880                 (( inherit == 3 - i )) ||
25881                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
25882                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
25883                 (( inherit_rr == 3 - i )) ||
25884                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
25885                 testdir=$testdir/sub
25886         done
25887
25888         mkdir $testdir || error "mkdir $testdir failed"
25889         count=$($LFS getdirstripe -D -c $testdir)
25890         (( count == 0 )) ||
25891                 error "$testdir default LMV count not zero: $count"
25892 }
25893 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
25894
25895 test_413z() {
25896         local pids=""
25897         local subdir
25898         local pid
25899
25900         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
25901                 unlinkmany $subdir/f. 1000 &
25902                 pids="$pids $!"
25903         done
25904
25905         for pid in $pids; do
25906                 wait $pid
25907         done
25908 }
25909 run_test 413z "413 test cleanup"
25910
25911 test_414() {
25912 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
25913         $LCTL set_param fail_loc=0x80000521
25914         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25915         rm -f $DIR/$tfile
25916 }
25917 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
25918
25919 test_415() {
25920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25921         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25922                 skip "Need server version at least 2.11.52"
25923
25924         # LU-11102
25925         local total
25926         local setattr_pid
25927         local start_time
25928         local end_time
25929         local duration
25930
25931         total=500
25932         # this test may be slow on ZFS
25933         [ "$mds1_FSTYPE" == "zfs" ] && total=50
25934
25935         # though this test is designed for striped directory, let's test normal
25936         # directory too since lock is always saved as CoS lock.
25937         test_mkdir $DIR/$tdir || error "mkdir $tdir"
25938         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
25939
25940         (
25941                 while true; do
25942                         touch $DIR/$tdir
25943                 done
25944         ) &
25945         setattr_pid=$!
25946
25947         start_time=$(date +%s)
25948         for i in $(seq $total); do
25949                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
25950                         > /dev/null
25951         done
25952         end_time=$(date +%s)
25953         duration=$((end_time - start_time))
25954
25955         kill -9 $setattr_pid
25956
25957         echo "rename $total files took $duration sec"
25958         [ $duration -lt 100 ] || error "rename took $duration sec"
25959 }
25960 run_test 415 "lock revoke is not missing"
25961
25962 test_416() {
25963         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25964                 skip "Need server version at least 2.11.55"
25965
25966         # define OBD_FAIL_OSD_TXN_START    0x19a
25967         do_facet mds1 lctl set_param fail_loc=0x19a
25968
25969         lfs mkdir -c $MDSCOUNT $DIR/$tdir
25970
25971         true
25972 }
25973 run_test 416 "transaction start failure won't cause system hung"
25974
25975 cleanup_417() {
25976         trap 0
25977         do_nodes $(comma_list $(mdts_nodes)) \
25978                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
25979         do_nodes $(comma_list $(mdts_nodes)) \
25980                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
25981         do_nodes $(comma_list $(mdts_nodes)) \
25982                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
25983 }
25984
25985 test_417() {
25986         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25987         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
25988                 skip "Need MDS version at least 2.11.56"
25989
25990         trap cleanup_417 RETURN EXIT
25991
25992         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
25993         do_nodes $(comma_list $(mdts_nodes)) \
25994                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
25995         $LFS migrate -m 0 $DIR/$tdir.1 &&
25996                 error "migrate dir $tdir.1 should fail"
25997
25998         do_nodes $(comma_list $(mdts_nodes)) \
25999                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
26000         $LFS mkdir -i 1 $DIR/$tdir.2 &&
26001                 error "create remote dir $tdir.2 should fail"
26002
26003         do_nodes $(comma_list $(mdts_nodes)) \
26004                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
26005         $LFS mkdir -c 2 $DIR/$tdir.3 &&
26006                 error "create striped dir $tdir.3 should fail"
26007         true
26008 }
26009 run_test 417 "disable remote dir, striped dir and dir migration"
26010
26011 # Checks that the outputs of df [-i] and lfs df [-i] match
26012 #
26013 # usage: check_lfs_df <blocks | inodes> <mountpoint>
26014 check_lfs_df() {
26015         local dir=$2
26016         local inodes
26017         local df_out
26018         local lfs_df_out
26019         local count
26020         local passed=false
26021
26022         # blocks or inodes
26023         [ "$1" == "blocks" ] && inodes= || inodes="-i"
26024
26025         for count in {1..100}; do
26026                 do_nodes "$CLIENTS" \
26027                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26028                 sync; sleep 0.2
26029
26030                 # read the lines of interest
26031                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
26032                         error "df $inodes $dir | tail -n +2 failed"
26033                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
26034                         error "lfs df $inodes $dir | grep summary: failed"
26035
26036                 # skip first substrings of each output as they are different
26037                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
26038                 # compare the two outputs
26039                 passed=true
26040                 #  skip "available" on MDT until LU-13997 is fixed.
26041                 #for i in {1..5}; do
26042                 for i in 1 2 4 5; do
26043                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
26044                 done
26045                 $passed && break
26046         done
26047
26048         if ! $passed; then
26049                 df -P $inodes $dir
26050                 echo
26051                 lfs df $inodes $dir
26052                 error "df and lfs df $1 output mismatch: "      \
26053                       "df ${inodes}: ${df_out[*]}, "            \
26054                       "lfs df ${inodes}: ${lfs_df_out[*]}"
26055         fi
26056 }
26057
26058 test_418() {
26059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26060
26061         local dir=$DIR/$tdir
26062         local numfiles=$((RANDOM % 4096 + 2))
26063         local numblocks=$((RANDOM % 256 + 1))
26064
26065         wait_delete_completed
26066         test_mkdir $dir
26067
26068         # check block output
26069         check_lfs_df blocks $dir
26070         # check inode output
26071         check_lfs_df inodes $dir
26072
26073         # create a single file and retest
26074         echo "Creating a single file and testing"
26075         createmany -o $dir/$tfile- 1 &>/dev/null ||
26076                 error "creating 1 file in $dir failed"
26077         check_lfs_df blocks $dir
26078         check_lfs_df inodes $dir
26079
26080         # create a random number of files
26081         echo "Creating $((numfiles - 1)) files and testing"
26082         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
26083                 error "creating $((numfiles - 1)) files in $dir failed"
26084
26085         # write a random number of blocks to the first test file
26086         echo "Writing $numblocks 4K blocks and testing"
26087         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26088                 count=$numblocks &>/dev/null ||
26089                 error "dd to $dir/${tfile}-0 failed"
26090
26091         # retest
26092         check_lfs_df blocks $dir
26093         check_lfs_df inodes $dir
26094
26095         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
26096                 error "unlinking $numfiles files in $dir failed"
26097 }
26098 run_test 418 "df and lfs df outputs match"
26099
26100 test_419()
26101 {
26102         local dir=$DIR/$tdir
26103
26104         mkdir -p $dir
26105         touch $dir/file
26106
26107         cancel_lru_locks mdc
26108
26109         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26110         $LCTL set_param fail_loc=0x1410
26111         cat $dir/file
26112         $LCTL set_param fail_loc=0
26113         rm -rf $dir
26114 }
26115 run_test 419 "Verify open file by name doesn't crash kernel"
26116
26117 test_420()
26118 {
26119         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26120                 skip "Need MDS version at least 2.12.53"
26121
26122         local SAVE_UMASK=$(umask)
26123         local dir=$DIR/$tdir
26124         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26125
26126         mkdir -p $dir
26127         umask 0000
26128         mkdir -m03777 $dir/testdir
26129         ls -dn $dir/testdir
26130         # Need to remove trailing '.' when SELinux is enabled
26131         local dirperms=$(ls -dn $dir/testdir |
26132                          awk '{ sub(/\.$/, "", $1); print $1}')
26133         [ $dirperms == "drwxrwsrwt" ] ||
26134                 error "incorrect perms on $dir/testdir"
26135
26136         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26137                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26138         ls -n $dir/testdir/testfile
26139         local fileperms=$(ls -n $dir/testdir/testfile |
26140                           awk '{ sub(/\.$/, "", $1); print $1}')
26141         [ $fileperms == "-rwxr-xr-x" ] ||
26142                 error "incorrect perms on $dir/testdir/testfile"
26143
26144         umask $SAVE_UMASK
26145 }
26146 run_test 420 "clear SGID bit on non-directories for non-members"
26147
26148 test_421a() {
26149         local cnt
26150         local fid1
26151         local fid2
26152
26153         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26154                 skip "Need MDS version at least 2.12.54"
26155
26156         test_mkdir $DIR/$tdir
26157         createmany -o $DIR/$tdir/f 3
26158         cnt=$(ls -1 $DIR/$tdir | wc -l)
26159         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26160
26161         fid1=$(lfs path2fid $DIR/$tdir/f1)
26162         fid2=$(lfs path2fid $DIR/$tdir/f2)
26163         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26164
26165         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26166         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26167
26168         cnt=$(ls -1 $DIR/$tdir | wc -l)
26169         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26170
26171         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26172         createmany -o $DIR/$tdir/f 3
26173         cnt=$(ls -1 $DIR/$tdir | wc -l)
26174         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26175
26176         fid1=$(lfs path2fid $DIR/$tdir/f1)
26177         fid2=$(lfs path2fid $DIR/$tdir/f2)
26178         echo "remove using fsname $FSNAME"
26179         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26180
26181         cnt=$(ls -1 $DIR/$tdir | wc -l)
26182         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26183 }
26184 run_test 421a "simple rm by fid"
26185
26186 test_421b() {
26187         local cnt
26188         local FID1
26189         local FID2
26190
26191         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26192                 skip "Need MDS version at least 2.12.54"
26193
26194         test_mkdir $DIR/$tdir
26195         createmany -o $DIR/$tdir/f 3
26196         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26197         MULTIPID=$!
26198
26199         FID1=$(lfs path2fid $DIR/$tdir/f1)
26200         FID2=$(lfs path2fid $DIR/$tdir/f2)
26201         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26202
26203         kill -USR1 $MULTIPID
26204         wait
26205
26206         cnt=$(ls $DIR/$tdir | wc -l)
26207         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26208 }
26209 run_test 421b "rm by fid on open file"
26210
26211 test_421c() {
26212         local cnt
26213         local FIDS
26214
26215         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26216                 skip "Need MDS version at least 2.12.54"
26217
26218         test_mkdir $DIR/$tdir
26219         createmany -o $DIR/$tdir/f 3
26220         touch $DIR/$tdir/$tfile
26221         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26222         cnt=$(ls -1 $DIR/$tdir | wc -l)
26223         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26224
26225         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26226         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26227
26228         cnt=$(ls $DIR/$tdir | wc -l)
26229         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26230 }
26231 run_test 421c "rm by fid against hardlinked files"
26232
26233 test_421d() {
26234         local cnt
26235         local FIDS
26236
26237         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26238                 skip "Need MDS version at least 2.12.54"
26239
26240         test_mkdir $DIR/$tdir
26241         createmany -o $DIR/$tdir/f 4097
26242         cnt=$(ls -1 $DIR/$tdir | wc -l)
26243         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26244
26245         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26246         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26247
26248         cnt=$(ls $DIR/$tdir | wc -l)
26249         rm -rf $DIR/$tdir
26250         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26251 }
26252 run_test 421d "rmfid en masse"
26253
26254 test_421e() {
26255         local cnt
26256         local FID
26257
26258         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26259         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26260                 skip "Need MDS version at least 2.12.54"
26261
26262         mkdir -p $DIR/$tdir
26263         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26264         createmany -o $DIR/$tdir/striped_dir/f 512
26265         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26266         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26267
26268         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26269                 sed "s/[/][^:]*://g")
26270         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26271
26272         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26273         rm -rf $DIR/$tdir
26274         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26275 }
26276 run_test 421e "rmfid in DNE"
26277
26278 test_421f() {
26279         local cnt
26280         local FID
26281
26282         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26283                 skip "Need MDS version at least 2.12.54"
26284
26285         test_mkdir $DIR/$tdir
26286         touch $DIR/$tdir/f
26287         cnt=$(ls -1 $DIR/$tdir | wc -l)
26288         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26289
26290         FID=$(lfs path2fid $DIR/$tdir/f)
26291         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26292         # rmfid should fail
26293         cnt=$(ls -1 $DIR/$tdir | wc -l)
26294         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26295
26296         chmod a+rw $DIR/$tdir
26297         ls -la $DIR/$tdir
26298         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26299         # rmfid should fail
26300         cnt=$(ls -1 $DIR/$tdir | wc -l)
26301         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26302
26303         rm -f $DIR/$tdir/f
26304         $RUNAS touch $DIR/$tdir/f
26305         FID=$(lfs path2fid $DIR/$tdir/f)
26306         echo "rmfid as root"
26307         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26308         cnt=$(ls -1 $DIR/$tdir | wc -l)
26309         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26310
26311         rm -f $DIR/$tdir/f
26312         $RUNAS touch $DIR/$tdir/f
26313         cnt=$(ls -1 $DIR/$tdir | wc -l)
26314         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26315         FID=$(lfs path2fid $DIR/$tdir/f)
26316         # rmfid w/o user_fid2path mount option should fail
26317         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26318         cnt=$(ls -1 $DIR/$tdir | wc -l)
26319         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26320
26321         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26322         stack_trap "rmdir $tmpdir"
26323         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26324                 error "failed to mount client'"
26325         stack_trap "umount_client $tmpdir"
26326
26327         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26328         # rmfid should succeed
26329         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26330         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26331
26332         # rmfid shouldn't allow to remove files due to dir's permission
26333         chmod a+rwx $tmpdir/$tdir
26334         touch $tmpdir/$tdir/f
26335         ls -la $tmpdir/$tdir
26336         FID=$(lfs path2fid $tmpdir/$tdir/f)
26337         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26338         return 0
26339 }
26340 run_test 421f "rmfid checks permissions"
26341
26342 test_421g() {
26343         local cnt
26344         local FIDS
26345
26346         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26347         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26348                 skip "Need MDS version at least 2.12.54"
26349
26350         mkdir -p $DIR/$tdir
26351         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26352         createmany -o $DIR/$tdir/striped_dir/f 512
26353         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26354         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26355
26356         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26357                 sed "s/[/][^:]*://g")
26358
26359         rm -f $DIR/$tdir/striped_dir/f1*
26360         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26361         removed=$((512 - cnt))
26362
26363         # few files have been just removed, so we expect
26364         # rmfid to fail on their fids
26365         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26366         [ $removed != $errors ] && error "$errors != $removed"
26367
26368         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26369         rm -rf $DIR/$tdir
26370         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26371 }
26372 run_test 421g "rmfid to return errors properly"
26373
26374 test_422() {
26375         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26376         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26377         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26378         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26379         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26380
26381         local amc=$(at_max_get client)
26382         local amo=$(at_max_get mds1)
26383         local timeout=`lctl get_param -n timeout`
26384
26385         at_max_set 0 client
26386         at_max_set 0 mds1
26387
26388 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26389         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26390                         fail_val=$(((2*timeout + 10)*1000))
26391         touch $DIR/$tdir/d3/file &
26392         sleep 2
26393 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26394         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26395                         fail_val=$((2*timeout + 5))
26396         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26397         local pid=$!
26398         sleep 1
26399         kill -9 $pid
26400         sleep $((2 * timeout))
26401         echo kill $pid
26402         kill -9 $pid
26403         lctl mark touch
26404         touch $DIR/$tdir/d2/file3
26405         touch $DIR/$tdir/d2/file4
26406         touch $DIR/$tdir/d2/file5
26407
26408         wait
26409         at_max_set $amc client
26410         at_max_set $amo mds1
26411
26412         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26413         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26414                 error "Watchdog is always throttled"
26415 }
26416 run_test 422 "kill a process with RPC in progress"
26417
26418 stat_test() {
26419     df -h $MOUNT &
26420     df -h $MOUNT &
26421     df -h $MOUNT &
26422     df -h $MOUNT &
26423     df -h $MOUNT &
26424     df -h $MOUNT &
26425 }
26426
26427 test_423() {
26428     local _stats
26429     # ensure statfs cache is expired
26430     sleep 2;
26431
26432     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26433     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26434
26435     return 0
26436 }
26437 run_test 423 "statfs should return a right data"
26438
26439 test_424() {
26440 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26441         $LCTL set_param fail_loc=0x80000522
26442         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26443         rm -f $DIR/$tfile
26444 }
26445 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26446
26447 test_425() {
26448         test_mkdir -c -1 $DIR/$tdir
26449         $LFS setstripe -c -1 $DIR/$tdir
26450
26451         lru_resize_disable "" 100
26452         stack_trap "lru_resize_enable" EXIT
26453
26454         sleep 5
26455
26456         for i in $(seq $((MDSCOUNT * 125))); do
26457                 local t=$DIR/$tdir/$tfile_$i
26458
26459                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26460                         error_noexit "Create file $t"
26461         done
26462         stack_trap "rm -rf $DIR/$tdir" EXIT
26463
26464         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26465                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26466                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26467
26468                 [ $lock_count -le $lru_size ] ||
26469                         error "osc lock count $lock_count > lru size $lru_size"
26470         done
26471
26472         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26473                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26474                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26475
26476                 [ $lock_count -le $lru_size ] ||
26477                         error "mdc lock count $lock_count > lru size $lru_size"
26478         done
26479 }
26480 run_test 425 "lock count should not exceed lru size"
26481
26482 test_426() {
26483         splice-test -r $DIR/$tfile
26484         splice-test -rd $DIR/$tfile
26485         splice-test $DIR/$tfile
26486         splice-test -d $DIR/$tfile
26487 }
26488 run_test 426 "splice test on Lustre"
26489
26490 test_427() {
26491         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26492         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26493                 skip "Need MDS version at least 2.12.4"
26494         local log
26495
26496         mkdir $DIR/$tdir
26497         mkdir $DIR/$tdir/1
26498         mkdir $DIR/$tdir/2
26499         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26500         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26501
26502         $LFS getdirstripe $DIR/$tdir/1/dir
26503
26504         #first setfattr for creating updatelog
26505         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26506
26507 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26508         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26509         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26510         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26511
26512         sleep 2
26513         fail mds2
26514         wait_recovery_complete mds2 $((2*TIMEOUT))
26515
26516         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26517         echo $log | grep "get update log failed" &&
26518                 error "update log corruption is detected" || true
26519 }
26520 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26521
26522 test_428() {
26523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26524         local cache_limit=$CACHE_MAX
26525
26526         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26527         $LCTL set_param -n llite.*.max_cached_mb=64
26528
26529         mkdir $DIR/$tdir
26530         $LFS setstripe -c 1 $DIR/$tdir
26531         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26532         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26533         #test write
26534         for f in $(seq 4); do
26535                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26536         done
26537         wait
26538
26539         cancel_lru_locks osc
26540         # Test read
26541         for f in $(seq 4); do
26542                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26543         done
26544         wait
26545 }
26546 run_test 428 "large block size IO should not hang"
26547
26548 test_429() { # LU-7915 / LU-10948
26549         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26550         local testfile=$DIR/$tfile
26551         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26552         local new_flag=1
26553         local first_rpc
26554         local second_rpc
26555         local third_rpc
26556
26557         $LCTL get_param $ll_opencache_threshold_count ||
26558                 skip "client does not have opencache parameter"
26559
26560         set_opencache $new_flag
26561         stack_trap "restore_opencache"
26562         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26563                 error "enable opencache failed"
26564         touch $testfile
26565         # drop MDC DLM locks
26566         cancel_lru_locks mdc
26567         # clear MDC RPC stats counters
26568         $LCTL set_param $mdc_rpcstats=clear
26569
26570         # According to the current implementation, we need to run 3 times
26571         # open & close file to verify if opencache is enabled correctly.
26572         # 1st, RPCs are sent for lookup/open and open handle is released on
26573         #      close finally.
26574         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26575         #      so open handle won't be released thereafter.
26576         # 3rd, No RPC is sent out.
26577         $MULTIOP $testfile oc || error "multiop failed"
26578         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26579         echo "1st: $first_rpc RPCs in flight"
26580
26581         $MULTIOP $testfile oc || error "multiop failed"
26582         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26583         echo "2nd: $second_rpc RPCs in flight"
26584
26585         $MULTIOP $testfile oc || error "multiop failed"
26586         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26587         echo "3rd: $third_rpc RPCs in flight"
26588
26589         #verify no MDC RPC is sent
26590         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26591 }
26592 run_test 429 "verify if opencache flag on client side does work"
26593
26594 lseek_test_430() {
26595         local offset
26596         local file=$1
26597
26598         # data at [200K, 400K)
26599         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26600                 error "256K->512K dd fails"
26601         # data at [2M, 3M)
26602         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26603                 error "2M->3M dd fails"
26604         # data at [4M, 5M)
26605         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26606                 error "4M->5M dd fails"
26607         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26608         # start at first component hole #1
26609         printf "Seeking hole from 1000 ... "
26610         offset=$(lseek_test -l 1000 $file)
26611         echo $offset
26612         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26613         printf "Seeking data from 1000 ... "
26614         offset=$(lseek_test -d 1000 $file)
26615         echo $offset
26616         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26617
26618         # start at first component data block
26619         printf "Seeking hole from 300000 ... "
26620         offset=$(lseek_test -l 300000 $file)
26621         echo $offset
26622         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26623         printf "Seeking data from 300000 ... "
26624         offset=$(lseek_test -d 300000 $file)
26625         echo $offset
26626         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26627
26628         # start at the first component but beyond end of object size
26629         printf "Seeking hole from 1000000 ... "
26630         offset=$(lseek_test -l 1000000 $file)
26631         echo $offset
26632         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26633         printf "Seeking data from 1000000 ... "
26634         offset=$(lseek_test -d 1000000 $file)
26635         echo $offset
26636         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26637
26638         # start at second component stripe 2 (empty file)
26639         printf "Seeking hole from 1500000 ... "
26640         offset=$(lseek_test -l 1500000 $file)
26641         echo $offset
26642         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26643         printf "Seeking data from 1500000 ... "
26644         offset=$(lseek_test -d 1500000 $file)
26645         echo $offset
26646         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26647
26648         # start at second component stripe 1 (all data)
26649         printf "Seeking hole from 3000000 ... "
26650         offset=$(lseek_test -l 3000000 $file)
26651         echo $offset
26652         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26653         printf "Seeking data from 3000000 ... "
26654         offset=$(lseek_test -d 3000000 $file)
26655         echo $offset
26656         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26657
26658         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26659                 error "2nd dd fails"
26660         echo "Add data block at 640K...1280K"
26661
26662         # start at before new data block, in hole
26663         printf "Seeking hole from 600000 ... "
26664         offset=$(lseek_test -l 600000 $file)
26665         echo $offset
26666         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26667         printf "Seeking data from 600000 ... "
26668         offset=$(lseek_test -d 600000 $file)
26669         echo $offset
26670         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26671
26672         # start at the first component new data block
26673         printf "Seeking hole from 1000000 ... "
26674         offset=$(lseek_test -l 1000000 $file)
26675         echo $offset
26676         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26677         printf "Seeking data from 1000000 ... "
26678         offset=$(lseek_test -d 1000000 $file)
26679         echo $offset
26680         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26681
26682         # start at second component stripe 2, new data
26683         printf "Seeking hole from 1200000 ... "
26684         offset=$(lseek_test -l 1200000 $file)
26685         echo $offset
26686         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26687         printf "Seeking data from 1200000 ... "
26688         offset=$(lseek_test -d 1200000 $file)
26689         echo $offset
26690         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
26691
26692         # start beyond file end
26693         printf "Using offset > filesize ... "
26694         lseek_test -l 4000000 $file && error "lseek should fail"
26695         printf "Using offset > filesize ... "
26696         lseek_test -d 4000000 $file && error "lseek should fail"
26697
26698         printf "Done\n\n"
26699 }
26700
26701 test_430a() {
26702         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
26703                 skip "MDT does not support SEEK_HOLE"
26704
26705         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26706                 skip "OST does not support SEEK_HOLE"
26707
26708         local file=$DIR/$tdir/$tfile
26709
26710         mkdir -p $DIR/$tdir
26711
26712         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
26713         # OST stripe #1 will have continuous data at [1M, 3M)
26714         # OST stripe #2 is empty
26715         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
26716         lseek_test_430 $file
26717         rm $file
26718         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
26719         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
26720         lseek_test_430 $file
26721         rm $file
26722         $LFS setstripe -c2 -S 512K $file
26723         echo "Two stripes, stripe size 512K"
26724         lseek_test_430 $file
26725         rm $file
26726         # FLR with stale mirror
26727         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
26728                        -N -c2 -S 1M $file
26729         echo "Mirrored file:"
26730         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
26731         echo "Plain 2 stripes 1M"
26732         lseek_test_430 $file
26733         rm $file
26734 }
26735 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
26736
26737 test_430b() {
26738         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26739                 skip "OST does not support SEEK_HOLE"
26740
26741         local offset
26742         local file=$DIR/$tdir/$tfile
26743
26744         mkdir -p $DIR/$tdir
26745         # Empty layout lseek should fail
26746         $MCREATE $file
26747         # seek from 0
26748         printf "Seeking hole from 0 ... "
26749         lseek_test -l 0 $file && error "lseek should fail"
26750         printf "Seeking data from 0 ... "
26751         lseek_test -d 0 $file && error "lseek should fail"
26752         rm $file
26753
26754         # 1M-hole file
26755         $LFS setstripe -E 1M -c2 -E eof $file
26756         $TRUNCATE $file 1048576
26757         printf "Seeking hole from 1000000 ... "
26758         offset=$(lseek_test -l 1000000 $file)
26759         echo $offset
26760         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26761         printf "Seeking data from 1000000 ... "
26762         lseek_test -d 1000000 $file && error "lseek should fail"
26763         rm $file
26764
26765         # full component followed by non-inited one
26766         $LFS setstripe -E 1M -c2 -E eof $file
26767         dd if=/dev/urandom of=$file bs=1M count=1
26768         printf "Seeking hole from 1000000 ... "
26769         offset=$(lseek_test -l 1000000 $file)
26770         echo $offset
26771         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26772         printf "Seeking hole from 1048576 ... "
26773         lseek_test -l 1048576 $file && error "lseek should fail"
26774         # init second component and truncate back
26775         echo "123" >> $file
26776         $TRUNCATE $file 1048576
26777         printf "Seeking hole from 1000000 ... "
26778         offset=$(lseek_test -l 1000000 $file)
26779         echo $offset
26780         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26781         printf "Seeking hole from 1048576 ... "
26782         lseek_test -l 1048576 $file && error "lseek should fail"
26783         # boundary checks for big values
26784         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
26785         offset=$(lseek_test -d 0 $file.10g)
26786         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
26787         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
26788         offset=$(lseek_test -d 0 $file.100g)
26789         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
26790         return 0
26791 }
26792 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
26793
26794 test_430c() {
26795         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26796                 skip "OST does not support SEEK_HOLE"
26797
26798         local file=$DIR/$tdir/$tfile
26799         local start
26800
26801         mkdir -p $DIR/$tdir
26802         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
26803
26804         # cp version 8.33+ prefers lseek over fiemap
26805         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
26806                 start=$SECONDS
26807                 time cp $file /dev/null
26808                 (( SECONDS - start < 5 )) ||
26809                         error "cp: too long runtime $((SECONDS - start))"
26810
26811         fi
26812         # tar version 1.29+ supports SEEK_HOLE/DATA
26813         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
26814                 start=$SECONDS
26815                 time tar cS $file - | cat > /dev/null
26816                 (( SECONDS - start < 5 )) ||
26817                         error "tar: too long runtime $((SECONDS - start))"
26818         fi
26819 }
26820 run_test 430c "lseek: external tools check"
26821
26822 test_431() { # LU-14187
26823         local file=$DIR/$tdir/$tfile
26824
26825         mkdir -p $DIR/$tdir
26826         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
26827         dd if=/dev/urandom of=$file bs=4k count=1
26828         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
26829         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
26830         #define OBD_FAIL_OST_RESTART_IO 0x251
26831         do_facet ost1 "$LCTL set_param fail_loc=0x251"
26832         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
26833         cp $file $file.0
26834         cancel_lru_locks
26835         sync_all_data
26836         echo 3 > /proc/sys/vm/drop_caches
26837         diff  $file $file.0 || error "data diff"
26838 }
26839 run_test 431 "Restart transaction for IO"
26840
26841 cleanup_test_432() {
26842         do_facet mgs $LCTL nodemap_activate 0
26843         wait_nm_sync active
26844 }
26845
26846 test_432() {
26847         local tmpdir=$TMP/dir432
26848
26849         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
26850                 skip "Need MDS version at least 2.14.52"
26851
26852         stack_trap cleanup_test_432 EXIT
26853         mkdir $DIR/$tdir
26854         mkdir $tmpdir
26855
26856         do_facet mgs $LCTL nodemap_activate 1
26857         wait_nm_sync active
26858         do_facet mgs $LCTL nodemap_modify --name default \
26859                 --property admin --value 1
26860         do_facet mgs $LCTL nodemap_modify --name default \
26861                 --property trusted --value 1
26862         cancel_lru_locks mdc
26863         wait_nm_sync default admin_nodemap
26864         wait_nm_sync default trusted_nodemap
26865
26866         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
26867                grep -ci "Operation not permitted") -ne 0 ]; then
26868                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
26869         fi
26870 }
26871 run_test 432 "mv dir from outside Lustre"
26872
26873 test_433() {
26874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26875
26876         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
26877                 skip "inode cache not supported"
26878
26879         $LCTL set_param llite.*.inode_cache=0
26880         stack_trap "$LCTL set_param llite.*.inode_cache=1"
26881
26882         local count=256
26883         local before
26884         local after
26885
26886         cancel_lru_locks mdc
26887         test_mkdir $DIR/$tdir || error "mkdir $tdir"
26888         createmany -m $DIR/$tdir/f $count
26889         createmany -d $DIR/$tdir/d $count
26890         ls -l $DIR/$tdir > /dev/null
26891         stack_trap "rm -rf $DIR/$tdir"
26892
26893         before=$(num_objects)
26894         cancel_lru_locks mdc
26895         after=$(num_objects)
26896
26897         # sometimes even @before is less than 2 * count
26898         while (( before - after < count )); do
26899                 sleep 1
26900                 after=$(num_objects)
26901                 wait=$((wait + 1))
26902                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
26903                 if (( wait > 60 )); then
26904                         error "inode slab grew from $before to $after"
26905                 fi
26906         done
26907
26908         echo "lustre_inode_cache $before objs before lock cancel, $after after"
26909 }
26910 run_test 433 "ldlm lock cancel releases dentries and inodes"
26911
26912 prep_801() {
26913         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26914         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26915                 skip "Need server version at least 2.9.55"
26916
26917         start_full_debug_logging
26918 }
26919
26920 post_801() {
26921         stop_full_debug_logging
26922 }
26923
26924 barrier_stat() {
26925         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26926                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26927                            awk '/The barrier for/ { print $7 }')
26928                 echo $st
26929         else
26930                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
26931                 echo \'$st\'
26932         fi
26933 }
26934
26935 barrier_expired() {
26936         local expired
26937
26938         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26939                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26940                           awk '/will be expired/ { print $7 }')
26941         else
26942                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
26943         fi
26944
26945         echo $expired
26946 }
26947
26948 test_801a() {
26949         prep_801
26950
26951         echo "Start barrier_freeze at: $(date)"
26952         #define OBD_FAIL_BARRIER_DELAY          0x2202
26953         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26954         # Do not reduce barrier time - See LU-11873
26955         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
26956
26957         sleep 2
26958         local b_status=$(barrier_stat)
26959         echo "Got barrier status at: $(date)"
26960         [ "$b_status" = "'freezing_p1'" ] ||
26961                 error "(1) unexpected barrier status $b_status"
26962
26963         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26964         wait
26965         b_status=$(barrier_stat)
26966         [ "$b_status" = "'frozen'" ] ||
26967                 error "(2) unexpected barrier status $b_status"
26968
26969         local expired=$(barrier_expired)
26970         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
26971         sleep $((expired + 3))
26972
26973         b_status=$(barrier_stat)
26974         [ "$b_status" = "'expired'" ] ||
26975                 error "(3) unexpected barrier status $b_status"
26976
26977         # Do not reduce barrier time - See LU-11873
26978         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
26979                 error "(4) fail to freeze barrier"
26980
26981         b_status=$(barrier_stat)
26982         [ "$b_status" = "'frozen'" ] ||
26983                 error "(5) unexpected barrier status $b_status"
26984
26985         echo "Start barrier_thaw at: $(date)"
26986         #define OBD_FAIL_BARRIER_DELAY          0x2202
26987         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26988         do_facet mgs $LCTL barrier_thaw $FSNAME &
26989
26990         sleep 2
26991         b_status=$(barrier_stat)
26992         echo "Got barrier status at: $(date)"
26993         [ "$b_status" = "'thawing'" ] ||
26994                 error "(6) unexpected barrier status $b_status"
26995
26996         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26997         wait
26998         b_status=$(barrier_stat)
26999         [ "$b_status" = "'thawed'" ] ||
27000                 error "(7) unexpected barrier status $b_status"
27001
27002         #define OBD_FAIL_BARRIER_FAILURE        0x2203
27003         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
27004         do_facet mgs $LCTL barrier_freeze $FSNAME
27005
27006         b_status=$(barrier_stat)
27007         [ "$b_status" = "'failed'" ] ||
27008                 error "(8) unexpected barrier status $b_status"
27009
27010         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
27011         do_facet mgs $LCTL barrier_thaw $FSNAME
27012
27013         post_801
27014 }
27015 run_test 801a "write barrier user interfaces and stat machine"
27016
27017 test_801b() {
27018         prep_801
27019
27020         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27021         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
27022         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
27023         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
27024         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
27025
27026         cancel_lru_locks mdc
27027
27028         # 180 seconds should be long enough
27029         do_facet mgs $LCTL barrier_freeze $FSNAME 180
27030
27031         local b_status=$(barrier_stat)
27032         [ "$b_status" = "'frozen'" ] ||
27033                 error "(6) unexpected barrier status $b_status"
27034
27035         mkdir $DIR/$tdir/d0/d10 &
27036         mkdir_pid=$!
27037
27038         touch $DIR/$tdir/d1/f13 &
27039         touch_pid=$!
27040
27041         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
27042         ln_pid=$!
27043
27044         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
27045         mv_pid=$!
27046
27047         rm -f $DIR/$tdir/d4/f12 &
27048         rm_pid=$!
27049
27050         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
27051
27052         # To guarantee taht the 'stat' is not blocked
27053         b_status=$(barrier_stat)
27054         [ "$b_status" = "'frozen'" ] ||
27055                 error "(8) unexpected barrier status $b_status"
27056
27057         # let above commands to run at background
27058         sleep 5
27059
27060         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
27061         ps -p $touch_pid || error "(10) touch should be blocked"
27062         ps -p $ln_pid || error "(11) link should be blocked"
27063         ps -p $mv_pid || error "(12) rename should be blocked"
27064         ps -p $rm_pid || error "(13) unlink should be blocked"
27065
27066         b_status=$(barrier_stat)
27067         [ "$b_status" = "'frozen'" ] ||
27068                 error "(14) unexpected barrier status $b_status"
27069
27070         do_facet mgs $LCTL barrier_thaw $FSNAME
27071         b_status=$(barrier_stat)
27072         [ "$b_status" = "'thawed'" ] ||
27073                 error "(15) unexpected barrier status $b_status"
27074
27075         wait $mkdir_pid || error "(16) mkdir should succeed"
27076         wait $touch_pid || error "(17) touch should succeed"
27077         wait $ln_pid || error "(18) link should succeed"
27078         wait $mv_pid || error "(19) rename should succeed"
27079         wait $rm_pid || error "(20) unlink should succeed"
27080
27081         post_801
27082 }
27083 run_test 801b "modification will be blocked by write barrier"
27084
27085 test_801c() {
27086         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27087
27088         prep_801
27089
27090         stop mds2 || error "(1) Fail to stop mds2"
27091
27092         do_facet mgs $LCTL barrier_freeze $FSNAME 30
27093
27094         local b_status=$(barrier_stat)
27095         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
27096                 do_facet mgs $LCTL barrier_thaw $FSNAME
27097                 error "(2) unexpected barrier status $b_status"
27098         }
27099
27100         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27101                 error "(3) Fail to rescan barrier bitmap"
27102
27103         # Do not reduce barrier time - See LU-11873
27104         do_facet mgs $LCTL barrier_freeze $FSNAME 20
27105
27106         b_status=$(barrier_stat)
27107         [ "$b_status" = "'frozen'" ] ||
27108                 error "(4) unexpected barrier status $b_status"
27109
27110         do_facet mgs $LCTL barrier_thaw $FSNAME
27111         b_status=$(barrier_stat)
27112         [ "$b_status" = "'thawed'" ] ||
27113                 error "(5) unexpected barrier status $b_status"
27114
27115         local devname=$(mdsdevname 2)
27116
27117         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
27118
27119         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27120                 error "(7) Fail to rescan barrier bitmap"
27121
27122         post_801
27123 }
27124 run_test 801c "rescan barrier bitmap"
27125
27126 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
27127 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
27128 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
27129 saved_MOUNT_OPTS=$MOUNT_OPTS
27130
27131 cleanup_802a() {
27132         trap 0
27133
27134         stopall
27135         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
27136         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
27137         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
27138         MOUNT_OPTS=$saved_MOUNT_OPTS
27139         setupall
27140 }
27141
27142 test_802a() {
27143         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
27144         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27145         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27146                 skip "Need server version at least 2.9.55"
27147
27148         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
27149
27150         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27151
27152         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27153                 error "(2) Fail to copy"
27154
27155         trap cleanup_802a EXIT
27156
27157         # sync by force before remount as readonly
27158         sync; sync_all_data; sleep 3; sync_all_data
27159
27160         stopall
27161
27162         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
27163         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
27164         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
27165
27166         echo "Mount the server as read only"
27167         setupall server_only || error "(3) Fail to start servers"
27168
27169         echo "Mount client without ro should fail"
27170         mount_client $MOUNT &&
27171                 error "(4) Mount client without 'ro' should fail"
27172
27173         echo "Mount client with ro should succeed"
27174         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
27175         mount_client $MOUNT ||
27176                 error "(5) Mount client with 'ro' should succeed"
27177
27178         echo "Modify should be refused"
27179         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27180
27181         echo "Read should be allowed"
27182         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27183                 error "(7) Read should succeed under ro mode"
27184
27185         cleanup_802a
27186 }
27187 run_test 802a "simulate readonly device"
27188
27189 test_802b() {
27190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27191         remote_mds_nodsh && skip "remote MDS with nodsh"
27192
27193         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27194                 skip "readonly option not available"
27195
27196         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27197
27198         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27199                 error "(2) Fail to copy"
27200
27201         # write back all cached data before setting MDT to readonly
27202         cancel_lru_locks
27203         sync_all_data
27204
27205         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27206         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27207
27208         echo "Modify should be refused"
27209         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27210
27211         echo "Read should be allowed"
27212         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27213                 error "(7) Read should succeed under ro mode"
27214
27215         # disable readonly
27216         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27217 }
27218 run_test 802b "be able to set MDTs to readonly"
27219
27220 test_803a() {
27221         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27222         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27223                 skip "MDS needs to be newer than 2.10.54"
27224
27225         mkdir_on_mdt0 $DIR/$tdir
27226         # Create some objects on all MDTs to trigger related logs objects
27227         for idx in $(seq $MDSCOUNT); do
27228                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27229                         $DIR/$tdir/dir${idx} ||
27230                         error "Fail to create $DIR/$tdir/dir${idx}"
27231         done
27232
27233         sync; sleep 3
27234         wait_delete_completed # ensure old test cleanups are finished
27235         echo "before create:"
27236         $LFS df -i $MOUNT
27237         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27238
27239         for i in {1..10}; do
27240                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27241                         error "Fail to create $DIR/$tdir/foo$i"
27242         done
27243
27244         sync; sleep 3
27245         echo "after create:"
27246         $LFS df -i $MOUNT
27247         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27248
27249         # allow for an llog to be cleaned up during the test
27250         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27251                 error "before ($before_used) + 10 > after ($after_used)"
27252
27253         for i in {1..10}; do
27254                 rm -rf $DIR/$tdir/foo$i ||
27255                         error "Fail to remove $DIR/$tdir/foo$i"
27256         done
27257
27258         sleep 3 # avoid MDT return cached statfs
27259         wait_delete_completed
27260         echo "after unlink:"
27261         $LFS df -i $MOUNT
27262         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27263
27264         # allow for an llog to be created during the test
27265         [ $after_used -le $((before_used + 1)) ] ||
27266                 error "after ($after_used) > before ($before_used) + 1"
27267 }
27268 run_test 803a "verify agent object for remote object"
27269
27270 test_803b() {
27271         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27272         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27273                 skip "MDS needs to be newer than 2.13.56"
27274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27275
27276         for i in $(seq 0 $((MDSCOUNT - 1))); do
27277                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27278         done
27279
27280         local before=0
27281         local after=0
27282
27283         local tmp
27284
27285         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27286         for i in $(seq 0 $((MDSCOUNT - 1))); do
27287                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27288                         awk '/getattr/ { print $2 }')
27289                 before=$((before + tmp))
27290         done
27291         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27292         for i in $(seq 0 $((MDSCOUNT - 1))); do
27293                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27294                         awk '/getattr/ { print $2 }')
27295                 after=$((after + tmp))
27296         done
27297
27298         [ $before -eq $after ] || error "getattr count $before != $after"
27299 }
27300 run_test 803b "remote object can getattr from cache"
27301
27302 test_804() {
27303         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27304         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27305                 skip "MDS needs to be newer than 2.10.54"
27306         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27307
27308         mkdir -p $DIR/$tdir
27309         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27310                 error "Fail to create $DIR/$tdir/dir0"
27311
27312         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27313         local dev=$(mdsdevname 2)
27314
27315         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27316                 grep ${fid} || error "NOT found agent entry for dir0"
27317
27318         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27319                 error "Fail to create $DIR/$tdir/dir1"
27320
27321         touch $DIR/$tdir/dir1/foo0 ||
27322                 error "Fail to create $DIR/$tdir/dir1/foo0"
27323         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27324         local rc=0
27325
27326         for idx in $(seq $MDSCOUNT); do
27327                 dev=$(mdsdevname $idx)
27328                 do_facet mds${idx} \
27329                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27330                         grep ${fid} && rc=$idx
27331         done
27332
27333         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27334                 error "Fail to rename foo0 to foo1"
27335         if [ $rc -eq 0 ]; then
27336                 for idx in $(seq $MDSCOUNT); do
27337                         dev=$(mdsdevname $idx)
27338                         do_facet mds${idx} \
27339                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27340                         grep ${fid} && rc=$idx
27341                 done
27342         fi
27343
27344         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27345                 error "Fail to rename foo1 to foo2"
27346         if [ $rc -eq 0 ]; then
27347                 for idx in $(seq $MDSCOUNT); do
27348                         dev=$(mdsdevname $idx)
27349                         do_facet mds${idx} \
27350                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27351                         grep ${fid} && rc=$idx
27352                 done
27353         fi
27354
27355         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27356
27357         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27358                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27359         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27360                 error "Fail to rename foo2 to foo0"
27361         unlink $DIR/$tdir/dir1/foo0 ||
27362                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27363         rm -rf $DIR/$tdir/dir0 ||
27364                 error "Fail to rm $DIR/$tdir/dir0"
27365
27366         for idx in $(seq $MDSCOUNT); do
27367                 rc=0
27368
27369                 stop mds${idx}
27370                 dev=$(mdsdevname $idx)
27371                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27372                         rc=$?
27373                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27374                         error "mount mds$idx failed"
27375                 df $MOUNT > /dev/null 2>&1
27376
27377                 # e2fsck should not return error
27378                 [ $rc -eq 0 ] ||
27379                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27380         done
27381 }
27382 run_test 804 "verify agent entry for remote entry"
27383
27384 cleanup_805() {
27385         do_facet $SINGLEMDS zfs set quota=$old $fsset
27386         unlinkmany $DIR/$tdir/f- 1000000
27387         trap 0
27388 }
27389
27390 test_805() {
27391         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
27392         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
27393         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
27394                 skip "netfree not implemented before 0.7"
27395         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
27396                 skip "Need MDS version at least 2.10.57"
27397
27398         local fsset
27399         local freekb
27400         local usedkb
27401         local old
27402         local quota
27403         local pref="osd-zfs.$FSNAME-MDT0000."
27404
27405         # limit available space on MDS dataset to meet nospace issue
27406         # quickly. then ZFS 0.7.2 can use reserved space if asked
27407         # properly (using netfree flag in osd_declare_destroy()
27408         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
27409         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
27410                 gawk '{print $3}')
27411         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
27412         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
27413         let "usedkb=usedkb-freekb"
27414         let "freekb=freekb/2"
27415         if let "freekb > 5000"; then
27416                 let "freekb=5000"
27417         fi
27418         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
27419         trap cleanup_805 EXIT
27420         mkdir_on_mdt0 $DIR/$tdir
27421         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
27422                 error "Can't set PFL layout"
27423         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27424         rm -rf $DIR/$tdir || error "not able to remove"
27425         do_facet $SINGLEMDS zfs set quota=$old $fsset
27426         trap 0
27427 }
27428 run_test 805 "ZFS can remove from full fs"
27429
27430 # Size-on-MDS test
27431 check_lsom_data()
27432 {
27433         local file=$1
27434         local expect=$(stat -c %s $file)
27435
27436         check_lsom_size $1 $expect
27437
27438         local blocks=$($LFS getsom -b $file)
27439         expect=$(stat -c %b $file)
27440         [[ $blocks == $expect ]] ||
27441                 error "$file expected blocks: $expect, got: $blocks"
27442 }
27443
27444 check_lsom_size()
27445 {
27446         local size
27447         local expect=$2
27448
27449         cancel_lru_locks mdc
27450
27451         size=$($LFS getsom -s $1)
27452         [[ $size == $expect ]] ||
27453                 error "$file expected size: $expect, got: $size"
27454 }
27455
27456 test_806() {
27457         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27458                 skip "Need MDS version at least 2.11.52"
27459
27460         local bs=1048576
27461
27462         touch $DIR/$tfile || error "touch $tfile failed"
27463
27464         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27465         save_lustre_params client "llite.*.xattr_cache" > $save
27466         lctl set_param llite.*.xattr_cache=0
27467         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27468
27469         # single-threaded write
27470         echo "Test SOM for single-threaded write"
27471         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27472                 error "write $tfile failed"
27473         check_lsom_size $DIR/$tfile $bs
27474
27475         local num=32
27476         local size=$(($num * $bs))
27477         local offset=0
27478         local i
27479
27480         echo "Test SOM for single client multi-threaded($num) write"
27481         $TRUNCATE $DIR/$tfile 0
27482         for ((i = 0; i < $num; i++)); do
27483                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27484                 local pids[$i]=$!
27485                 offset=$((offset + $bs))
27486         done
27487         for (( i=0; i < $num; i++ )); do
27488                 wait ${pids[$i]}
27489         done
27490         check_lsom_size $DIR/$tfile $size
27491
27492         $TRUNCATE $DIR/$tfile 0
27493         for ((i = 0; i < $num; i++)); do
27494                 offset=$((offset - $bs))
27495                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27496                 local pids[$i]=$!
27497         done
27498         for (( i=0; i < $num; i++ )); do
27499                 wait ${pids[$i]}
27500         done
27501         check_lsom_size $DIR/$tfile $size
27502
27503         # multi-client writes
27504         num=$(get_node_count ${CLIENTS//,/ })
27505         size=$(($num * $bs))
27506         offset=0
27507         i=0
27508
27509         echo "Test SOM for multi-client ($num) writes"
27510         $TRUNCATE $DIR/$tfile 0
27511         for client in ${CLIENTS//,/ }; do
27512                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27513                 local pids[$i]=$!
27514                 i=$((i + 1))
27515                 offset=$((offset + $bs))
27516         done
27517         for (( i=0; i < $num; i++ )); do
27518                 wait ${pids[$i]}
27519         done
27520         check_lsom_size $DIR/$tfile $offset
27521
27522         i=0
27523         $TRUNCATE $DIR/$tfile 0
27524         for client in ${CLIENTS//,/ }; do
27525                 offset=$((offset - $bs))
27526                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27527                 local pids[$i]=$!
27528                 i=$((i + 1))
27529         done
27530         for (( i=0; i < $num; i++ )); do
27531                 wait ${pids[$i]}
27532         done
27533         check_lsom_size $DIR/$tfile $size
27534
27535         # verify truncate
27536         echo "Test SOM for truncate"
27537         $TRUNCATE $DIR/$tfile 1048576
27538         check_lsom_size $DIR/$tfile 1048576
27539         $TRUNCATE $DIR/$tfile 1234
27540         check_lsom_size $DIR/$tfile 1234
27541
27542         # verify SOM blocks count
27543         echo "Verify SOM block count"
27544         $TRUNCATE $DIR/$tfile 0
27545         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27546                 error "failed to write file $tfile"
27547         check_lsom_data $DIR/$tfile
27548 }
27549 run_test 806 "Verify Lazy Size on MDS"
27550
27551 test_807() {
27552         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27553         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27554                 skip "Need MDS version at least 2.11.52"
27555
27556         # Registration step
27557         changelog_register || error "changelog_register failed"
27558         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27559         changelog_users $SINGLEMDS | grep -q $cl_user ||
27560                 error "User $cl_user not found in changelog_users"
27561
27562         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27563         save_lustre_params client "llite.*.xattr_cache" > $save
27564         lctl set_param llite.*.xattr_cache=0
27565         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27566
27567         rm -rf $DIR/$tdir || error "rm $tdir failed"
27568         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27569         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27570         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27571         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27572                 error "truncate $tdir/trunc failed"
27573
27574         local bs=1048576
27575         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27576                 error "write $tfile failed"
27577
27578         # multi-client wirtes
27579         local num=$(get_node_count ${CLIENTS//,/ })
27580         local offset=0
27581         local i=0
27582
27583         echo "Test SOM for multi-client ($num) writes"
27584         touch $DIR/$tfile || error "touch $tfile failed"
27585         $TRUNCATE $DIR/$tfile 0
27586         for client in ${CLIENTS//,/ }; do
27587                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27588                 local pids[$i]=$!
27589                 i=$((i + 1))
27590                 offset=$((offset + $bs))
27591         done
27592         for (( i=0; i < $num; i++ )); do
27593                 wait ${pids[$i]}
27594         done
27595
27596         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27597         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27598         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27599         check_lsom_data $DIR/$tdir/trunc
27600         check_lsom_data $DIR/$tdir/single_dd
27601         check_lsom_data $DIR/$tfile
27602
27603         rm -rf $DIR/$tdir
27604         # Deregistration step
27605         changelog_deregister || error "changelog_deregister failed"
27606 }
27607 run_test 807 "verify LSOM syncing tool"
27608
27609 check_som_nologged()
27610 {
27611         local lines=$($LFS changelog $FSNAME-MDT0000 |
27612                 grep 'x=trusted.som' | wc -l)
27613         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27614 }
27615
27616 test_808() {
27617         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27618                 skip "Need MDS version at least 2.11.55"
27619
27620         # Registration step
27621         changelog_register || error "changelog_register failed"
27622
27623         touch $DIR/$tfile || error "touch $tfile failed"
27624         check_som_nologged
27625
27626         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27627                 error "write $tfile failed"
27628         check_som_nologged
27629
27630         $TRUNCATE $DIR/$tfile 1234
27631         check_som_nologged
27632
27633         $TRUNCATE $DIR/$tfile 1048576
27634         check_som_nologged
27635
27636         # Deregistration step
27637         changelog_deregister || error "changelog_deregister failed"
27638 }
27639 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27640
27641 check_som_nodata()
27642 {
27643         $LFS getsom $1
27644         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27645 }
27646
27647 test_809() {
27648         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27649                 skip "Need MDS version at least 2.11.56"
27650
27651         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27652                 error "failed to create DoM-only file $DIR/$tfile"
27653         touch $DIR/$tfile || error "touch $tfile failed"
27654         check_som_nodata $DIR/$tfile
27655
27656         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27657                 error "write $tfile failed"
27658         check_som_nodata $DIR/$tfile
27659
27660         $TRUNCATE $DIR/$tfile 1234
27661         check_som_nodata $DIR/$tfile
27662
27663         $TRUNCATE $DIR/$tfile 4097
27664         check_som_nodata $DIR/$file
27665 }
27666 run_test 809 "Verify no SOM xattr store for DoM-only files"
27667
27668 test_810() {
27669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27670         $GSS && skip_env "could not run with gss"
27671         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27672                 skip "OST < 2.12.58 doesn't align checksum"
27673
27674         set_checksums 1
27675         stack_trap "set_checksums $ORIG_CSUM" EXIT
27676         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27677
27678         local csum
27679         local before
27680         local after
27681         for csum in $CKSUM_TYPES; do
27682                 #define OBD_FAIL_OSC_NO_GRANT   0x411
27683                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
27684                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
27685                         eval set -- $i
27686                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
27687                         before=$(md5sum $DIR/$tfile)
27688                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
27689                         after=$(md5sum $DIR/$tfile)
27690                         [ "$before" == "$after" ] ||
27691                                 error "$csum: $before != $after bs=$1 seek=$2"
27692                 done
27693         done
27694 }
27695 run_test 810 "partial page writes on ZFS (LU-11663)"
27696
27697 test_812a() {
27698         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27699                 skip "OST < 2.12.51 doesn't support this fail_loc"
27700
27701         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27702         # ensure ost1 is connected
27703         stat $DIR/$tfile >/dev/null || error "can't stat"
27704         wait_osc_import_state client ost1 FULL
27705         # no locks, no reqs to let the connection idle
27706         cancel_lru_locks osc
27707
27708         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27709 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27710         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27711         wait_osc_import_state client ost1 CONNECTING
27712         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27713
27714         stat $DIR/$tfile >/dev/null || error "can't stat file"
27715 }
27716 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
27717
27718 test_812b() { # LU-12378
27719         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27720                 skip "OST < 2.12.51 doesn't support this fail_loc"
27721
27722         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
27723         # ensure ost1 is connected
27724         stat $DIR/$tfile >/dev/null || error "can't stat"
27725         wait_osc_import_state client ost1 FULL
27726         # no locks, no reqs to let the connection idle
27727         cancel_lru_locks osc
27728
27729         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27730 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27731         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27732         wait_osc_import_state client ost1 CONNECTING
27733         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27734
27735         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
27736         wait_osc_import_state client ost1 IDLE
27737 }
27738 run_test 812b "do not drop no resend request for idle connect"
27739
27740 test_812c() {
27741         local old
27742
27743         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
27744
27745         $LFS setstripe -c 1 -o 0 $DIR/$tfile
27746         $LFS getstripe $DIR/$tfile
27747         $LCTL set_param osc.*.idle_timeout=10
27748         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
27749         # ensure ost1 is connected
27750         stat $DIR/$tfile >/dev/null || error "can't stat"
27751         wait_osc_import_state client ost1 FULL
27752         # no locks, no reqs to let the connection idle
27753         cancel_lru_locks osc
27754
27755 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
27756         $LCTL set_param fail_loc=0x80000533
27757         sleep 15
27758         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
27759 }
27760 run_test 812c "idle import vs lock enqueue race"
27761
27762 test_813() {
27763         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
27764         [ -z "$file_heat_sav" ] && skip "no file heat support"
27765
27766         local readsample
27767         local writesample
27768         local readbyte
27769         local writebyte
27770         local readsample1
27771         local writesample1
27772         local readbyte1
27773         local writebyte1
27774
27775         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
27776         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
27777
27778         $LCTL set_param -n llite.*.file_heat=1
27779         echo "Turn on file heat"
27780         echo "Period second: $period_second, Decay percentage: $decay_pct"
27781
27782         echo "QQQQ" > $DIR/$tfile
27783         echo "QQQQ" > $DIR/$tfile
27784         echo "QQQQ" > $DIR/$tfile
27785         cat $DIR/$tfile > /dev/null
27786         cat $DIR/$tfile > /dev/null
27787         cat $DIR/$tfile > /dev/null
27788         cat $DIR/$tfile > /dev/null
27789
27790         local out=$($LFS heat_get $DIR/$tfile)
27791
27792         $LFS heat_get $DIR/$tfile
27793         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27794         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27795         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27796         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27797
27798         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
27799         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
27800         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
27801         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
27802
27803         sleep $((period_second + 3))
27804         echo "Sleep $((period_second + 3)) seconds..."
27805         # The recursion formula to calculate the heat of the file f is as
27806         # follow:
27807         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
27808         # Where Hi is the heat value in the period between time points i*I and
27809         # (i+1)*I; Ci is the access count in the period; the symbol P refers
27810         # to the weight of Ci.
27811         out=$($LFS heat_get $DIR/$tfile)
27812         $LFS heat_get $DIR/$tfile
27813         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27814         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27815         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27816         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27817
27818         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
27819                 error "read sample ($readsample) is wrong"
27820         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
27821                 error "write sample ($writesample) is wrong"
27822         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
27823                 error "read bytes ($readbyte) is wrong"
27824         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
27825                 error "write bytes ($writebyte) is wrong"
27826
27827         echo "QQQQ" > $DIR/$tfile
27828         echo "QQQQ" > $DIR/$tfile
27829         echo "QQQQ" > $DIR/$tfile
27830         cat $DIR/$tfile > /dev/null
27831         cat $DIR/$tfile > /dev/null
27832         cat $DIR/$tfile > /dev/null
27833         cat $DIR/$tfile > /dev/null
27834
27835         sleep $((period_second + 3))
27836         echo "Sleep $((period_second + 3)) seconds..."
27837
27838         out=$($LFS heat_get $DIR/$tfile)
27839         $LFS heat_get $DIR/$tfile
27840         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27841         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27842         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27843         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27844
27845         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
27846                 4 * $decay_pct) / 100") -eq 1 ] ||
27847                 error "read sample ($readsample1) is wrong"
27848         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
27849                 3 * $decay_pct) / 100") -eq 1 ] ||
27850                 error "write sample ($writesample1) is wrong"
27851         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
27852                 20 * $decay_pct) / 100") -eq 1 ] ||
27853                 error "read bytes ($readbyte1) is wrong"
27854         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
27855                 15 * $decay_pct) / 100") -eq 1 ] ||
27856                 error "write bytes ($writebyte1) is wrong"
27857
27858         echo "Turn off file heat for the file $DIR/$tfile"
27859         $LFS heat_set -o $DIR/$tfile
27860
27861         echo "QQQQ" > $DIR/$tfile
27862         echo "QQQQ" > $DIR/$tfile
27863         echo "QQQQ" > $DIR/$tfile
27864         cat $DIR/$tfile > /dev/null
27865         cat $DIR/$tfile > /dev/null
27866         cat $DIR/$tfile > /dev/null
27867         cat $DIR/$tfile > /dev/null
27868
27869         out=$($LFS heat_get $DIR/$tfile)
27870         $LFS heat_get $DIR/$tfile
27871         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27872         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27873         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27874         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27875
27876         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27877         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27878         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27879         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27880
27881         echo "Trun on file heat for the file $DIR/$tfile"
27882         $LFS heat_set -O $DIR/$tfile
27883
27884         echo "QQQQ" > $DIR/$tfile
27885         echo "QQQQ" > $DIR/$tfile
27886         echo "QQQQ" > $DIR/$tfile
27887         cat $DIR/$tfile > /dev/null
27888         cat $DIR/$tfile > /dev/null
27889         cat $DIR/$tfile > /dev/null
27890         cat $DIR/$tfile > /dev/null
27891
27892         out=$($LFS heat_get $DIR/$tfile)
27893         $LFS heat_get $DIR/$tfile
27894         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27895         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27896         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27897         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27898
27899         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
27900         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
27901         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
27902         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
27903
27904         $LFS heat_set -c $DIR/$tfile
27905         $LCTL set_param -n llite.*.file_heat=0
27906         echo "Turn off file heat support for the Lustre filesystem"
27907
27908         echo "QQQQ" > $DIR/$tfile
27909         echo "QQQQ" > $DIR/$tfile
27910         echo "QQQQ" > $DIR/$tfile
27911         cat $DIR/$tfile > /dev/null
27912         cat $DIR/$tfile > /dev/null
27913         cat $DIR/$tfile > /dev/null
27914         cat $DIR/$tfile > /dev/null
27915
27916         out=$($LFS heat_get $DIR/$tfile)
27917         $LFS heat_get $DIR/$tfile
27918         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27919         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27920         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27921         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27922
27923         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27924         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27925         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27926         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27927
27928         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
27929         rm -f $DIR/$tfile
27930 }
27931 run_test 813 "File heat verfication"
27932
27933 test_814()
27934 {
27935         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
27936         echo -n y >> $DIR/$tfile
27937         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
27938         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
27939 }
27940 run_test 814 "sparse cp works as expected (LU-12361)"
27941
27942 test_815()
27943 {
27944         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
27945         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
27946 }
27947 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
27948
27949 test_816() {
27950         local ost1_imp=$(get_osc_import_name client ost1)
27951         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27952                          cut -d'.' -f2)
27953
27954         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27955         # ensure ost1 is connected
27956
27957         stat $DIR/$tfile >/dev/null || error "can't stat"
27958         wait_osc_import_state client ost1 FULL
27959         # no locks, no reqs to let the connection idle
27960         cancel_lru_locks osc
27961         lru_resize_disable osc
27962         local before
27963         local now
27964         before=$($LCTL get_param -n \
27965                  ldlm.namespaces.$imp_name.lru_size)
27966
27967         wait_osc_import_state client ost1 IDLE
27968         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
27969         now=$($LCTL get_param -n \
27970               ldlm.namespaces.$imp_name.lru_size)
27971         [ $before == $now ] || error "lru_size changed $before != $now"
27972 }
27973 run_test 816 "do not reset lru_resize on idle reconnect"
27974
27975 cleanup_817() {
27976         umount $tmpdir
27977         exportfs -u localhost:$DIR/nfsexp
27978         rm -rf $DIR/nfsexp
27979 }
27980
27981 test_817() {
27982         systemctl restart nfs-server.service || skip "failed to restart nfsd"
27983
27984         mkdir -p $DIR/nfsexp
27985         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
27986                 error "failed to export nfs"
27987
27988         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
27989         stack_trap cleanup_817 EXIT
27990
27991         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
27992                 error "failed to mount nfs to $tmpdir"
27993
27994         cp /bin/true $tmpdir
27995         $DIR/nfsexp/true || error "failed to execute 'true' command"
27996 }
27997 run_test 817 "nfsd won't cache write lock for exec file"
27998
27999 test_818() {
28000         test_mkdir -i0 -c1 $DIR/$tdir
28001         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
28002         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
28003         stop $SINGLEMDS
28004
28005         # restore osp-syn threads
28006         stack_trap "fail $SINGLEMDS"
28007
28008         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
28009         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
28010         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
28011                 error "start $SINGLEMDS failed"
28012         rm -rf $DIR/$tdir
28013
28014         local testid=$(echo $TESTNAME | tr '_' ' ')
28015
28016         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
28017                 grep "run LFSCK" || error "run LFSCK is not suggested"
28018 }
28019 run_test 818 "unlink with failed llog"
28020
28021 test_819a() {
28022         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28023         cancel_lru_locks osc
28024         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28025         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28026         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
28027         rm -f $TDIR/$tfile
28028 }
28029 run_test 819a "too big niobuf in read"
28030
28031 test_819b() {
28032         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28033         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28034         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28035         cancel_lru_locks osc
28036         sleep 1
28037         rm -f $TDIR/$tfile
28038 }
28039 run_test 819b "too big niobuf in write"
28040
28041
28042 function test_820_start_ost() {
28043         sleep 5
28044
28045         for num in $(seq $OSTCOUNT); do
28046                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
28047         done
28048 }
28049
28050 test_820() {
28051         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28052
28053         mkdir $DIR/$tdir
28054         umount_client $MOUNT || error "umount failed"
28055         for num in $(seq $OSTCOUNT); do
28056                 stop ost$num
28057         done
28058
28059         # mount client with no active OSTs
28060         # so that the client can't initialize max LOV EA size
28061         # from OSC notifications
28062         mount_client $MOUNT || error "mount failed"
28063         # delay OST starting to keep this 0 max EA size for a while
28064         test_820_start_ost &
28065
28066         # create a directory on MDS2
28067         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
28068                 error "Failed to create directory"
28069         # open intent should update default EA size
28070         # see mdc_update_max_ea_from_body()
28071         # notice this is the very first RPC to MDS2
28072         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
28073         ret=$?
28074         echo $out
28075         # With SSK, this situation can lead to -EPERM being returned.
28076         # In that case, simply retry.
28077         if [ $ret -ne 0 ] && $SHARED_KEY; then
28078                 if echo "$out" | grep -q "not permitted"; then
28079                         cp /etc/services $DIR/$tdir/mds2
28080                         ret=$?
28081                 fi
28082         fi
28083         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
28084 }
28085 run_test 820 "update max EA from open intent"
28086
28087 test_822() {
28088         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28089
28090         save_lustre_params mds1 \
28091                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28092         do_facet $SINGLEMDS "$LCTL set_param -n \
28093                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
28094         do_facet $SINGLEMDS "$LCTL set_param -n \
28095                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
28096
28097         # wait for statfs update to clear OS_STATFS_NOPRECREATE
28098         local maxage=$(do_facet mds1 $LCTL get_param -n \
28099                        osp.$FSNAME-OST0000*MDT0000.maxage)
28100         sleep $((maxage + 1))
28101
28102         #define OBD_FAIL_NET_ERROR_RPC          0x532
28103         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
28104
28105         stack_trap "restore_lustre_params < $p; rm $p"
28106
28107         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
28108                       osp.$FSNAME-OST0000*MDT0000.create_count")
28109         for i in $(seq 1 $count); do
28110                 touch $DIR/$tfile.${i} || error "touch failed"
28111         done
28112 }
28113 run_test 822 "test precreate failure"
28114
28115 test_823() {
28116         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28117         local OST_MAX_PRECREATE=20000
28118
28119         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
28120                 skip "Need MDS version at least 2.14.56"
28121
28122         save_lustre_params mds1 \
28123                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28124         do_facet $SINGLEMDS "$LCTL set_param -n \
28125                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
28126         do_facet $SINGLEMDS "$LCTL set_param -n \
28127                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
28128
28129         stack_trap "restore_lustre_params < $p; rm $p"
28130
28131         do_facet $SINGLEMDS "$LCTL set_param -n \
28132                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
28133
28134         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28135                       osp.$FSNAME-OST0000*MDT0000.create_count")
28136         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28137                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
28138         local expect_count=$(((($max/2)/256) * 256))
28139
28140         log "setting create_count to 100200:"
28141         log " -result- count: $count with max: $max, expecting: $expect_count"
28142
28143         [[ $count -eq expect_count ]] ||
28144                 error "Create count not set to max precreate."
28145 }
28146 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28147
28148 test_831() {
28149         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
28150                 skip "Need MDS version 2.14.56"
28151
28152         local sync_changes=$(do_facet $SINGLEMDS \
28153                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28154
28155         [ "$sync_changes" -gt 100 ] &&
28156                 skip "Sync changes $sync_changes > 100 already"
28157
28158         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28159
28160         $LFS mkdir -i 0 $DIR/$tdir
28161         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28162
28163         save_lustre_params mds1 \
28164                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28165         save_lustre_params mds1 \
28166                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28167
28168         do_facet mds1 "$LCTL set_param -n \
28169                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28170                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28171         stack_trap "restore_lustre_params < $p" EXIT
28172
28173         createmany -o $DIR/$tdir/f- 1000
28174         unlinkmany $DIR/$tdir/f- 1000 &
28175         local UNLINK_PID=$!
28176
28177         while sleep 1; do
28178                 sync_changes=$(do_facet mds1 \
28179                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28180                 # the check in the code is racy, fail the test
28181                 # if the value above the limit by 10.
28182                 [ $sync_changes -gt 110 ] && {
28183                         kill -2 $UNLINK_PID
28184                         wait
28185                         error "osp changes throttling failed, $sync_changes>110"
28186                 }
28187                 kill -0 $UNLINK_PID 2> /dev/null || break
28188         done
28189         wait
28190 }
28191 run_test 831 "throttling unlink/setattr queuing on OSP"
28192
28193 #
28194 # tests that do cleanup/setup should be run at the end
28195 #
28196
28197 test_900() {
28198         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28199         local ls
28200
28201         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28202         $LCTL set_param fail_loc=0x903
28203
28204         cancel_lru_locks MGC
28205
28206         FAIL_ON_ERROR=true cleanup
28207         FAIL_ON_ERROR=true setup
28208 }
28209 run_test 900 "umount should not race with any mgc requeue thread"
28210
28211 # LUS-6253/LU-11185
28212 test_901() {
28213         local old
28214         local count
28215         local oldc
28216         local newc
28217         local olds
28218         local news
28219         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28220
28221         # some get_param have a bug to handle dot in param name
28222         cancel_lru_locks MGC
28223         old=$(mount -t lustre | wc -l)
28224         # 1 config+sptlrpc
28225         # 2 params
28226         # 3 nodemap
28227         # 4 IR
28228         old=$((old * 4))
28229         oldc=0
28230         count=0
28231         while [ $old -ne $oldc ]; do
28232                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28233                 sleep 1
28234                 ((count++))
28235                 if [ $count -ge $TIMEOUT ]; then
28236                         error "too large timeout"
28237                 fi
28238         done
28239         umount_client $MOUNT || error "umount failed"
28240         mount_client $MOUNT || error "mount failed"
28241         cancel_lru_locks MGC
28242         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28243
28244         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28245
28246         return 0
28247 }
28248 run_test 901 "don't leak a mgc lock on client umount"
28249
28250 # LU-13377
28251 test_902() {
28252         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28253                 skip "client does not have LU-13377 fix"
28254         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28255         $LCTL set_param fail_loc=0x1415
28256         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28257         cancel_lru_locks osc
28258         rm -f $DIR/$tfile
28259 }
28260 run_test 902 "test short write doesn't hang lustre"
28261
28262 # LU-14711
28263 test_903() {
28264         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28265         echo "blah" > $DIR/${tfile}-2
28266         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28267         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28268         $LCTL set_param fail_loc=0x417 fail_val=20
28269
28270         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28271         sleep 1 # To start the destroy
28272         wait_destroy_complete 150 || error "Destroy taking too long"
28273         cat $DIR/$tfile > /dev/null || error "Evicted"
28274 }
28275 run_test 903 "Test long page discard does not cause evictions"
28276
28277 test_904() {
28278         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28279         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28280                 grep -q project || skip "skip project quota not supported"
28281
28282         local testfile="$DIR/$tdir/$tfile"
28283         local xattr="trusted.projid"
28284         local projid
28285         local mdts=$(comma_list $(mdts_nodes))
28286         local saved=$(do_facet mds1 $LCTL get_param -n \
28287                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
28288
28289         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
28290         stack_trap "do_nodes $mdts $LCTL set_param \
28291                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
28292
28293         mkdir -p $DIR/$tdir
28294         touch $testfile
28295         #hide projid xattr on server
28296         $LFS project -p 1 $testfile ||
28297                 error "set $testfile project id failed"
28298         getfattr -m - $testfile | grep $xattr &&
28299                 error "do not show trusted.projid when disabled on server"
28300         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
28301         #should be hidden when projid is 0
28302         $LFS project -p 0 $testfile ||
28303                 error "set $testfile project id failed"
28304         getfattr -m - $testfile | grep $xattr &&
28305                 error "do not show trusted.projid with project ID 0"
28306
28307         #still can getxattr explicitly
28308         projid=$(getfattr -n $xattr $testfile |
28309                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28310         [ $projid == "0" ] ||
28311                 error "projid expected 0 not $projid"
28312
28313         #set the projid via setxattr
28314         setfattr -n $xattr -v "1000" $testfile ||
28315                 error "setattr failed with $?"
28316         projid=($($LFS project $testfile))
28317         [ ${projid[0]} == "1000" ] ||
28318                 error "projid expected 1000 not $projid"
28319
28320         #check the new projid via getxattr
28321         $LFS project -p 1001 $testfile ||
28322                 error "set $testfile project id failed"
28323         getfattr -m - $testfile | grep $xattr ||
28324                 error "should show trusted.projid when project ID != 0"
28325         projid=$(getfattr -n $xattr $testfile |
28326                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28327         [ $projid == "1001" ] ||
28328                 error "projid expected 1001 not $projid"
28329
28330         #try to set invalid projid
28331         setfattr -n $xattr -v "4294967295" $testfile &&
28332                 error "set invalid projid should fail"
28333
28334         #remove the xattr means setting projid to 0
28335         setfattr -x $xattr $testfile ||
28336                 error "setfattr failed with $?"
28337         projid=($($LFS project $testfile))
28338         [ ${projid[0]} == "0" ] ||
28339                 error "projid expected 0 not $projid"
28340
28341         #should be hidden when parent has inherit flag and same projid
28342         $LFS project -srp 1002 $DIR/$tdir ||
28343                 error "set $tdir project id failed"
28344         getfattr -m - $testfile | grep $xattr &&
28345                 error "do not show trusted.projid with inherit flag"
28346
28347         #still can getxattr explicitly
28348         projid=$(getfattr -n $xattr $testfile |
28349                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28350         [ $projid == "1002" ] ||
28351                 error "projid expected 1002 not $projid"
28352 }
28353 run_test 904 "virtual project ID xattr"
28354
28355 complete $SECONDS
28356 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28357 check_and_cleanup_lustre
28358 if [ "$I_MOUNTED" != "yes" ]; then
28359         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28360 fi
28361 exit_status