Whamcloud - gitweb
LU-15576 osp: Interop skip sanity test 823 for MDS < 2.14.56
[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 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE=${LUSTRE:-$(dirname $0)/..}
35 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054
45 ALWAYS_EXCEPT+=" 407     312"
46
47 if $SHARED_KEY; then
48         # bug number:    LU-14181 LU-14181
49         ALWAYS_EXCEPT+=" 64e      64f"
50 fi
51
52 selinux_status=$(getenforce)
53 if [ "$selinux_status" != "Disabled" ]; then
54         # bug number:
55         ALWAYS_EXCEPT+=""
56 fi
57
58 # skip the grant tests for ARM until they are fixed
59 if [[ $(uname -m) = aarch64 ]]; then
60         # bug number:    LU-11671
61         ALWAYS_EXCEPT+=" 45"
62         # bug number:    LU-14067 LU-14067
63         ALWAYS_EXCEPT+=" 400a     400b"
64 fi
65
66 # skip nfs tests on kernels >= 4.12.0 until they are fixed
67 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
68         # bug number:   LU-12661
69         ALWAYS_EXCEPT+=" 817"
70 fi
71 # skip cgroup tests on RHEL8.1 kernels until they are fixed
72 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
73       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
74         # bug number:   LU-13063
75         ALWAYS_EXCEPT+=" 411"
76 fi
77
78 #skip ACL tests on RHEL8 and SLES15 until tests changed to use other users
79 if (( $(egrep -cw "^bin|^daemon" /etc/passwd) < 2 )); then
80         # bug number:   LU-15259 LU-15259
81         ALWAYS_EXCEPT+=" 103a  125   154a"
82 fi
83
84 #                                  5              12     8   12  15   (min)"
85 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 60i 64b 68 71 115 135 136 230d 300o"
86
87 if [ "$mds1_FSTYPE" = "zfs" ]; then
88         # bug number for skipped test:
89         ALWAYS_EXCEPT+="              "
90         #                                               13    (min)"
91         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
92 fi
93
94 if [ "$ost1_FSTYPE" = "zfs" ]; then
95         # bug number for skipped test:  LU-1941  LU-1941  LU-1941  LU-1941
96         ALWAYS_EXCEPT+="                130a 130b 130c 130d 130e 130f 130g"
97 fi
98
99 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
100
101 # Get the SLES distro version
102 #
103 # Returns a version string that should only be used in comparing
104 # strings returned by version_code()
105 sles_version_code()
106 {
107         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
108
109         # All SuSE Linux versions have one decimal. version_code expects two
110         local sles_version=$version.0
111         version_code $sles_version
112 }
113
114 # Check if we are running on Ubuntu or SLES so we can make decisions on
115 # what tests to run
116 if [ -r /etc/SuSE-release ]; then
117         sles_version=$(sles_version_code)
118         [ $sles_version -lt $(version_code 11.4.0) ] &&
119                 # bug number for skipped test: LU-4341
120                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
121         [ $sles_version -lt $(version_code 12.0.0) ] &&
122                 # bug number for skipped test: LU-3703
123                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
124 elif [ -r /etc/os-release ]; then
125         if grep -qi ubuntu /etc/os-release; then
126                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
127                                                 -e 's/^VERSION=//p' \
128                                                 /etc/os-release |
129                                                 awk '{ print $1 }'))
130
131                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
132                         # bug number for skipped test:
133                         #                LU-10334 LU-10366
134                         ALWAYS_EXCEPT+=" 103a     410"
135                 fi
136         fi
137 fi
138
139 build_test_filter
140 FAIL_ON_ERROR=false
141
142 cleanup() {
143         echo -n "cln.."
144         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
145         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
146 }
147 setup() {
148         echo -n "mnt.."
149         load_modules
150         setupall || exit 10
151         echo "done"
152 }
153
154 check_swap_layouts_support()
155 {
156         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
157                 skip "Does not support layout lock."
158 }
159
160 check_swap_layout_no_dom()
161 {
162         local FOLDER=$1
163         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
164         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
165 }
166
167 check_and_setup_lustre
168 DIR=${DIR:-$MOUNT}
169 assert_DIR
170
171 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
172
173 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
174 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
175 rm -rf $DIR/[Rdfs][0-9]*
176
177 # $RUNAS_ID may get set incorrectly somewhere else
178 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
179         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
180
181 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
182
183 if [ "${ONLY}" = "MOUNT" ] ; then
184         echo "Lustre is up, please go on"
185         exit
186 fi
187
188 echo "preparing for tests involving mounts"
189 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
190 touch $EXT2_DEV
191 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
192 echo # add a newline after mke2fs.
193
194 umask 077
195
196 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
197 lctl set_param debug=-1 2> /dev/null || true
198 test_0a() {
199         touch $DIR/$tfile
200         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
201         rm $DIR/$tfile
202         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
203 }
204 run_test 0a "touch; rm ====================="
205
206 test_0b() {
207         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
208         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
209 }
210 run_test 0b "chmod 0755 $DIR ============================="
211
212 test_0c() {
213         $LCTL get_param mdc.*.import | grep "state: FULL" ||
214                 error "import not FULL"
215         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
216                 error "bad target"
217 }
218 run_test 0c "check import proc"
219
220 test_0d() { # LU-3397
221         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
222                 skip "proc exports not supported before 2.10.57"
223
224         local mgs_exp="mgs.MGS.exports"
225         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
226         local exp_client_nid
227         local exp_client_version
228         local exp_val
229         local imp_val
230         local temp_imp=$DIR/$tfile.import
231         local temp_exp=$DIR/$tfile.export
232
233         # save mgc import file to $temp_imp
234         $LCTL get_param mgc.*.import | tee $temp_imp
235         # Check if client uuid is found in MGS export
236         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
237                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
238                         $client_uuid ] &&
239                         break;
240         done
241         # save mgs export file to $temp_exp
242         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
243
244         # Compare the value of field "connect_flags"
245         imp_val=$(grep "connect_flags" $temp_imp)
246         exp_val=$(grep "connect_flags" $temp_exp)
247         [ "$exp_val" == "$imp_val" ] ||
248                 error "export flags '$exp_val' != import flags '$imp_val'"
249
250         # Compare client versions.  Only compare top-3 fields for compatibility
251         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
252         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
253         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
254         [ "$exp_val" == "$imp_val" ] ||
255                 error "exp version '$exp_client_version'($exp_val) != " \
256                         "'$(lustre_build_version client)'($imp_val)"
257 }
258 run_test 0d "check export proc ============================="
259
260 test_0e() { # LU-13417
261         (( $MDSCOUNT > 1 )) ||
262                 skip "We need at least 2 MDTs for this test"
263
264         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
265                 skip "Need server version at least 2.14.51"
266
267         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
268         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
269
270         [ $default_lmv_count -eq 1 ] ||
271                 error "$MOUNT default stripe count $default_lmv_count"
272
273         [ $default_lmv_index -eq -1 ] ||
274                 error "$MOUNT default stripe index $default_lmv_index"
275
276         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
277         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
278
279         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
280         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
281
282         [ $mdt_index1 -eq $mdt_index2 ] &&
283                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
284
285         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
286 }
287 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
288
289 test_1() {
290         test_mkdir $DIR/$tdir
291         test_mkdir $DIR/$tdir/d2
292         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
293         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
294         rmdir $DIR/$tdir/d2
295         rmdir $DIR/$tdir
296         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
297 }
298 run_test 1 "mkdir; remkdir; rmdir"
299
300 test_2() {
301         test_mkdir $DIR/$tdir
302         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
303         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
304         rm -r $DIR/$tdir
305         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
306 }
307 run_test 2 "mkdir; touch; rmdir; check file"
308
309 test_3() {
310         test_mkdir $DIR/$tdir
311         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
312         touch $DIR/$tdir/$tfile
313         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
314         rm -r $DIR/$tdir
315         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
316 }
317 run_test 3 "mkdir; touch; rmdir; check dir"
318
319 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
320 test_4() {
321         test_mkdir -i 1 $DIR/$tdir
322
323         touch $DIR/$tdir/$tfile ||
324                 error "Create file under remote directory failed"
325
326         rmdir $DIR/$tdir &&
327                 error "Expect error removing in-use dir $DIR/$tdir"
328
329         test -d $DIR/$tdir || error "Remote directory disappeared"
330
331         rm -rf $DIR/$tdir || error "remove remote dir error"
332 }
333 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
334
335 test_5() {
336         test_mkdir $DIR/$tdir
337         test_mkdir $DIR/$tdir/d2
338         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
339         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
340         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
341 }
342 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
343
344 test_6a() {
345         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
346         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
347         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
348                 error "$tfile does not have perm 0666 or UID $UID"
349         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
350         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
351                 error "$tfile should be 0666 and owned by UID $UID"
352 }
353 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
354
355 test_6c() {
356         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
357
358         touch $DIR/$tfile
359         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
360         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
361                 error "$tfile should be owned by UID $RUNAS_ID"
362         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
363         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
364                 error "$tfile should be owned by UID $RUNAS_ID"
365 }
366 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
367
368 test_6e() {
369         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
370
371         touch $DIR/$tfile
372         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
373         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
374                 error "$tfile should be owned by GID $UID"
375         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
376         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
377                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
378 }
379 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
380
381 test_6g() {
382         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
383
384         test_mkdir $DIR/$tdir
385         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
386         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
387         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
388         test_mkdir $DIR/$tdir/d/subdir
389         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
390                 error "$tdir/d/subdir should be GID $RUNAS_GID"
391         if [[ $MDSCOUNT -gt 1 ]]; then
392                 # check remote dir sgid inherite
393                 $LFS mkdir -i 0 $DIR/$tdir.local ||
394                         error "mkdir $tdir.local failed"
395                 chmod g+s $DIR/$tdir.local ||
396                         error "chmod $tdir.local failed"
397                 chgrp $RUNAS_GID $DIR/$tdir.local ||
398                         error "chgrp $tdir.local failed"
399                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
400                         error "mkdir $tdir.remote failed"
401                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
402                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
403                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
404                         error "$tdir.remote should be mode 02755"
405         fi
406 }
407 run_test 6g "verify new dir in sgid dir inherits group"
408
409 test_6h() { # bug 7331
410         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
411
412         touch $DIR/$tfile || error "touch failed"
413         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
414         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
415                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
416         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
417                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
418 }
419 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
420
421 test_7a() {
422         test_mkdir $DIR/$tdir
423         $MCREATE $DIR/$tdir/$tfile
424         chmod 0666 $DIR/$tdir/$tfile
425         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
426                 error "$tdir/$tfile should be mode 0666"
427 }
428 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
429
430 test_7b() {
431         if [ ! -d $DIR/$tdir ]; then
432                 test_mkdir $DIR/$tdir
433         fi
434         $MCREATE $DIR/$tdir/$tfile
435         echo -n foo > $DIR/$tdir/$tfile
436         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
437         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
438 }
439 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
440
441 test_8() {
442         test_mkdir $DIR/$tdir
443         touch $DIR/$tdir/$tfile
444         chmod 0666 $DIR/$tdir/$tfile
445         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
446                 error "$tfile mode not 0666"
447 }
448 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
449
450 test_9() {
451         test_mkdir $DIR/$tdir
452         test_mkdir $DIR/$tdir/d2
453         test_mkdir $DIR/$tdir/d2/d3
454         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
455 }
456 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
457
458 test_10() {
459         test_mkdir $DIR/$tdir
460         test_mkdir $DIR/$tdir/d2
461         touch $DIR/$tdir/d2/$tfile
462         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
463                 error "$tdir/d2/$tfile not a file"
464 }
465 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
466
467 test_11() {
468         test_mkdir $DIR/$tdir
469         test_mkdir $DIR/$tdir/d2
470         chmod 0666 $DIR/$tdir/d2
471         chmod 0705 $DIR/$tdir/d2
472         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
473                 error "$tdir/d2 mode not 0705"
474 }
475 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
476
477 test_12() {
478         test_mkdir $DIR/$tdir
479         touch $DIR/$tdir/$tfile
480         chmod 0666 $DIR/$tdir/$tfile
481         chmod 0654 $DIR/$tdir/$tfile
482         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
483                 error "$tdir/d2 mode not 0654"
484 }
485 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
486
487 test_13() {
488         test_mkdir $DIR/$tdir
489         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
490         >  $DIR/$tdir/$tfile
491         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
492                 error "$tdir/$tfile size not 0 after truncate"
493 }
494 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
495
496 test_14() {
497         test_mkdir $DIR/$tdir
498         touch $DIR/$tdir/$tfile
499         rm $DIR/$tdir/$tfile
500         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
501 }
502 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
503
504 test_15() {
505         test_mkdir $DIR/$tdir
506         touch $DIR/$tdir/$tfile
507         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
508         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
509                 error "$tdir/${tfile_2} not a file after rename"
510         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
511 }
512 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
513
514 test_16() {
515         test_mkdir $DIR/$tdir
516         touch $DIR/$tdir/$tfile
517         rm -rf $DIR/$tdir/$tfile
518         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
519 }
520 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
521
522 test_17a() {
523         test_mkdir $DIR/$tdir
524         touch $DIR/$tdir/$tfile
525         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
526         ls -l $DIR/$tdir
527         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
528                 error "$tdir/l-exist not a symlink"
529         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
530                 error "$tdir/l-exist not referencing a file"
531         rm -f $DIR/$tdir/l-exist
532         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
533 }
534 run_test 17a "symlinks: create, remove (real)"
535
536 test_17b() {
537         test_mkdir $DIR/$tdir
538         ln -s no-such-file $DIR/$tdir/l-dangle
539         ls -l $DIR/$tdir
540         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
541                 error "$tdir/l-dangle not referencing no-such-file"
542         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
543                 error "$tdir/l-dangle not referencing non-existent file"
544         rm -f $DIR/$tdir/l-dangle
545         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
546 }
547 run_test 17b "symlinks: create, remove (dangling)"
548
549 test_17c() { # bug 3440 - don't save failed open RPC for replay
550         test_mkdir $DIR/$tdir
551         ln -s foo $DIR/$tdir/$tfile
552         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
553 }
554 run_test 17c "symlinks: open dangling (should return error)"
555
556 test_17d() {
557         test_mkdir $DIR/$tdir
558         ln -s foo $DIR/$tdir/$tfile
559         touch $DIR/$tdir/$tfile || error "creating to new symlink"
560 }
561 run_test 17d "symlinks: create dangling"
562
563 test_17e() {
564         test_mkdir $DIR/$tdir
565         local foo=$DIR/$tdir/$tfile
566         ln -s $foo $foo || error "create symlink failed"
567         ls -l $foo || error "ls -l failed"
568         ls $foo && error "ls not failed" || true
569 }
570 run_test 17e "symlinks: create recursive symlink (should return error)"
571
572 test_17f() {
573         test_mkdir $DIR/$tdir
574         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
575         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
576         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
577         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
578         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
579         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
580         ls -l  $DIR/$tdir
581 }
582 run_test 17f "symlinks: long and very long symlink name"
583
584 # str_repeat(S, N) generate a string that is string S repeated N times
585 str_repeat() {
586         local s=$1
587         local n=$2
588         local ret=''
589         while [ $((n -= 1)) -ge 0 ]; do
590                 ret=$ret$s
591         done
592         echo $ret
593 }
594
595 # Long symlinks and LU-2241
596 test_17g() {
597         test_mkdir $DIR/$tdir
598         local TESTS="59 60 61 4094 4095"
599
600         # Fix for inode size boundary in 2.1.4
601         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
602                 TESTS="4094 4095"
603
604         # Patch not applied to 2.2 or 2.3 branches
605         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
606         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
607                 TESTS="4094 4095"
608
609         for i in $TESTS; do
610                 local SYMNAME=$(str_repeat 'x' $i)
611                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
612                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
613         done
614 }
615 run_test 17g "symlinks: really long symlink name and inode boundaries"
616
617 test_17h() { #bug 17378
618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
619         remote_mds_nodsh && skip "remote MDS with nodsh"
620
621         local mdt_idx
622
623         test_mkdir $DIR/$tdir
624         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
625         $LFS setstripe -c -1 $DIR/$tdir
626         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
627         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
628         touch $DIR/$tdir/$tfile || true
629 }
630 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
631
632 test_17i() { #bug 20018
633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
634         remote_mds_nodsh && skip "remote MDS with nodsh"
635
636         local foo=$DIR/$tdir/$tfile
637         local mdt_idx
638
639         test_mkdir -c1 $DIR/$tdir
640         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
641         ln -s $foo $foo || error "create symlink failed"
642 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
643         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
644         ls -l $foo && error "error not detected"
645         return 0
646 }
647 run_test 17i "don't panic on short symlink (should return error)"
648
649 test_17k() { #bug 22301
650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
651         [[ -z "$(which rsync 2>/dev/null)" ]] &&
652                 skip "no rsync command"
653         rsync --help | grep -q xattr ||
654                 skip_env "$(rsync --version | head -n1) does not support xattrs"
655         test_mkdir $DIR/$tdir
656         test_mkdir $DIR/$tdir.new
657         touch $DIR/$tdir/$tfile
658         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
659         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
660                 error "rsync failed with xattrs enabled"
661 }
662 run_test 17k "symlinks: rsync with xattrs enabled"
663
664 test_17l() { # LU-279
665         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
666                 skip "no getfattr command"
667
668         test_mkdir $DIR/$tdir
669         touch $DIR/$tdir/$tfile
670         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
671         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
672                 # -h to not follow symlinks. -m '' to list all the xattrs.
673                 # grep to remove first line: '# file: $path'.
674                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
675                 do
676                         lgetxattr_size_check $path $xattr ||
677                                 error "lgetxattr_size_check $path $xattr failed"
678                 done
679         done
680 }
681 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
682
683 # LU-1540
684 test_17m() {
685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
686         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
687         remote_mds_nodsh && skip "remote MDS with nodsh"
688         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
689         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
690                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
691
692         local short_sym="0123456789"
693         local wdir=$DIR/$tdir
694         local i
695
696         test_mkdir $wdir
697         long_sym=$short_sym
698         # create a long symlink file
699         for ((i = 0; i < 4; ++i)); do
700                 long_sym=${long_sym}${long_sym}
701         done
702
703         echo "create 512 short and long symlink files under $wdir"
704         for ((i = 0; i < 256; ++i)); do
705                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
706                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
707         done
708
709         echo "erase them"
710         rm -f $wdir/*
711         sync
712         wait_delete_completed
713
714         echo "recreate the 512 symlink files with a shorter string"
715         for ((i = 0; i < 512; ++i)); do
716                 # rewrite the symlink file with a shorter string
717                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
718                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
719         done
720
721         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
722
723         echo "stop and checking mds${mds_index}:"
724         # e2fsck should not return error
725         stop mds${mds_index}
726         local devname=$(mdsdevname $mds_index)
727         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
728         rc=$?
729
730         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
731                 error "start mds${mds_index} failed"
732         df $MOUNT > /dev/null 2>&1
733         [ $rc -eq 0 ] ||
734                 error "e2fsck detected error for short/long symlink: rc=$rc"
735         rm -f $wdir/*
736 }
737 run_test 17m "run e2fsck against MDT which contains short/long symlink"
738
739 check_fs_consistency_17n() {
740         local mdt_index
741         local rc=0
742
743         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
744         # so it only check MDT1/MDT2 instead of all of MDTs.
745         for mdt_index in 1 2; do
746                 # e2fsck should not return error
747                 stop mds${mdt_index}
748                 local devname=$(mdsdevname $mdt_index)
749                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
750                         rc=$((rc + $?))
751
752                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
753                         error "mount mds$mdt_index failed"
754                 df $MOUNT > /dev/null 2>&1
755         done
756         return $rc
757 }
758
759 test_17n() {
760         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
762         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
763         remote_mds_nodsh && skip "remote MDS with nodsh"
764         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
765         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
766                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
767
768         local i
769
770         test_mkdir $DIR/$tdir
771         for ((i=0; i<10; i++)); do
772                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
773                         error "create remote dir error $i"
774                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
775                         error "create files under remote dir failed $i"
776         done
777
778         check_fs_consistency_17n ||
779                 error "e2fsck report error after create files under remote dir"
780
781         for ((i = 0; i < 10; i++)); do
782                 rm -rf $DIR/$tdir/remote_dir_${i} ||
783                         error "destroy remote dir error $i"
784         done
785
786         check_fs_consistency_17n ||
787                 error "e2fsck report error after unlink files under remote dir"
788
789         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
790                 skip "lustre < 2.4.50 does not support migrate mv"
791
792         for ((i = 0; i < 10; i++)); do
793                 mkdir -p $DIR/$tdir/remote_dir_${i}
794                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
795                         error "create files under remote dir failed $i"
796                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
797                         error "migrate remote dir error $i"
798         done
799         check_fs_consistency_17n || error "e2fsck report error after migration"
800
801         for ((i = 0; i < 10; i++)); do
802                 rm -rf $DIR/$tdir/remote_dir_${i} ||
803                         error "destroy remote dir error $i"
804         done
805
806         check_fs_consistency_17n || error "e2fsck report error after unlink"
807 }
808 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
809
810 test_17o() {
811         remote_mds_nodsh && skip "remote MDS with nodsh"
812         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
813                 skip "Need MDS version at least 2.3.64"
814
815         local wdir=$DIR/${tdir}o
816         local mdt_index
817         local rc=0
818
819         test_mkdir $wdir
820         touch $wdir/$tfile
821         mdt_index=$($LFS getstripe -m $wdir/$tfile)
822         mdt_index=$((mdt_index + 1))
823
824         cancel_lru_locks mdc
825         #fail mds will wait the failover finish then set
826         #following fail_loc to avoid interfer the recovery process.
827         fail mds${mdt_index}
828
829         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
830         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
831         ls -l $wdir/$tfile && rc=1
832         do_facet mds${mdt_index} lctl set_param fail_loc=0
833         [[ $rc -eq 0 ]] || error "stat file should fail"
834 }
835 run_test 17o "stat file with incompat LMA feature"
836
837 test_18() {
838         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
839         ls $DIR || error "Failed to ls $DIR: $?"
840 }
841 run_test 18 "touch .../f ; ls ... =============================="
842
843 test_19a() {
844         touch $DIR/$tfile
845         ls -l $DIR
846         rm $DIR/$tfile
847         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
848 }
849 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
850
851 test_19b() {
852         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
853 }
854 run_test 19b "ls -l .../f19 (should return error) =============="
855
856 test_19c() {
857         [ $RUNAS_ID -eq $UID ] &&
858                 skip_env "RUNAS_ID = UID = $UID -- skipping"
859
860         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
861 }
862 run_test 19c "$RUNAS touch .../f19 (should return error) =="
863
864 test_19d() {
865         cat $DIR/f19 && error || true
866 }
867 run_test 19d "cat .../f19 (should return error) =============="
868
869 test_20() {
870         touch $DIR/$tfile
871         rm $DIR/$tfile
872         touch $DIR/$tfile
873         rm $DIR/$tfile
874         touch $DIR/$tfile
875         rm $DIR/$tfile
876         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
877 }
878 run_test 20 "touch .../f ; ls -l ..."
879
880 test_21() {
881         test_mkdir $DIR/$tdir
882         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
883         ln -s dangle $DIR/$tdir/link
884         echo foo >> $DIR/$tdir/link
885         cat $DIR/$tdir/dangle
886         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
887         $CHECKSTAT -f -t file $DIR/$tdir/link ||
888                 error "$tdir/link not linked to a file"
889 }
890 run_test 21 "write to dangling link"
891
892 test_22() {
893         local wdir=$DIR/$tdir
894         test_mkdir $wdir
895         chown $RUNAS_ID:$RUNAS_GID $wdir
896         (cd $wdir || error "cd $wdir failed";
897                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
898                 $RUNAS tar xf -)
899         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
900         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
901         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
902                 error "checkstat -u failed"
903 }
904 run_test 22 "unpack tar archive as non-root user"
905
906 # was test_23
907 test_23a() {
908         test_mkdir $DIR/$tdir
909         local file=$DIR/$tdir/$tfile
910
911         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
912         openfile -f O_CREAT:O_EXCL $file &&
913                 error "$file recreate succeeded" || true
914 }
915 run_test 23a "O_CREAT|O_EXCL in subdir"
916
917 test_23b() { # bug 18988
918         test_mkdir $DIR/$tdir
919         local file=$DIR/$tdir/$tfile
920
921         rm -f $file
922         echo foo > $file || error "write filed"
923         echo bar >> $file || error "append filed"
924         $CHECKSTAT -s 8 $file || error "wrong size"
925         rm $file
926 }
927 run_test 23b "O_APPEND check"
928
929 # LU-9409, size with O_APPEND and tiny writes
930 test_23c() {
931         local file=$DIR/$tfile
932
933         # single dd
934         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
935         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
936         rm -f $file
937
938         # racing tiny writes
939         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
940         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
941         wait
942         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
943         rm -f $file
944
945         #racing tiny & normal writes
946         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
947         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
948         wait
949         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
950         rm -f $file
951
952         #racing tiny & normal writes 2, ugly numbers
953         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
954         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
955         wait
956         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
957         rm -f $file
958 }
959 run_test 23c "O_APPEND size checks for tiny writes"
960
961 # LU-11069 file offset is correct after appending writes
962 test_23d() {
963         local file=$DIR/$tfile
964         local offset
965
966         echo CentaurHauls > $file
967         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
968         if ((offset != 26)); then
969                 error "wrong offset, expected 26, got '$offset'"
970         fi
971 }
972 run_test 23d "file offset is correct after appending writes"
973
974 # rename sanity
975 test_24a() {
976         echo '-- same directory rename'
977         test_mkdir $DIR/$tdir
978         touch $DIR/$tdir/$tfile.1
979         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
980         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
981 }
982 run_test 24a "rename file to non-existent target"
983
984 test_24b() {
985         test_mkdir $DIR/$tdir
986         touch $DIR/$tdir/$tfile.{1,2}
987         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
988         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
989         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
990 }
991 run_test 24b "rename file to existing target"
992
993 test_24c() {
994         test_mkdir $DIR/$tdir
995         test_mkdir $DIR/$tdir/d$testnum.1
996         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
997         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
998         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
999 }
1000 run_test 24c "rename directory to non-existent target"
1001
1002 test_24d() {
1003         test_mkdir -c1 $DIR/$tdir
1004         test_mkdir -c1 $DIR/$tdir/d$testnum.1
1005         test_mkdir -c1 $DIR/$tdir/d$testnum.2
1006         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
1007         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
1008         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
1009 }
1010 run_test 24d "rename directory to existing target"
1011
1012 test_24e() {
1013         echo '-- cross directory renames --'
1014         test_mkdir $DIR/R5a
1015         test_mkdir $DIR/R5b
1016         touch $DIR/R5a/f
1017         mv $DIR/R5a/f $DIR/R5b/g
1018         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1019         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1020 }
1021 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1022
1023 test_24f() {
1024         test_mkdir $DIR/R6a
1025         test_mkdir $DIR/R6b
1026         touch $DIR/R6a/f $DIR/R6b/g
1027         mv $DIR/R6a/f $DIR/R6b/g
1028         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1029         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1030 }
1031 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1032
1033 test_24g() {
1034         test_mkdir $DIR/R7a
1035         test_mkdir $DIR/R7b
1036         test_mkdir $DIR/R7a/d
1037         mv $DIR/R7a/d $DIR/R7b/e
1038         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1039         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1040 }
1041 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1042
1043 test_24h() {
1044         test_mkdir -c1 $DIR/R8a
1045         test_mkdir -c1 $DIR/R8b
1046         test_mkdir -c1 $DIR/R8a/d
1047         test_mkdir -c1 $DIR/R8b/e
1048         mrename $DIR/R8a/d $DIR/R8b/e
1049         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1050         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1051 }
1052 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1053
1054 test_24i() {
1055         echo "-- rename error cases"
1056         test_mkdir $DIR/R9
1057         test_mkdir $DIR/R9/a
1058         touch $DIR/R9/f
1059         mrename $DIR/R9/f $DIR/R9/a
1060         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1061         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1062         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1063 }
1064 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1065
1066 test_24j() {
1067         test_mkdir $DIR/R10
1068         mrename $DIR/R10/f $DIR/R10/g
1069         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1070         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1071         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1072 }
1073 run_test 24j "source does not exist ============================"
1074
1075 test_24k() {
1076         test_mkdir $DIR/R11a
1077         test_mkdir $DIR/R11a/d
1078         touch $DIR/R11a/f
1079         mv $DIR/R11a/f $DIR/R11a/d
1080         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1081         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1082 }
1083 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1084
1085 # bug 2429 - rename foo foo foo creates invalid file
1086 test_24l() {
1087         f="$DIR/f24l"
1088         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1089 }
1090 run_test 24l "Renaming a file to itself ========================"
1091
1092 test_24m() {
1093         f="$DIR/f24m"
1094         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1095         # on ext3 this does not remove either the source or target files
1096         # though the "expected" operation would be to remove the source
1097         $CHECKSTAT -t file ${f} || error "${f} missing"
1098         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1099 }
1100 run_test 24m "Renaming a file to a hard link to itself ========="
1101
1102 test_24n() {
1103     f="$DIR/f24n"
1104     # this stats the old file after it was renamed, so it should fail
1105     touch ${f}
1106     $CHECKSTAT ${f} || error "${f} missing"
1107     mv ${f} ${f}.rename
1108     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1109     $CHECKSTAT -a ${f} || error "${f} exists"
1110 }
1111 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1112
1113 test_24o() {
1114         test_mkdir $DIR/$tdir
1115         rename_many -s random -v -n 10 $DIR/$tdir
1116 }
1117 run_test 24o "rename of files during htree split"
1118
1119 test_24p() {
1120         test_mkdir $DIR/R12a
1121         test_mkdir $DIR/R12b
1122         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1123         mrename $DIR/R12a $DIR/R12b
1124         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1125         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1126         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1127         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1128 }
1129 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1130
1131 cleanup_multiop_pause() {
1132         trap 0
1133         kill -USR1 $MULTIPID
1134 }
1135
1136 test_24q() {
1137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1138
1139         test_mkdir $DIR/R13a
1140         test_mkdir $DIR/R13b
1141         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1142         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1143         MULTIPID=$!
1144
1145         trap cleanup_multiop_pause EXIT
1146         mrename $DIR/R13a $DIR/R13b
1147         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1148         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1149         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1150         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1151         cleanup_multiop_pause
1152         wait $MULTIPID || error "multiop close failed"
1153 }
1154 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1155
1156 test_24r() { #bug 3789
1157         test_mkdir $DIR/R14a
1158         test_mkdir $DIR/R14a/b
1159         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1160         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1161         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1162 }
1163 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1164
1165 test_24s() {
1166         test_mkdir $DIR/R15a
1167         test_mkdir $DIR/R15a/b
1168         test_mkdir $DIR/R15a/b/c
1169         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1170         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1171         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1172 }
1173 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1174 test_24t() {
1175         test_mkdir $DIR/R16a
1176         test_mkdir $DIR/R16a/b
1177         test_mkdir $DIR/R16a/b/c
1178         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1179         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1180         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1181 }
1182 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1183
1184 test_24u() { # bug12192
1185         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1186         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1187 }
1188 run_test 24u "create stripe file"
1189
1190 simple_cleanup_common() {
1191         local createmany=$1
1192         local rc=0
1193
1194         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1195
1196         local start=$SECONDS
1197
1198         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1199         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1200         rc=$?
1201         wait_delete_completed
1202         echo "cleanup time $((SECONDS - start))"
1203         return $rc
1204 }
1205
1206 max_pages_per_rpc() {
1207         local mdtname="$(printf "MDT%04x" ${1:-0})"
1208         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1209 }
1210
1211 test_24v() {
1212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1213
1214         local nrfiles=${COUNT:-100000}
1215         local fname="$DIR/$tdir/$tfile"
1216
1217         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1218         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1219
1220         test_mkdir "$(dirname $fname)"
1221         # assume MDT0000 has the fewest inodes
1222         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1223         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1224         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1225
1226         stack_trap "simple_cleanup_common $nrfiles"
1227
1228         createmany -m "$fname" $nrfiles
1229
1230         cancel_lru_locks mdc
1231         lctl set_param mdc.*.stats clear
1232
1233         # was previously test_24D: LU-6101
1234         # readdir() returns correct number of entries after cursor reload
1235         local num_ls=$(ls $DIR/$tdir | wc -l)
1236         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1237         local num_all=$(ls -a $DIR/$tdir | wc -l)
1238         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1239                 [ $num_all -ne $((nrfiles + 2)) ]; then
1240                         error "Expected $nrfiles files, got $num_ls " \
1241                                 "($num_uniq unique $num_all .&..)"
1242         fi
1243         # LU-5 large readdir
1244         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1245         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1246         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1247         # take into account of overhead in lu_dirpage header and end mark in
1248         # each page, plus one in rpc_num calculation.
1249         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1250         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1251         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1252         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1253         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1254         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1255         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1256         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1257                 error "large readdir doesn't take effect: " \
1258                       "$mds_readpage should be about $rpc_max"
1259 }
1260 run_test 24v "list large directory (test hash collision, b=17560)"
1261
1262 test_24w() { # bug21506
1263         SZ1=234852
1264         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1265         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1266         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1267         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1268         [[ "$SZ1" -eq "$SZ2" ]] ||
1269                 error "Error reading at the end of the file $tfile"
1270 }
1271 run_test 24w "Reading a file larger than 4Gb"
1272
1273 test_24x() {
1274         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1276         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1277                 skip "Need MDS version at least 2.7.56"
1278
1279         local MDTIDX=1
1280         local remote_dir=$DIR/$tdir/remote_dir
1281
1282         test_mkdir $DIR/$tdir
1283         $LFS mkdir -i $MDTIDX $remote_dir ||
1284                 error "create remote directory failed"
1285
1286         test_mkdir $DIR/$tdir/src_dir
1287         touch $DIR/$tdir/src_file
1288         test_mkdir $remote_dir/tgt_dir
1289         touch $remote_dir/tgt_file
1290
1291         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1292                 error "rename dir cross MDT failed!"
1293
1294         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1295                 error "rename file cross MDT failed!"
1296
1297         touch $DIR/$tdir/ln_file
1298         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1299                 error "ln file cross MDT failed"
1300
1301         rm -rf $DIR/$tdir || error "Can not delete directories"
1302 }
1303 run_test 24x "cross MDT rename/link"
1304
1305 test_24y() {
1306         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1308
1309         local remote_dir=$DIR/$tdir/remote_dir
1310         local mdtidx=1
1311
1312         test_mkdir $DIR/$tdir
1313         $LFS mkdir -i $mdtidx $remote_dir ||
1314                 error "create remote directory failed"
1315
1316         test_mkdir $remote_dir/src_dir
1317         touch $remote_dir/src_file
1318         test_mkdir $remote_dir/tgt_dir
1319         touch $remote_dir/tgt_file
1320
1321         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1322                 error "rename subdir in the same remote dir failed!"
1323
1324         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1325                 error "rename files in the same remote dir failed!"
1326
1327         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1328                 error "link files in the same remote dir failed!"
1329
1330         rm -rf $DIR/$tdir || error "Can not delete directories"
1331 }
1332 run_test 24y "rename/link on the same dir should succeed"
1333
1334 test_24z() {
1335         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1336         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1337                 skip "Need MDS version at least 2.12.51"
1338
1339         local index
1340
1341         for index in 0 1; do
1342                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1343                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1344         done
1345
1346         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1347
1348         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1349         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1350
1351         local mdts=$(comma_list $(mdts_nodes))
1352
1353         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1354         stack_trap "do_nodes $mdts $LCTL \
1355                 set_param mdt.*.enable_remote_rename=1" EXIT
1356
1357         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1358
1359         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1360         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1361 }
1362 run_test 24z "cross-MDT rename is done as cp"
1363
1364 test_24A() { # LU-3182
1365         local NFILES=5000
1366
1367         test_mkdir $DIR/$tdir
1368         stack_trap "simple_cleanup_common $NFILES"
1369         createmany -m $DIR/$tdir/$tfile $NFILES
1370         local t=$(ls $DIR/$tdir | wc -l)
1371         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1372         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1373
1374         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1375                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1376 }
1377 run_test 24A "readdir() returns correct number of entries."
1378
1379 test_24B() { # LU-4805
1380         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1381
1382         local count
1383
1384         test_mkdir $DIR/$tdir
1385         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1386                 error "create striped dir failed"
1387
1388         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1389         [ $count -eq 2 ] || error "Expected 2, got $count"
1390
1391         touch $DIR/$tdir/striped_dir/a
1392
1393         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1394         [ $count -eq 3 ] || error "Expected 3, got $count"
1395
1396         touch $DIR/$tdir/striped_dir/.f
1397
1398         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1399         [ $count -eq 4 ] || error "Expected 4, got $count"
1400
1401         rm -rf $DIR/$tdir || error "Can not delete directories"
1402 }
1403 run_test 24B "readdir for striped dir return correct number of entries"
1404
1405 test_24C() {
1406         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1407
1408         mkdir $DIR/$tdir
1409         mkdir $DIR/$tdir/d0
1410         mkdir $DIR/$tdir/d1
1411
1412         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1413                 error "create striped dir failed"
1414
1415         cd $DIR/$tdir/d0/striped_dir
1416
1417         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1418         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1419         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1420
1421         [ "$d0_ino" = "$parent_ino" ] ||
1422                 error ".. wrong, expect $d0_ino, get $parent_ino"
1423
1424         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1425                 error "mv striped dir failed"
1426
1427         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1428
1429         [ "$d1_ino" = "$parent_ino" ] ||
1430                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1431 }
1432 run_test 24C "check .. in striped dir"
1433
1434 test_24E() {
1435         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1436         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1437
1438         mkdir -p $DIR/$tdir
1439         mkdir $DIR/$tdir/src_dir
1440         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1441                 error "create remote source failed"
1442
1443         touch $DIR/$tdir/src_dir/src_child/a
1444
1445         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1446                 error "create remote target dir failed"
1447
1448         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1449                 error "create remote target child failed"
1450
1451         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1452                 error "rename dir cross MDT failed!"
1453
1454         find $DIR/$tdir
1455
1456         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1457                 error "src_child still exists after rename"
1458
1459         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1460                 error "missing file(a) after rename"
1461
1462         rm -rf $DIR/$tdir || error "Can not delete directories"
1463 }
1464 run_test 24E "cross MDT rename/link"
1465
1466 test_24F () {
1467         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1468
1469         local repeats=1000
1470         [ "$SLOW" = "no" ] && repeats=100
1471
1472         mkdir -p $DIR/$tdir
1473
1474         echo "$repeats repeats"
1475         for ((i = 0; i < repeats; i++)); do
1476                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1477                 touch $DIR/$tdir/test/a || error "touch fails"
1478                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1479                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1480         done
1481
1482         true
1483 }
1484 run_test 24F "hash order vs readdir (LU-11330)"
1485
1486 test_24G () {
1487         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1488
1489         local ino1
1490         local ino2
1491
1492         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1493         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1494         touch $DIR/$tdir-0/f1 || error "touch f1"
1495         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1496         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1497         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1498         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1499         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1500 }
1501 run_test 24G "migrate symlink in rename"
1502
1503 test_24H() {
1504         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1505         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1506                 skip "MDT1 should be on another node"
1507
1508         test_mkdir -i 1 -c 1 $DIR/$tdir
1509 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1510         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1511         touch $DIR/$tdir/$tfile || error "touch failed"
1512 }
1513 run_test 24H "repeat FLD_QUERY rpc"
1514
1515 test_25a() {
1516         echo '== symlink sanity ============================================='
1517
1518         test_mkdir $DIR/d25
1519         ln -s d25 $DIR/s25
1520         touch $DIR/s25/foo ||
1521                 error "File creation in symlinked directory failed"
1522 }
1523 run_test 25a "create file in symlinked directory ==============="
1524
1525 test_25b() {
1526         [ ! -d $DIR/d25 ] && test_25a
1527         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1528 }
1529 run_test 25b "lookup file in symlinked directory ==============="
1530
1531 test_26a() {
1532         test_mkdir $DIR/d26
1533         test_mkdir $DIR/d26/d26-2
1534         ln -s d26/d26-2 $DIR/s26
1535         touch $DIR/s26/foo || error "File creation failed"
1536 }
1537 run_test 26a "multiple component symlink ======================="
1538
1539 test_26b() {
1540         test_mkdir -p $DIR/$tdir/d26-2
1541         ln -s $tdir/d26-2/foo $DIR/s26-2
1542         touch $DIR/s26-2 || error "File creation failed"
1543 }
1544 run_test 26b "multiple component symlink at end of lookup ======"
1545
1546 test_26c() {
1547         test_mkdir $DIR/d26.2
1548         touch $DIR/d26.2/foo
1549         ln -s d26.2 $DIR/s26.2-1
1550         ln -s s26.2-1 $DIR/s26.2-2
1551         ln -s s26.2-2 $DIR/s26.2-3
1552         chmod 0666 $DIR/s26.2-3/foo
1553 }
1554 run_test 26c "chain of symlinks"
1555
1556 # recursive symlinks (bug 439)
1557 test_26d() {
1558         ln -s d26-3/foo $DIR/d26-3
1559 }
1560 run_test 26d "create multiple component recursive symlink"
1561
1562 test_26e() {
1563         [ ! -h $DIR/d26-3 ] && test_26d
1564         rm $DIR/d26-3
1565 }
1566 run_test 26e "unlink multiple component recursive symlink"
1567
1568 # recursive symlinks (bug 7022)
1569 test_26f() {
1570         test_mkdir $DIR/$tdir
1571         test_mkdir $DIR/$tdir/$tfile
1572         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1573         test_mkdir -p lndir/bar1
1574         test_mkdir $DIR/$tdir/$tfile/$tfile
1575         cd $tfile                || error "cd $tfile failed"
1576         ln -s .. dotdot          || error "ln dotdot failed"
1577         ln -s dotdot/lndir lndir || error "ln lndir failed"
1578         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1579         output=`ls $tfile/$tfile/lndir/bar1`
1580         [ "$output" = bar1 ] && error "unexpected output"
1581         rm -r $tfile             || error "rm $tfile failed"
1582         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1583 }
1584 run_test 26f "rm -r of a directory which has recursive symlink"
1585
1586 test_27a() {
1587         test_mkdir $DIR/$tdir
1588         $LFS getstripe $DIR/$tdir
1589         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1590         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1591         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1592 }
1593 run_test 27a "one stripe file"
1594
1595 test_27b() {
1596         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1597
1598         test_mkdir $DIR/$tdir
1599         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1600         $LFS getstripe -c $DIR/$tdir/$tfile
1601         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1602                 error "two-stripe file doesn't have two stripes"
1603
1604         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1605 }
1606 run_test 27b "create and write to two stripe file"
1607
1608 # 27c family tests specific striping, setstripe -o
1609 test_27ca() {
1610         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1611         test_mkdir -p $DIR/$tdir
1612         local osts="1"
1613
1614         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1615         $LFS getstripe -i $DIR/$tdir/$tfile
1616         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1617                 error "stripe not on specified OST"
1618
1619         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1620 }
1621 run_test 27ca "one stripe on specified OST"
1622
1623 test_27cb() {
1624         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1625         test_mkdir -p $DIR/$tdir
1626         local osts="1,0"
1627         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1628         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1629         echo "$getstripe"
1630
1631         # Strip getstripe output to a space separated list of OSTs
1632         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1633                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1634         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1635                 error "stripes not on specified OSTs"
1636
1637         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1638 }
1639 run_test 27cb "two stripes on specified OSTs"
1640
1641 test_27cc() {
1642         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1643         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1644                 skip "server does not support overstriping"
1645
1646         test_mkdir -p $DIR/$tdir
1647         local osts="0,0"
1648         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1649         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1650         echo "$getstripe"
1651
1652         # Strip getstripe output to a space separated list of OSTs
1653         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1654                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1655         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1656                 error "stripes not on specified OSTs"
1657
1658         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1659 }
1660 run_test 27cc "two stripes on the same OST"
1661
1662 test_27cd() {
1663         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1664         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1665                 skip "server does not support overstriping"
1666         test_mkdir -p $DIR/$tdir
1667         local osts="0,1,1,0"
1668         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1669         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1670         echo "$getstripe"
1671
1672         # Strip getstripe output to a space separated list of OSTs
1673         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1674                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1675         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1676                 error "stripes not on specified OSTs"
1677
1678         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1679 }
1680 run_test 27cd "four stripes on two OSTs"
1681
1682 test_27ce() {
1683         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1684                 skip_env "too many osts, skipping"
1685         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1686                 skip "server does not support overstriping"
1687         # We do one more stripe than we have OSTs
1688         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1689                 skip_env "ea_inode feature disabled"
1690
1691         test_mkdir -p $DIR/$tdir
1692         local osts=""
1693         for i in $(seq 0 $OSTCOUNT);
1694         do
1695                 osts=$osts"0"
1696                 if [ $i -ne $OSTCOUNT ]; then
1697                         osts=$osts","
1698                 fi
1699         done
1700         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1701         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1702         echo "$getstripe"
1703
1704         # Strip getstripe output to a space separated list of OSTs
1705         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1706                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1707         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1708                 error "stripes not on specified OSTs"
1709
1710         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1711 }
1712 run_test 27ce "more stripes than OSTs with -o"
1713
1714 test_27cf() {
1715         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1716         local pid=0
1717
1718         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1719         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1720         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1721         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1722                 error "failed to set $osp_proc=0"
1723
1724         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1725         pid=$!
1726         sleep 1
1727         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1728         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1729                 error "failed to set $osp_proc=1"
1730         wait $pid
1731         [[ $pid -ne 0 ]] ||
1732                 error "should return error due to $osp_proc=0"
1733 }
1734 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1735
1736 test_27d() {
1737         test_mkdir $DIR/$tdir
1738         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1739                 error "setstripe failed"
1740         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1741         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1742 }
1743 run_test 27d "create file with default settings"
1744
1745 test_27e() {
1746         # LU-5839 adds check for existed layout before setting it
1747         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1748                 skip "Need MDS version at least 2.7.56"
1749
1750         test_mkdir $DIR/$tdir
1751         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1752         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1753         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1754 }
1755 run_test 27e "setstripe existing file (should return error)"
1756
1757 test_27f() {
1758         test_mkdir $DIR/$tdir
1759         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1760                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1761         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1762                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1763         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1764         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1765 }
1766 run_test 27f "setstripe with bad stripe size (should return error)"
1767
1768 test_27g() {
1769         test_mkdir $DIR/$tdir
1770         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1771         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1772                 error "$DIR/$tdir/$tfile has object"
1773 }
1774 run_test 27g "$LFS getstripe with no objects"
1775
1776 test_27ga() {
1777         test_mkdir $DIR/$tdir
1778         touch $DIR/$tdir/$tfile || error "touch failed"
1779         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1780         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1781         local rc=$?
1782         (( rc == 2 )) || error "getstripe did not return ENOENT"
1783 }
1784 run_test 27ga "$LFS getstripe with missing file (should return error)"
1785
1786 test_27i() {
1787         test_mkdir $DIR/$tdir
1788         touch $DIR/$tdir/$tfile || error "touch failed"
1789         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1790                 error "missing objects"
1791 }
1792 run_test 27i "$LFS getstripe with some objects"
1793
1794 test_27j() {
1795         test_mkdir $DIR/$tdir
1796         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1797                 error "setstripe failed" || true
1798 }
1799 run_test 27j "setstripe with bad stripe offset (should return error)"
1800
1801 test_27k() { # bug 2844
1802         test_mkdir $DIR/$tdir
1803         local file=$DIR/$tdir/$tfile
1804         local ll_max_blksize=$((4 * 1024 * 1024))
1805         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1806         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1807         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1808         dd if=/dev/zero of=$file bs=4k count=1
1809         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1810         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1811 }
1812 run_test 27k "limit i_blksize for broken user apps"
1813
1814 test_27l() {
1815         mcreate $DIR/$tfile || error "creating file"
1816         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1817                 error "setstripe should have failed" || true
1818 }
1819 run_test 27l "check setstripe permissions (should return error)"
1820
1821 test_27m() {
1822         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1823
1824         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1825                 skip_env "multiple clients -- skipping"
1826
1827         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1828                    head -n1)
1829         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1830                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1831         fi
1832         stack_trap simple_cleanup_common
1833         test_mkdir $DIR/$tdir
1834         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1835         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1836                 error "dd should fill OST0"
1837         i=2
1838         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1839                 i=$((i + 1))
1840                 [ $i -gt 256 ] && break
1841         done
1842         i=$((i + 1))
1843         touch $DIR/$tdir/$tfile.$i
1844         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1845             awk '{print $1}'| grep -w "0") ] &&
1846                 error "OST0 was full but new created file still use it"
1847         i=$((i + 1))
1848         touch $DIR/$tdir/$tfile.$i
1849         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1850             awk '{print $1}'| grep -w "0") ] &&
1851                 error "OST0 was full but new created file still use it" || true
1852 }
1853 run_test 27m "create file while OST0 was full"
1854
1855 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1856 # if the OST isn't full anymore.
1857 reset_enospc() {
1858         local ostidx=${1:-""}
1859         local delay
1860         local ready
1861         local get_prealloc
1862
1863         local list=$(comma_list $(osts_nodes))
1864         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1865
1866         do_nodes $list lctl set_param fail_loc=0
1867         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1868         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1869                 awk '{print $1 * 2;exit;}')
1870         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1871                         grep -v \"^0$\""
1872         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1873 }
1874
1875 test_27n() {
1876         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1878         remote_mds_nodsh && skip "remote MDS with nodsh"
1879         remote_ost_nodsh && skip "remote OST with nodsh"
1880
1881         reset_enospc
1882         rm -f $DIR/$tdir/$tfile
1883         exhaust_precreations 0 0x80000215
1884         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1885         touch $DIR/$tdir/$tfile || error "touch failed"
1886         $LFS getstripe $DIR/$tdir/$tfile
1887         reset_enospc
1888 }
1889 run_test 27n "create file with some full OSTs"
1890
1891 test_27o() {
1892         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1894         remote_mds_nodsh && skip "remote MDS with nodsh"
1895         remote_ost_nodsh && skip "remote OST with nodsh"
1896
1897         reset_enospc
1898         rm -f $DIR/$tdir/$tfile
1899         exhaust_all_precreations 0x215
1900
1901         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1902
1903         reset_enospc
1904         rm -rf $DIR/$tdir/*
1905 }
1906 run_test 27o "create file with all full OSTs (should error)"
1907
1908 function create_and_checktime() {
1909         local fname=$1
1910         local loops=$2
1911         local i
1912
1913         for ((i=0; i < $loops; i++)); do
1914                 local start=$SECONDS
1915                 multiop $fname-$i Oc
1916                 ((SECONDS-start < TIMEOUT)) ||
1917                         error "creation took " $((SECONDS-$start)) && return 1
1918         done
1919 }
1920
1921 test_27oo() {
1922         local mdts=$(comma_list $(mdts_nodes))
1923
1924         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1925                 skip "Need MDS version at least 2.13.57"
1926
1927         local f0=$DIR/${tfile}-0
1928         local f1=$DIR/${tfile}-1
1929
1930         wait_delete_completed
1931
1932         # refill precreated objects
1933         $LFS setstripe -i0 -c1 $f0
1934
1935         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1936         # force QoS allocation policy
1937         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1938         stack_trap "do_nodes $mdts $LCTL set_param \
1939                 lov.*.qos_threshold_rr=$saved" EXIT
1940         sleep_maxage
1941
1942         # one OST is unavailable, but still have few objects preallocated
1943         stop ost1
1944         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1945                 rm -rf $f1 $DIR/$tdir*" EXIT
1946
1947         for ((i=0; i < 7; i++)); do
1948                 mkdir $DIR/$tdir$i || error "can't create dir"
1949                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1950                         error "can't set striping"
1951         done
1952         for ((i=0; i < 7; i++)); do
1953                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1954         done
1955         wait
1956 }
1957 run_test 27oo "don't let few threads to reserve too many objects"
1958
1959 test_27p() {
1960         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1962         remote_mds_nodsh && skip "remote MDS with nodsh"
1963         remote_ost_nodsh && skip "remote OST with nodsh"
1964
1965         reset_enospc
1966         rm -f $DIR/$tdir/$tfile
1967         test_mkdir $DIR/$tdir
1968
1969         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1970         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1971         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1972
1973         exhaust_precreations 0 0x80000215
1974         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1975         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1976         $LFS getstripe $DIR/$tdir/$tfile
1977
1978         reset_enospc
1979 }
1980 run_test 27p "append to a truncated file with some full OSTs"
1981
1982 test_27q() {
1983         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1985         remote_mds_nodsh && skip "remote MDS with nodsh"
1986         remote_ost_nodsh && skip "remote OST with nodsh"
1987
1988         reset_enospc
1989         rm -f $DIR/$tdir/$tfile
1990
1991         mkdir_on_mdt0 $DIR/$tdir
1992         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1993         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1994                 error "truncate $DIR/$tdir/$tfile failed"
1995         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1996
1997         exhaust_all_precreations 0x215
1998
1999         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2000         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2001
2002         reset_enospc
2003 }
2004 run_test 27q "append to truncated file with all OSTs full (should error)"
2005
2006 test_27r() {
2007         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2009         remote_mds_nodsh && skip "remote MDS with nodsh"
2010         remote_ost_nodsh && skip "remote OST with nodsh"
2011
2012         reset_enospc
2013         rm -f $DIR/$tdir/$tfile
2014         exhaust_precreations 0 0x80000215
2015
2016         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2017
2018         reset_enospc
2019 }
2020 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2021
2022 test_27s() { # bug 10725
2023         test_mkdir $DIR/$tdir
2024         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2025         local stripe_count=0
2026         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2027         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2028                 error "stripe width >= 2^32 succeeded" || true
2029
2030 }
2031 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2032
2033 test_27t() { # bug 10864
2034         WDIR=$(pwd)
2035         WLFS=$(which lfs)
2036         cd $DIR
2037         touch $tfile
2038         $WLFS getstripe $tfile
2039         cd $WDIR
2040 }
2041 run_test 27t "check that utils parse path correctly"
2042
2043 test_27u() { # bug 4900
2044         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2045         remote_mds_nodsh && skip "remote MDS with nodsh"
2046
2047         local index
2048         local list=$(comma_list $(mdts_nodes))
2049
2050 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2051         do_nodes $list $LCTL set_param fail_loc=0x139
2052         test_mkdir -p $DIR/$tdir
2053         stack_trap "simple_cleanup_common 1000"
2054         createmany -o $DIR/$tdir/$tfile 1000
2055         do_nodes $list $LCTL set_param fail_loc=0
2056
2057         TLOG=$TMP/$tfile.getstripe
2058         $LFS getstripe $DIR/$tdir > $TLOG
2059         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2060         [[ $OBJS -gt 0 ]] &&
2061                 error "$OBJS objects created on OST-0. See $TLOG" ||
2062                 rm -f $TLOG
2063 }
2064 run_test 27u "skip object creation on OSC w/o objects"
2065
2066 test_27v() { # bug 4900
2067         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2069         remote_mds_nodsh && skip "remote MDS with nodsh"
2070         remote_ost_nodsh && skip "remote OST with nodsh"
2071
2072         exhaust_all_precreations 0x215
2073         reset_enospc
2074
2075         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2076
2077         touch $DIR/$tdir/$tfile
2078         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2079         # all except ost1
2080         for (( i=1; i < OSTCOUNT; i++ )); do
2081                 do_facet ost$i lctl set_param fail_loc=0x705
2082         done
2083         local START=`date +%s`
2084         createmany -o $DIR/$tdir/$tfile 32
2085
2086         local FINISH=`date +%s`
2087         local TIMEOUT=`lctl get_param -n timeout`
2088         local PROCESS=$((FINISH - START))
2089         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2090                error "$FINISH - $START >= $TIMEOUT / 2"
2091         sleep $((TIMEOUT / 2 - PROCESS))
2092         reset_enospc
2093 }
2094 run_test 27v "skip object creation on slow OST"
2095
2096 test_27w() { # bug 10997
2097         test_mkdir $DIR/$tdir
2098         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2099         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2100                 error "stripe size $size != 65536" || true
2101         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2102                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2103 }
2104 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2105
2106 test_27wa() {
2107         [[ $OSTCOUNT -lt 2 ]] &&
2108                 skip_env "skipping multiple stripe count/offset test"
2109
2110         test_mkdir $DIR/$tdir
2111         for i in $(seq 1 $OSTCOUNT); do
2112                 offset=$((i - 1))
2113                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2114                         error "setstripe -c $i -i $offset failed"
2115                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2116                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2117                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2118                 [ $index -ne $offset ] &&
2119                         error "stripe offset $index != $offset" || true
2120         done
2121 }
2122 run_test 27wa "check $LFS setstripe -c -i options"
2123
2124 test_27x() {
2125         remote_ost_nodsh && skip "remote OST with nodsh"
2126         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2128
2129         OFFSET=$(($OSTCOUNT - 1))
2130         OSTIDX=0
2131         local OST=$(ostname_from_index $OSTIDX)
2132
2133         test_mkdir $DIR/$tdir
2134         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2135         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2136         sleep_maxage
2137         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2138         for i in $(seq 0 $OFFSET); do
2139                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2140                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2141                 error "OST0 was degraded but new created file still use it"
2142         done
2143         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2144 }
2145 run_test 27x "create files while OST0 is degraded"
2146
2147 test_27y() {
2148         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2149         remote_mds_nodsh && skip "remote MDS with nodsh"
2150         remote_ost_nodsh && skip "remote OST with nodsh"
2151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2152
2153         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2154         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2155                 osp.$mdtosc.prealloc_last_id)
2156         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2157                 osp.$mdtosc.prealloc_next_id)
2158         local fcount=$((last_id - next_id))
2159         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2160         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2161
2162         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2163                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2164         local OST_DEACTIVE_IDX=-1
2165         local OSC
2166         local OSTIDX
2167         local OST
2168
2169         for OSC in $MDS_OSCS; do
2170                 OST=$(osc_to_ost $OSC)
2171                 OSTIDX=$(index_from_ostuuid $OST)
2172                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2173                         OST_DEACTIVE_IDX=$OSTIDX
2174                 fi
2175                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2176                         echo $OSC "is Deactivated:"
2177                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2178                 fi
2179         done
2180
2181         OSTIDX=$(index_from_ostuuid $OST)
2182         test_mkdir $DIR/$tdir
2183         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2184
2185         for OSC in $MDS_OSCS; do
2186                 OST=$(osc_to_ost $OSC)
2187                 OSTIDX=$(index_from_ostuuid $OST)
2188                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2189                         echo $OST "is degraded:"
2190                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2191                                                 obdfilter.$OST.degraded=1
2192                 fi
2193         done
2194
2195         sleep_maxage
2196         createmany -o $DIR/$tdir/$tfile $fcount
2197
2198         for OSC in $MDS_OSCS; do
2199                 OST=$(osc_to_ost $OSC)
2200                 OSTIDX=$(index_from_ostuuid $OST)
2201                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2202                         echo $OST "is recovered from degraded:"
2203                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2204                                                 obdfilter.$OST.degraded=0
2205                 else
2206                         do_facet $SINGLEMDS lctl --device %$OSC activate
2207                 fi
2208         done
2209
2210         # all osp devices get activated, hence -1 stripe count restored
2211         local stripe_count=0
2212
2213         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2214         # devices get activated.
2215         sleep_maxage
2216         $LFS setstripe -c -1 $DIR/$tfile
2217         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2218         rm -f $DIR/$tfile
2219         [ $stripe_count -ne $OSTCOUNT ] &&
2220                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2221         return 0
2222 }
2223 run_test 27y "create files while OST0 is degraded and the rest inactive"
2224
2225 check_seq_oid()
2226 {
2227         log "check file $1"
2228
2229         lmm_count=$($LFS getstripe -c $1)
2230         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2231         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2232
2233         local old_ifs="$IFS"
2234         IFS=$'[:]'
2235         fid=($($LFS path2fid $1))
2236         IFS="$old_ifs"
2237
2238         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2239         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2240
2241         # compare lmm_seq and lu_fid->f_seq
2242         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2243         # compare lmm_object_id and lu_fid->oid
2244         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2245
2246         # check the trusted.fid attribute of the OST objects of the file
2247         local have_obdidx=false
2248         local stripe_nr=0
2249         $LFS getstripe $1 | while read obdidx oid hex seq; do
2250                 # skip lines up to and including "obdidx"
2251                 [ -z "$obdidx" ] && break
2252                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2253                 $have_obdidx || continue
2254
2255                 local ost=$((obdidx + 1))
2256                 local dev=$(ostdevname $ost)
2257                 local oid_hex
2258
2259                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2260
2261                 seq=$(echo $seq | sed -e "s/^0x//g")
2262                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2263                         oid_hex=$(echo $oid)
2264                 else
2265                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2266                 fi
2267                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2268
2269                 local ff=""
2270                 #
2271                 # Don't unmount/remount the OSTs if we don't need to do that.
2272                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2273                 # update too, until that use mount/ll_decode_filter_fid/mount.
2274                 # Re-enable when debugfs will understand new filter_fid.
2275                 #
2276                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2277                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2278                                 $dev 2>/dev/null" | grep "parent=")
2279                 fi
2280                 if [ -z "$ff" ]; then
2281                         stop ost$ost
2282                         mount_fstype ost$ost
2283                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2284                                 $(facet_mntpt ost$ost)/$obj_file)
2285                         unmount_fstype ost$ost
2286                         start ost$ost $dev $OST_MOUNT_OPTS
2287                         clients_up
2288                 fi
2289
2290                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2291
2292                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2293
2294                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2295                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2296                 #
2297                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2298                 #       stripe_size=1048576 component_id=1 component_start=0 \
2299                 #       component_end=33554432
2300                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2301                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2302                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2303                 local ff_pstripe
2304                 if grep -q 'stripe=' <<<$ff; then
2305                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2306                 else
2307                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2308                         # into f_ver in this case.  See comment on ff_parent.
2309                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2310                 fi
2311
2312                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2313                 [ $ff_pseq = $lmm_seq ] ||
2314                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2315                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2316                 [ $ff_poid = $lmm_oid ] ||
2317                         error "FF parent OID $ff_poid != $lmm_oid"
2318                 (($ff_pstripe == $stripe_nr)) ||
2319                         error "FF stripe $ff_pstripe != $stripe_nr"
2320
2321                 stripe_nr=$((stripe_nr + 1))
2322                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2323                         continue
2324                 if grep -q 'stripe_count=' <<<$ff; then
2325                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2326                                             -e 's/ .*//' <<<$ff)
2327                         [ $lmm_count = $ff_scnt ] ||
2328                                 error "FF stripe count $lmm_count != $ff_scnt"
2329                 fi
2330         done
2331 }
2332
2333 test_27z() {
2334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2335         remote_ost_nodsh && skip "remote OST with nodsh"
2336
2337         test_mkdir $DIR/$tdir
2338         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2339                 { error "setstripe -c -1 failed"; return 1; }
2340         # We need to send a write to every object to get parent FID info set.
2341         # This _should_ also work for setattr, but does not currently.
2342         # touch $DIR/$tdir/$tfile-1 ||
2343         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2344                 { error "dd $tfile-1 failed"; return 2; }
2345         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2346                 { error "setstripe -c -1 failed"; return 3; }
2347         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2348                 { error "dd $tfile-2 failed"; return 4; }
2349
2350         # make sure write RPCs have been sent to OSTs
2351         sync; sleep 5; sync
2352
2353         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2354         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2355 }
2356 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2357
2358 test_27A() { # b=19102
2359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2360
2361         save_layout_restore_at_exit $MOUNT
2362         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2363         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2364                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2365         local default_size=$($LFS getstripe -S $MOUNT)
2366         local default_offset=$($LFS getstripe -i $MOUNT)
2367         local dsize=$(do_facet $SINGLEMDS \
2368                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2369         [ $default_size -eq $dsize ] ||
2370                 error "stripe size $default_size != $dsize"
2371         [ $default_offset -eq -1 ] ||
2372                 error "stripe offset $default_offset != -1"
2373 }
2374 run_test 27A "check filesystem-wide default LOV EA values"
2375
2376 test_27B() { # LU-2523
2377         test_mkdir $DIR/$tdir
2378         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2379         touch $DIR/$tdir/f0
2380         # open f1 with O_LOV_DELAY_CREATE
2381         # rename f0 onto f1
2382         # call setstripe ioctl on open file descriptor for f1
2383         # close
2384         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2385                 $DIR/$tdir/f0
2386
2387         rm -f $DIR/$tdir/f1
2388         # open f1 with O_LOV_DELAY_CREATE
2389         # unlink f1
2390         # call setstripe ioctl on open file descriptor for f1
2391         # close
2392         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2393
2394         # Allow multiop to fail in imitation of NFS's busted semantics.
2395         true
2396 }
2397 run_test 27B "call setstripe on open unlinked file/rename victim"
2398
2399 # 27C family tests full striping and overstriping
2400 test_27Ca() { #LU-2871
2401         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2402
2403         declare -a ost_idx
2404         local index
2405         local found
2406         local i
2407         local j
2408
2409         test_mkdir $DIR/$tdir
2410         cd $DIR/$tdir
2411         for i in $(seq 0 $((OSTCOUNT - 1))); do
2412                 # set stripe across all OSTs starting from OST$i
2413                 $LFS setstripe -i $i -c -1 $tfile$i
2414                 # get striping information
2415                 ost_idx=($($LFS getstripe $tfile$i |
2416                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2417                 echo ${ost_idx[@]}
2418
2419                 # check the layout
2420                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2421                         error "${#ost_idx[@]} != $OSTCOUNT"
2422
2423                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2424                         found=0
2425                         for j in $(echo ${ost_idx[@]}); do
2426                                 if [ $index -eq $j ]; then
2427                                         found=1
2428                                         break
2429                                 fi
2430                         done
2431                         [ $found = 1 ] ||
2432                                 error "Can not find $index in ${ost_idx[@]}"
2433                 done
2434         done
2435 }
2436 run_test 27Ca "check full striping across all OSTs"
2437
2438 test_27Cb() {
2439         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2440                 skip "server does not support overstriping"
2441         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2442                 skip_env "too many osts, skipping"
2443
2444         test_mkdir -p $DIR/$tdir
2445         local setcount=$(($OSTCOUNT * 2))
2446         [ $setcount -lt 160 ] || large_xattr_enabled ||
2447                 skip_env "ea_inode feature disabled"
2448
2449         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2450                 error "setstripe failed"
2451
2452         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2453         [ $count -eq $setcount ] ||
2454                 error "stripe count $count, should be $setcount"
2455
2456         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2457                 error "overstriped should be set in pattern"
2458
2459         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2460                 error "dd failed"
2461 }
2462 run_test 27Cb "more stripes than OSTs with -C"
2463
2464 test_27Cc() {
2465         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2466                 skip "server does not support overstriping"
2467         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2468
2469         test_mkdir -p $DIR/$tdir
2470         local setcount=$(($OSTCOUNT - 1))
2471
2472         [ $setcount -lt 160 ] || large_xattr_enabled ||
2473                 skip_env "ea_inode feature disabled"
2474
2475         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2476                 error "setstripe failed"
2477
2478         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2479         [ $count -eq $setcount ] ||
2480                 error "stripe count $count, should be $setcount"
2481
2482         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2483                 error "overstriped should not be set in pattern"
2484
2485         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2486                 error "dd failed"
2487 }
2488 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2489
2490 test_27Cd() {
2491         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2492                 skip "server does not support overstriping"
2493         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2494         large_xattr_enabled || skip_env "ea_inode feature disabled"
2495
2496         test_mkdir -p $DIR/$tdir
2497         local setcount=$LOV_MAX_STRIPE_COUNT
2498
2499         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2500                 error "setstripe failed"
2501
2502         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2503         [ $count -eq $setcount ] ||
2504                 error "stripe count $count, should be $setcount"
2505
2506         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2507                 error "overstriped should be set in pattern"
2508
2509         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2510                 error "dd failed"
2511
2512         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2513 }
2514 run_test 27Cd "test maximum stripe count"
2515
2516 test_27Ce() {
2517         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2518                 skip "server does not support overstriping"
2519         test_mkdir -p $DIR/$tdir
2520
2521         pool_add $TESTNAME || error "Pool creation failed"
2522         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2523
2524         local setcount=8
2525
2526         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2527                 error "setstripe failed"
2528
2529         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2530         [ $count -eq $setcount ] ||
2531                 error "stripe count $count, should be $setcount"
2532
2533         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2534                 error "overstriped should be set in pattern"
2535
2536         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2537                 error "dd failed"
2538
2539         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2540 }
2541 run_test 27Ce "test pool with overstriping"
2542
2543 test_27Cf() {
2544         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2545                 skip "server does not support overstriping"
2546         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2547                 skip_env "too many osts, skipping"
2548
2549         test_mkdir -p $DIR/$tdir
2550
2551         local setcount=$(($OSTCOUNT * 2))
2552         [ $setcount -lt 160 ] || large_xattr_enabled ||
2553                 skip_env "ea_inode feature disabled"
2554
2555         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2556                 error "setstripe failed"
2557
2558         echo 1 > $DIR/$tdir/$tfile
2559
2560         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2561         [ $count -eq $setcount ] ||
2562                 error "stripe count $count, should be $setcount"
2563
2564         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2565                 error "overstriped should be set in pattern"
2566
2567         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2568                 error "dd failed"
2569
2570         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2571 }
2572 run_test 27Cf "test default inheritance with overstriping"
2573
2574 test_27D() {
2575         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2576         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2577         remote_mds_nodsh && skip "remote MDS with nodsh"
2578
2579         local POOL=${POOL:-testpool}
2580         local first_ost=0
2581         local last_ost=$(($OSTCOUNT - 1))
2582         local ost_step=1
2583         local ost_list=$(seq $first_ost $ost_step $last_ost)
2584         local ost_range="$first_ost $last_ost $ost_step"
2585
2586         test_mkdir $DIR/$tdir
2587         pool_add $POOL || error "pool_add failed"
2588         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2589
2590         local skip27D
2591         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2592                 skip27D+="-s 29"
2593         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2594                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2595                         skip27D+=" -s 30,31"
2596         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2597           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2598                 skip27D+=" -s 32,33"
2599         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2600                 skip27D+=" -s 34"
2601         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2602                 error "llapi_layout_test failed"
2603
2604         destroy_test_pools || error "destroy test pools failed"
2605 }
2606 run_test 27D "validate llapi_layout API"
2607
2608 # Verify that default_easize is increased from its initial value after
2609 # accessing a widely striped file.
2610 test_27E() {
2611         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2612         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2613                 skip "client does not have LU-3338 fix"
2614
2615         # 72 bytes is the minimum space required to store striping
2616         # information for a file striped across one OST:
2617         # (sizeof(struct lov_user_md_v3) +
2618         #  sizeof(struct lov_user_ost_data_v1))
2619         local min_easize=72
2620         $LCTL set_param -n llite.*.default_easize $min_easize ||
2621                 error "lctl set_param failed"
2622         local easize=$($LCTL get_param -n llite.*.default_easize)
2623
2624         [ $easize -eq $min_easize ] ||
2625                 error "failed to set default_easize"
2626
2627         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2628                 error "setstripe failed"
2629         # In order to ensure stat() call actually talks to MDS we need to
2630         # do something drastic to this file to shake off all lock, e.g.
2631         # rename it (kills lookup lock forcing cache cleaning)
2632         mv $DIR/$tfile $DIR/${tfile}-1
2633         ls -l $DIR/${tfile}-1
2634         rm $DIR/${tfile}-1
2635
2636         easize=$($LCTL get_param -n llite.*.default_easize)
2637
2638         [ $easize -gt $min_easize ] ||
2639                 error "default_easize not updated"
2640 }
2641 run_test 27E "check that default extended attribute size properly increases"
2642
2643 test_27F() { # LU-5346/LU-7975
2644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2645         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2646         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2647                 skip "Need MDS version at least 2.8.51"
2648         remote_ost_nodsh && skip "remote OST with nodsh"
2649
2650         test_mkdir $DIR/$tdir
2651         rm -f $DIR/$tdir/f0
2652         $LFS setstripe -c 2 $DIR/$tdir
2653
2654         # stop all OSTs to reproduce situation for LU-7975 ticket
2655         for num in $(seq $OSTCOUNT); do
2656                 stop ost$num
2657         done
2658
2659         # open/create f0 with O_LOV_DELAY_CREATE
2660         # truncate f0 to a non-0 size
2661         # close
2662         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2663
2664         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2665         # open/write it again to force delayed layout creation
2666         cat /etc/hosts > $DIR/$tdir/f0 &
2667         catpid=$!
2668
2669         # restart OSTs
2670         for num in $(seq $OSTCOUNT); do
2671                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2672                         error "ost$num failed to start"
2673         done
2674
2675         wait $catpid || error "cat failed"
2676
2677         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2678         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2679                 error "wrong stripecount"
2680
2681 }
2682 run_test 27F "Client resend delayed layout creation with non-zero size"
2683
2684 test_27G() { #LU-10629
2685         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2686                 skip "Need MDS version at least 2.11.51"
2687         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2688         remote_mds_nodsh && skip "remote MDS with nodsh"
2689         local POOL=${POOL:-testpool}
2690         local ostrange="0 0 1"
2691
2692         test_mkdir $DIR/$tdir
2693         touch $DIR/$tdir/$tfile.nopool
2694         pool_add $POOL || error "pool_add failed"
2695         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2696         $LFS setstripe -p $POOL $DIR/$tdir
2697
2698         local pool=$($LFS getstripe -p $DIR/$tdir)
2699
2700         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2701         touch $DIR/$tdir/$tfile.default
2702         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2703         $LFS find $DIR/$tdir -type f --pool $POOL
2704         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2705         [[ "$found" == "2" ]] ||
2706                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2707
2708         $LFS setstripe -d $DIR/$tdir
2709
2710         pool=$($LFS getstripe -p -d $DIR/$tdir)
2711
2712         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2713 }
2714 run_test 27G "Clear OST pool from stripe"
2715
2716 test_27H() {
2717         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2718                 skip "Need MDS version newer than 2.11.54"
2719         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2720         test_mkdir $DIR/$tdir
2721         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2722         touch $DIR/$tdir/$tfile
2723         $LFS getstripe -c $DIR/$tdir/$tfile
2724         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2725                 error "two-stripe file doesn't have two stripes"
2726
2727         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2728         $LFS getstripe -y $DIR/$tdir/$tfile
2729         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2730              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2731                 error "expected l_ost_idx: [02]$ not matched"
2732
2733         # make sure ost list has been cleared
2734         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2735         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2736                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2737         touch $DIR/$tdir/f3
2738         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2739 }
2740 run_test 27H "Set specific OSTs stripe"
2741
2742 test_27I() {
2743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2744         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2745         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2746                 skip "Need MDS version newer than 2.12.52"
2747         local pool=$TESTNAME
2748         local ostrange="1 1 1"
2749
2750         save_layout_restore_at_exit $MOUNT
2751         $LFS setstripe -c 2 -i 0 $MOUNT
2752         pool_add $pool || error "pool_add failed"
2753         pool_add_targets $pool $ostrange ||
2754                 error "pool_add_targets failed"
2755         test_mkdir $DIR/$tdir
2756         $LFS setstripe -p $pool $DIR/$tdir
2757         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2758         $LFS getstripe $DIR/$tdir/$tfile
2759 }
2760 run_test 27I "check that root dir striping does not break parent dir one"
2761
2762 test_27J() {
2763         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2764                 skip "Need MDS version newer than 2.12.51"
2765
2766         test_mkdir $DIR/$tdir
2767         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2768         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2769
2770         # create foreign file (raw way)
2771         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2772                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2773
2774         ! $LFS setstripe --foreign --flags foo \
2775                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2776                         error "creating $tfile with '--flags foo' should fail"
2777
2778         ! $LFS setstripe --foreign --flags 0xffffffff \
2779                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2780                         error "creating $tfile w/ 0xffffffff flags should fail"
2781
2782         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2783                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2784
2785         # verify foreign file (raw way)
2786         parse_foreign_file -f $DIR/$tdir/$tfile |
2787                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2788                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2789         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2790                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2791         parse_foreign_file -f $DIR/$tdir/$tfile |
2792                 grep "lov_foreign_size: 73" ||
2793                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2794         parse_foreign_file -f $DIR/$tdir/$tfile |
2795                 grep "lov_foreign_type: 1" ||
2796                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2797         parse_foreign_file -f $DIR/$tdir/$tfile |
2798                 grep "lov_foreign_flags: 0x0000DA08" ||
2799                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2800         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2801                 grep "lov_foreign_value: 0x" |
2802                 sed -e 's/lov_foreign_value: 0x//')
2803         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2804         [[ $lov = ${lov2// /} ]] ||
2805                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2806
2807         # create foreign file (lfs + API)
2808         $LFS setstripe --foreign=none --flags 0xda08 \
2809                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2810                 error "$DIR/$tdir/${tfile}2: create failed"
2811
2812         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2813                 grep "lfm_magic:.*0x0BD70BD0" ||
2814                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2815         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2816         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2817                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2818         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2819                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2820         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2821                 grep "lfm_flags:.*0x0000DA08" ||
2822                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2823         $LFS getstripe $DIR/$tdir/${tfile}2 |
2824                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2825                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2826
2827         # modify striping should fail
2828         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2829                 error "$DIR/$tdir/$tfile: setstripe should fail"
2830         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2831                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2832
2833         # R/W should fail
2834         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2835         cat $DIR/$tdir/${tfile}2 &&
2836                 error "$DIR/$tdir/${tfile}2: read should fail"
2837         cat /etc/passwd > $DIR/$tdir/$tfile &&
2838                 error "$DIR/$tdir/$tfile: write should fail"
2839         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2840                 error "$DIR/$tdir/${tfile}2: write should fail"
2841
2842         # chmod should work
2843         chmod 222 $DIR/$tdir/$tfile ||
2844                 error "$DIR/$tdir/$tfile: chmod failed"
2845         chmod 222 $DIR/$tdir/${tfile}2 ||
2846                 error "$DIR/$tdir/${tfile}2: chmod failed"
2847
2848         # chown should work
2849         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2850                 error "$DIR/$tdir/$tfile: chown failed"
2851         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2852                 error "$DIR/$tdir/${tfile}2: chown failed"
2853
2854         # rename should work
2855         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2856                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2857         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2858                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2859
2860         #remove foreign file
2861         rm $DIR/$tdir/${tfile}.new ||
2862                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2863         rm $DIR/$tdir/${tfile}2.new ||
2864                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2865 }
2866 run_test 27J "basic ops on file with foreign LOV"
2867
2868 test_27K() {
2869         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2870                 skip "Need MDS version newer than 2.12.49"
2871
2872         test_mkdir $DIR/$tdir
2873         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2874         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2875
2876         # create foreign dir (raw way)
2877         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2878                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2879
2880         ! $LFS setdirstripe --foreign --flags foo \
2881                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2882                         error "creating $tdir with '--flags foo' should fail"
2883
2884         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2885                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2886                         error "creating $tdir w/ 0xffffffff flags should fail"
2887
2888         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2889                 error "create_foreign_dir FAILED"
2890
2891         # verify foreign dir (raw way)
2892         parse_foreign_dir -d $DIR/$tdir/$tdir |
2893                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2894                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2895         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2896                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2897         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2898                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2899         parse_foreign_dir -d $DIR/$tdir/$tdir |
2900                 grep "lmv_foreign_flags: 55813$" ||
2901                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2902         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2903                 grep "lmv_foreign_value: 0x" |
2904                 sed 's/lmv_foreign_value: 0x//')
2905         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2906                 sed 's/ //g')
2907         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2908
2909         # create foreign dir (lfs + API)
2910         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2911                 $DIR/$tdir/${tdir}2 ||
2912                 error "$DIR/$tdir/${tdir}2: create failed"
2913
2914         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2915                 grep "lfm_magic:.*0x0CD50CD0" ||
2916                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2917         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2918         # - sizeof(lfm_type) - sizeof(lfm_flags)
2919         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2920                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2921         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2922                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2923         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2924                 grep "lfm_flags:.*0x0000DA05" ||
2925                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2926         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2927                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2928                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2929
2930         # file create in dir should fail
2931         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2932         touch $DIR/$tdir/${tdir}2/$tfile &&
2933                 error "$DIR/${tdir}2: file create should fail"
2934
2935         # chmod should work
2936         chmod 777 $DIR/$tdir/$tdir ||
2937                 error "$DIR/$tdir: chmod failed"
2938         chmod 777 $DIR/$tdir/${tdir}2 ||
2939                 error "$DIR/${tdir}2: chmod failed"
2940
2941         # chown should work
2942         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2943                 error "$DIR/$tdir: chown failed"
2944         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2945                 error "$DIR/${tdir}2: chown failed"
2946
2947         # rename should work
2948         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2949                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2950         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2951                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2952
2953         #remove foreign dir
2954         rmdir $DIR/$tdir/${tdir}.new ||
2955                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2956         rmdir $DIR/$tdir/${tdir}2.new ||
2957                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2958 }
2959 run_test 27K "basic ops on dir with foreign LMV"
2960
2961 test_27L() {
2962         remote_mds_nodsh && skip "remote MDS with nodsh"
2963
2964         local POOL=${POOL:-$TESTNAME}
2965
2966         pool_add $POOL || error "pool_add failed"
2967
2968         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2969                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2970                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2971 }
2972 run_test 27L "lfs pool_list gives correct pool name"
2973
2974 test_27M() {
2975         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2976                 skip "Need MDS version >= than 2.12.57"
2977         remote_mds_nodsh && skip "remote MDS with nodsh"
2978         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2979
2980         test_mkdir $DIR/$tdir
2981
2982         # Set default striping on directory
2983         local setcount=4
2984         local stripe_opt
2985
2986         # if we run against a 2.12 server which lacks overstring support
2987         # then the connect_flag will not report overstriping, even if client
2988         # is 2.14+
2989         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
2990                 stripe_opt="-C $setcount"
2991         elif (( $OSTCOUNT >= $setcount )); then
2992                 stripe_opt="-c $setcount"
2993         else
2994                 skip "server does not support overstriping"
2995         fi
2996         $LFS setstripe $stripe_opt $DIR/$tdir
2997
2998         echo 1 > $DIR/$tdir/${tfile}.1
2999         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3000         [ $count -eq $setcount ] ||
3001                 error "(1) stripe count $count, should be $setcount"
3002
3003         # Capture existing append_stripe_count setting for restore
3004         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3005         local mdts=$(comma_list $(mdts_nodes))
3006         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
3007
3008         local appendcount=$orig_count
3009         echo 1 >> $DIR/$tdir/${tfile}.2_append
3010         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3011         [ $count -eq $appendcount ] ||
3012                 error "(2)stripe count $count, should be $appendcount for append"
3013
3014         # Disable O_APPEND striping, verify it works
3015         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3016
3017         # Should now get the default striping, which is 4
3018         setcount=4
3019         echo 1 >> $DIR/$tdir/${tfile}.3_append
3020         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3021         [ $count -eq $setcount ] ||
3022                 error "(3) stripe count $count, should be $setcount"
3023
3024         # Try changing the stripe count for append files
3025         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3026
3027         # Append striping is now 2 (directory default is still 4)
3028         appendcount=2
3029         echo 1 >> $DIR/$tdir/${tfile}.4_append
3030         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3031         [ $count -eq $appendcount ] ||
3032                 error "(4) stripe count $count, should be $appendcount for append"
3033
3034         # Test append stripe count of -1
3035         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3036         appendcount=$OSTCOUNT
3037         echo 1 >> $DIR/$tdir/${tfile}.5
3038         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3039         [ $count -eq $appendcount ] ||
3040                 error "(5) stripe count $count, should be $appendcount for append"
3041
3042         # Set append striping back to default of 1
3043         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3044
3045         # Try a new default striping, PFL + DOM
3046         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3047
3048         # Create normal DOM file, DOM returns stripe count == 0
3049         setcount=0
3050         touch $DIR/$tdir/${tfile}.6
3051         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3052         [ $count -eq $setcount ] ||
3053                 error "(6) stripe count $count, should be $setcount"
3054
3055         # Show
3056         appendcount=1
3057         echo 1 >> $DIR/$tdir/${tfile}.7_append
3058         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3059         [ $count -eq $appendcount ] ||
3060                 error "(7) stripe count $count, should be $appendcount for append"
3061
3062         # Clean up DOM layout
3063         $LFS setstripe -d $DIR/$tdir
3064
3065         save_layout_restore_at_exit $MOUNT
3066         # Now test that append striping works when layout is from root
3067         $LFS setstripe -c 2 $MOUNT
3068         # Make a special directory for this
3069         mkdir $DIR/${tdir}/${tdir}.2
3070
3071         # Verify for normal file
3072         setcount=2
3073         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3074         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3075         [ $count -eq $setcount ] ||
3076                 error "(8) stripe count $count, should be $setcount"
3077
3078         appendcount=1
3079         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3080         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3081         [ $count -eq $appendcount ] ||
3082                 error "(9) stripe count $count, should be $appendcount for append"
3083
3084         # Now test O_APPEND striping with pools
3085         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3086         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3087
3088         # Create the pool
3089         pool_add $TESTNAME || error "pool creation failed"
3090         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3091
3092         echo 1 >> $DIR/$tdir/${tfile}.10_append
3093
3094         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3095         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3096
3097         # Check that count is still correct
3098         appendcount=1
3099         echo 1 >> $DIR/$tdir/${tfile}.11_append
3100         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3101         [ $count -eq $appendcount ] ||
3102                 error "(11) stripe count $count, should be $appendcount for append"
3103
3104         # Disable O_APPEND stripe count, verify pool works separately
3105         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3106
3107         echo 1 >> $DIR/$tdir/${tfile}.12_append
3108
3109         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3110         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3111
3112         # Remove pool setting, verify it's not applied
3113         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3114
3115         echo 1 >> $DIR/$tdir/${tfile}.13_append
3116
3117         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3118         [ "$pool" = "" ] || error "(13) pool found: $pool"
3119 }
3120 run_test 27M "test O_APPEND striping"
3121
3122 test_27N() {
3123         combined_mgs_mds && skip "needs separate MGS/MDT"
3124
3125         pool_add $TESTNAME || error "pool_add failed"
3126         do_facet mgs "$LCTL pool_list $FSNAME" |
3127                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3128                 error "lctl pool_list on MGS failed"
3129 }
3130 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3131
3132 clean_foreign_symlink() {
3133         trap 0
3134         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3135         for i in $DIR/$tdir/* ; do
3136                 $LFS unlink_foreign $i || true
3137         done
3138 }
3139
3140 test_27O() {
3141         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3142                 skip "Need MDS version newer than 2.12.51"
3143
3144         test_mkdir $DIR/$tdir
3145         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3146         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3147
3148         trap clean_foreign_symlink EXIT
3149
3150         # enable foreign_symlink behaviour
3151         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3152
3153         # foreign symlink LOV format is a partial path by default
3154
3155         # create foreign file (lfs + API)
3156         $LFS setstripe --foreign=symlink --flags 0xda05 \
3157                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3158                 error "$DIR/$tdir/${tfile}: create failed"
3159
3160         $LFS getstripe -v $DIR/$tdir/${tfile} |
3161                 grep "lfm_magic:.*0x0BD70BD0" ||
3162                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3163         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3164                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3165         $LFS getstripe -v $DIR/$tdir/${tfile} |
3166                 grep "lfm_flags:.*0x0000DA05" ||
3167                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3168         $LFS getstripe $DIR/$tdir/${tfile} |
3169                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3170                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3171
3172         # modify striping should fail
3173         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3174                 error "$DIR/$tdir/$tfile: setstripe should fail"
3175
3176         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3177         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3178         cat /etc/passwd > $DIR/$tdir/$tfile &&
3179                 error "$DIR/$tdir/$tfile: write should fail"
3180
3181         # rename should succeed
3182         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3183                 error "$DIR/$tdir/$tfile: rename has failed"
3184
3185         #remove foreign_symlink file should fail
3186         rm $DIR/$tdir/${tfile}.new &&
3187                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3188
3189         #test fake symlink
3190         mkdir /tmp/${uuid1} ||
3191                 error "/tmp/${uuid1}: mkdir has failed"
3192         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3193                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3194         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3195         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3196                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3197         #read should succeed now
3198         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3199                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3200         #write should succeed now
3201         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3202                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3203         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3204                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3205         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3206                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3207
3208         #check that getstripe still works
3209         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3210                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3211
3212         # chmod should still succeed
3213         chmod 644 $DIR/$tdir/${tfile}.new ||
3214                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3215
3216         # chown should still succeed
3217         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3218                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3219
3220         # rename should still succeed
3221         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3222                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3223
3224         #remove foreign_symlink file should still fail
3225         rm $DIR/$tdir/${tfile} &&
3226                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3227
3228         #use special ioctl() to unlink foreign_symlink file
3229         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3230                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3231
3232 }
3233 run_test 27O "basic ops on foreign file of symlink type"
3234
3235 test_27P() {
3236         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3237                 skip "Need MDS version newer than 2.12.49"
3238
3239         test_mkdir $DIR/$tdir
3240         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3241         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3242
3243         trap clean_foreign_symlink EXIT
3244
3245         # enable foreign_symlink behaviour
3246         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3247
3248         # foreign symlink LMV format is a partial path by default
3249
3250         # create foreign dir (lfs + API)
3251         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3252                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3253                 error "$DIR/$tdir/${tdir}: create failed"
3254
3255         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3256                 grep "lfm_magic:.*0x0CD50CD0" ||
3257                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3258         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3259                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3260         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3261                 grep "lfm_flags:.*0x0000DA05" ||
3262                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3263         $LFS getdirstripe $DIR/$tdir/${tdir} |
3264                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3265                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3266
3267         # file create in dir should fail
3268         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3269         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3270
3271         # rename should succeed
3272         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3273                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3274
3275         #remove foreign_symlink dir should fail
3276         rmdir $DIR/$tdir/${tdir}.new &&
3277                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3278
3279         #test fake symlink
3280         mkdir -p /tmp/${uuid1}/${uuid2} ||
3281                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3282         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3283                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3284         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3285         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3286                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3287         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3288                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3289
3290         #check that getstripe fails now that foreign_symlink enabled
3291         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3292                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3293
3294         # file create in dir should work now
3295         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3296                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3297         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3298                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3299         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3300                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3301
3302         # chmod should still succeed
3303         chmod 755 $DIR/$tdir/${tdir}.new ||
3304                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3305
3306         # chown should still succeed
3307         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3308                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3309
3310         # rename should still succeed
3311         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3312                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3313
3314         #remove foreign_symlink dir should still fail
3315         rmdir $DIR/$tdir/${tdir} &&
3316                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3317
3318         #use special ioctl() to unlink foreign_symlink file
3319         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3320                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3321
3322         #created file should still exist
3323         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3324                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3325         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3326                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3327 }
3328 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3329
3330 test_27Q() {
3331         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3332         stack_trap "rm -f $TMP/$tfile*"
3333
3334         test_mkdir $DIR/$tdir-1
3335         test_mkdir $DIR/$tdir-2
3336
3337         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3338         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3339
3340         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3341         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3342
3343         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3344         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3345
3346         # Create some bad symlinks and ensure that we don't loop
3347         # forever or something. These should return ELOOP (40) and
3348         # ENOENT (2) but I don't want to test for that because there's
3349         # always some weirdo architecture that needs to ruin
3350         # everything by defining these error numbers differently.
3351
3352         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3353         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3354
3355         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3356         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3357
3358         return 0
3359 }
3360 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3361
3362 test_27R() {
3363         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3364                 skip "need MDS 2.14.55 or later"
3365         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3366
3367         local testdir="$DIR/$tdir"
3368         test_mkdir -p $testdir
3369         stack_trap "rm -rf $testdir"
3370         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3371
3372         local f1="$testdir/f1"
3373         touch $f1 || error "failed to touch $f1"
3374         local count=$($LFS getstripe -c $f1)
3375         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3376
3377         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3378         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3379
3380         local maxcount=$(($OSTCOUNT - 1))
3381         local mdts=$(comma_list $(mdts_nodes))
3382         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3383         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3384
3385         local f2="$testdir/f2"
3386         touch $f2 || error "failed to touch $f2"
3387         local count=$($LFS getstripe -c $f2)
3388         (( $count == $maxcount )) || error "wrong stripe count"
3389 }
3390 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3391
3392 test_27S() {
3393         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
3394                 skip "Need MDS version at least 2.14.54"
3395         [[ "$(facet_host mds1)" != "$(facet_host ost1)" ]] ||
3396                 skip "needs different host for mdt1 ost1"
3397
3398         local count=$(precreated_ost_obj_count 0 0)
3399
3400         echo "precreate count $count"
3401         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
3402         $LFS setstripe -i 0 -c 1 $DIR/$tdir || error "setstripe $tdir failed"
3403         #define OBD_FAIL_OSP_GET_LAST_FID       0x2109
3404         do_facet mds1 $LCTL set_param fail_loc=0x2109
3405         #define OBD_FAIL_OST_GET_LAST_FID       0x252
3406         do_facet ost1 $LCTL set_param fail_loc=0x252
3407         createmany -o $DIR/$tdir/f $count &
3408         pid=$!
3409         echo "precreate count $(precreated_ost_obj_count 0 0)"
3410         do_facet mds1 $LCTL set_param fail_loc=0
3411         do_facet ost1 $LCTL set_param fail_loc=0
3412         wait $pid || error "createmany failed"
3413         echo "precreate count $(precreated_ost_obj_count 0 0)"
3414 }
3415 run_test 27S "don't deactivate OSP on network issue"
3416
3417 test_27T() {
3418         [ $(facet_host client) == $(facet_host ost1) ] &&
3419                 skip "need ost1 and client on different nodes"
3420
3421 #define OBD_FAIL_OSC_NO_GRANT            0x411
3422         $LCTL set_param fail_loc=0x20000411 fail_val=1
3423 #define OBD_FAIL_OST_ENOSPC              0x215
3424         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3425         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3426         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3427                 error "multiop failed"
3428 }
3429 run_test 27T "no eio on close on partial write due to enosp"
3430
3431 # createtest also checks that device nodes are created and
3432 # then visible correctly (#2091)
3433 test_28() { # bug 2091
3434         test_mkdir $DIR/d28
3435         $CREATETEST $DIR/d28/ct || error "createtest failed"
3436 }
3437 run_test 28 "create/mknod/mkdir with bad file types ============"
3438
3439 test_29() {
3440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3441
3442         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3443                 disable_opencache
3444                 stack_trap "restore_opencache"
3445         }
3446
3447         sync; sleep 1; sync # flush out any dirty pages from previous tests
3448         cancel_lru_locks
3449         test_mkdir $DIR/d29
3450         touch $DIR/d29/foo
3451         log 'first d29'
3452         ls -l $DIR/d29
3453
3454         declare -i LOCKCOUNTORIG=0
3455         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3456                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3457         done
3458         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3459
3460         declare -i LOCKUNUSEDCOUNTORIG=0
3461         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3462                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3463         done
3464
3465         log 'second d29'
3466         ls -l $DIR/d29
3467         log 'done'
3468
3469         declare -i LOCKCOUNTCURRENT=0
3470         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3471                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3472         done
3473
3474         declare -i LOCKUNUSEDCOUNTCURRENT=0
3475         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3476                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3477         done
3478
3479         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3480                 $LCTL set_param -n ldlm.dump_namespaces ""
3481                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3482                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3483                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3484                 return 2
3485         fi
3486         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3487                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3488                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3489                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3490                 return 3
3491         fi
3492 }
3493 run_test 29 "IT_GETATTR regression  ============================"
3494
3495 test_30a() { # was test_30
3496         cp $(which ls) $DIR || cp /bin/ls $DIR
3497         $DIR/ls / || error "Can't execute binary from lustre"
3498         rm $DIR/ls
3499 }
3500 run_test 30a "execute binary from Lustre (execve) =============="
3501
3502 test_30b() {
3503         cp `which ls` $DIR || cp /bin/ls $DIR
3504         chmod go+rx $DIR/ls
3505         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3506         rm $DIR/ls
3507 }
3508 run_test 30b "execute binary from Lustre as non-root ==========="
3509
3510 test_30c() { # b=22376
3511         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3512
3513         cp $(which ls) $DIR || cp /bin/ls $DIR
3514         chmod a-rw $DIR/ls
3515         cancel_lru_locks mdc
3516         cancel_lru_locks osc
3517         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3518         rm -f $DIR/ls
3519 }
3520 run_test 30c "execute binary from Lustre without read perms ===="
3521
3522 test_30d() {
3523         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3524
3525         for i in {1..10}; do
3526                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3527                 local PID=$!
3528                 sleep 1
3529                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3530                 wait $PID || error "executing dd from Lustre failed"
3531                 rm -f $DIR/$tfile
3532         done
3533
3534         rm -f $DIR/dd
3535 }
3536 run_test 30d "execute binary from Lustre while clear locks"
3537
3538 test_31a() {
3539         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3540         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3541 }
3542 run_test 31a "open-unlink file =================================="
3543
3544 test_31b() {
3545         touch $DIR/f31 || error "touch $DIR/f31 failed"
3546         ln $DIR/f31 $DIR/f31b || error "ln failed"
3547         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3548         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3549 }
3550 run_test 31b "unlink file with multiple links while open ======="
3551
3552 test_31c() {
3553         touch $DIR/f31 || error "touch $DIR/f31 failed"
3554         ln $DIR/f31 $DIR/f31c || error "ln failed"
3555         multiop_bg_pause $DIR/f31 O_uc ||
3556                 error "multiop_bg_pause for $DIR/f31 failed"
3557         MULTIPID=$!
3558         $MULTIOP $DIR/f31c Ouc
3559         kill -USR1 $MULTIPID
3560         wait $MULTIPID
3561 }
3562 run_test 31c "open-unlink file with multiple links ============="
3563
3564 test_31d() {
3565         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3566         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3567 }
3568 run_test 31d "remove of open directory ========================="
3569
3570 test_31e() { # bug 2904
3571         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3572 }
3573 run_test 31e "remove of open non-empty directory ==============="
3574
3575 test_31f() { # bug 4554
3576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3577
3578         set -vx
3579         test_mkdir $DIR/d31f
3580         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3581         cp /etc/hosts $DIR/d31f
3582         ls -l $DIR/d31f
3583         $LFS getstripe $DIR/d31f/hosts
3584         multiop_bg_pause $DIR/d31f D_c || return 1
3585         MULTIPID=$!
3586
3587         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3588         test_mkdir $DIR/d31f
3589         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3590         cp /etc/hosts $DIR/d31f
3591         ls -l $DIR/d31f
3592         $LFS getstripe $DIR/d31f/hosts
3593         multiop_bg_pause $DIR/d31f D_c || return 1
3594         MULTIPID2=$!
3595
3596         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3597         wait $MULTIPID || error "first opendir $MULTIPID failed"
3598
3599         sleep 6
3600
3601         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3602         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3603         set +vx
3604 }
3605 run_test 31f "remove of open directory with open-unlink file ==="
3606
3607 test_31g() {
3608         echo "-- cross directory link --"
3609         test_mkdir -c1 $DIR/${tdir}ga
3610         test_mkdir -c1 $DIR/${tdir}gb
3611         touch $DIR/${tdir}ga/f
3612         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3613         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3614         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3615         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3616         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3617 }
3618 run_test 31g "cross directory link==============="
3619
3620 test_31h() {
3621         echo "-- cross directory link --"
3622         test_mkdir -c1 $DIR/${tdir}
3623         test_mkdir -c1 $DIR/${tdir}/dir
3624         touch $DIR/${tdir}/f
3625         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3626         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3627         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3628         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3629         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3630 }
3631 run_test 31h "cross directory link under child==============="
3632
3633 test_31i() {
3634         echo "-- cross directory link --"
3635         test_mkdir -c1 $DIR/$tdir
3636         test_mkdir -c1 $DIR/$tdir/dir
3637         touch $DIR/$tdir/dir/f
3638         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3639         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3640         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3641         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3642         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3643 }
3644 run_test 31i "cross directory link under parent==============="
3645
3646 test_31j() {
3647         test_mkdir -c1 -p $DIR/$tdir
3648         test_mkdir -c1 -p $DIR/$tdir/dir1
3649         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3650         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3651         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3652         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3653         return 0
3654 }
3655 run_test 31j "link for directory==============="
3656
3657 test_31k() {
3658         test_mkdir -c1 -p $DIR/$tdir
3659         touch $DIR/$tdir/s
3660         touch $DIR/$tdir/exist
3661         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3662         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3663         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3664         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3665         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3666         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3667         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3668         return 0
3669 }
3670 run_test 31k "link to file: the same, non-existing, dir==============="
3671
3672 test_31m() {
3673         mkdir $DIR/d31m
3674         touch $DIR/d31m/s
3675         mkdir $DIR/d31m2
3676         touch $DIR/d31m2/exist
3677         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3678         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3679         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3680         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3681         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3682         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3683         return 0
3684 }
3685 run_test 31m "link to file: the same, non-existing, dir==============="
3686
3687 test_31n() {
3688         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3689         nlink=$(stat --format=%h $DIR/$tfile)
3690         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3691         local fd=$(free_fd)
3692         local cmd="exec $fd<$DIR/$tfile"
3693         eval $cmd
3694         cmd="exec $fd<&-"
3695         trap "eval $cmd" EXIT
3696         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3697         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3698         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3699         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3700         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3701         eval $cmd
3702 }
3703 run_test 31n "check link count of unlinked file"
3704
3705 link_one() {
3706         local tempfile=$(mktemp $1_XXXXXX)
3707         mlink $tempfile $1 2> /dev/null &&
3708                 echo "$BASHPID: link $tempfile to $1 succeeded"
3709         munlink $tempfile
3710 }
3711
3712 test_31o() { # LU-2901
3713         test_mkdir $DIR/$tdir
3714         for LOOP in $(seq 100); do
3715                 rm -f $DIR/$tdir/$tfile*
3716                 for THREAD in $(seq 8); do
3717                         link_one $DIR/$tdir/$tfile.$LOOP &
3718                 done
3719                 wait
3720                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3721                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3722                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3723                         break || true
3724         done
3725 }
3726 run_test 31o "duplicate hard links with same filename"
3727
3728 test_31p() {
3729         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3730
3731         test_mkdir $DIR/$tdir
3732         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3733         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3734
3735         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3736                 error "open unlink test1 failed"
3737         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3738                 error "open unlink test2 failed"
3739
3740         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3741                 error "test1 still exists"
3742         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3743                 error "test2 still exists"
3744 }
3745 run_test 31p "remove of open striped directory"
3746
3747 test_31q() {
3748         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3749
3750         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3751         index=$($LFS getdirstripe -i $DIR/$tdir)
3752         [ $index -eq 3 ] || error "first stripe index $index != 3"
3753         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3754         [ $index -eq 1 ] || error "second stripe index $index != 1"
3755
3756         # when "-c <stripe_count>" is set, the number of MDTs specified after
3757         # "-i" should equal to the stripe count
3758         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3759 }
3760 run_test 31q "create striped directory on specific MDTs"
3761
3762 #LU-14949
3763 test_31r() {
3764         touch $DIR/$tfile.target
3765         touch $DIR/$tfile.source
3766
3767         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3768         $LCTL set_param fail_loc=0x1419 fail_val=3
3769         cat $DIR/$tfile.target &
3770         CATPID=$!
3771
3772         # Guarantee open is waiting before we get here
3773         sleep 1
3774         mv $DIR/$tfile.source $DIR/$tfile.target
3775
3776         wait $CATPID
3777         RC=$?
3778         if [[ $RC -ne 0 ]]; then
3779                 error "open with cat failed, rc=$RC"
3780         fi
3781 }
3782 run_test 31r "open-rename(replace) race"
3783
3784 cleanup_test32_mount() {
3785         local rc=0
3786         trap 0
3787         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3788         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3789         losetup -d $loopdev || true
3790         rm -rf $DIR/$tdir
3791         return $rc
3792 }
3793
3794 test_32a() {
3795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3796
3797         echo "== more mountpoints and symlinks ================="
3798         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3799         trap cleanup_test32_mount EXIT
3800         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3801         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3802                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3803         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3804                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3805         cleanup_test32_mount
3806 }
3807 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3808
3809 test_32b() {
3810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3811
3812         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3813         trap cleanup_test32_mount EXIT
3814         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3815         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3816                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3817         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3818                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3819         cleanup_test32_mount
3820 }
3821 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3822
3823 test_32c() {
3824         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3825
3826         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3827         trap cleanup_test32_mount EXIT
3828         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3829         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3830                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3831         test_mkdir -p $DIR/$tdir/d2/test_dir
3832         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3833                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3834         cleanup_test32_mount
3835 }
3836 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3837
3838 test_32d() {
3839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3840
3841         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3842         trap cleanup_test32_mount EXIT
3843         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3844         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3845                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3846         test_mkdir -p $DIR/$tdir/d2/test_dir
3847         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3848                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3849         cleanup_test32_mount
3850 }
3851 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3852
3853 test_32e() {
3854         rm -fr $DIR/$tdir
3855         test_mkdir -p $DIR/$tdir/tmp
3856         local tmp_dir=$DIR/$tdir/tmp
3857         ln -s $DIR/$tdir $tmp_dir/symlink11
3858         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3859         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3860         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3861 }
3862 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3863
3864 test_32f() {
3865         rm -fr $DIR/$tdir
3866         test_mkdir -p $DIR/$tdir/tmp
3867         local tmp_dir=$DIR/$tdir/tmp
3868         ln -s $DIR/$tdir $tmp_dir/symlink11
3869         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3870         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3871         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3872 }
3873 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3874
3875 test_32g() {
3876         local tmp_dir=$DIR/$tdir/tmp
3877         test_mkdir -p $tmp_dir
3878         test_mkdir $DIR/${tdir}2
3879         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3880         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3881         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3882         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3883         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3884         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3885 }
3886 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3887
3888 test_32h() {
3889         rm -fr $DIR/$tdir $DIR/${tdir}2
3890         tmp_dir=$DIR/$tdir/tmp
3891         test_mkdir -p $tmp_dir
3892         test_mkdir $DIR/${tdir}2
3893         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3894         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3895         ls $tmp_dir/symlink12 || error "listing symlink12"
3896         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3897 }
3898 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3899
3900 test_32i() {
3901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3902
3903         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3904         trap cleanup_test32_mount EXIT
3905         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3906         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3907                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3908         touch $DIR/$tdir/test_file
3909         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3910                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3911         cleanup_test32_mount
3912 }
3913 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3914
3915 test_32j() {
3916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3917
3918         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3919         trap cleanup_test32_mount EXIT
3920         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3921         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3922                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3923         touch $DIR/$tdir/test_file
3924         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3925                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3926         cleanup_test32_mount
3927 }
3928 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3929
3930 test_32k() {
3931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3932
3933         rm -fr $DIR/$tdir
3934         trap cleanup_test32_mount EXIT
3935         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3936         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3937                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3938         test_mkdir -p $DIR/$tdir/d2
3939         touch $DIR/$tdir/d2/test_file || error "touch failed"
3940         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3941                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3942         cleanup_test32_mount
3943 }
3944 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3945
3946 test_32l() {
3947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3948
3949         rm -fr $DIR/$tdir
3950         trap cleanup_test32_mount EXIT
3951         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3952         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3953                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3954         test_mkdir -p $DIR/$tdir/d2
3955         touch $DIR/$tdir/d2/test_file || error "touch failed"
3956         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3957                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3958         cleanup_test32_mount
3959 }
3960 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3961
3962 test_32m() {
3963         rm -fr $DIR/d32m
3964         test_mkdir -p $DIR/d32m/tmp
3965         TMP_DIR=$DIR/d32m/tmp
3966         ln -s $DIR $TMP_DIR/symlink11
3967         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3968         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3969                 error "symlink11 not a link"
3970         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3971                 error "symlink01 not a link"
3972 }
3973 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3974
3975 test_32n() {
3976         rm -fr $DIR/d32n
3977         test_mkdir -p $DIR/d32n/tmp
3978         TMP_DIR=$DIR/d32n/tmp
3979         ln -s $DIR $TMP_DIR/symlink11
3980         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3981         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3982         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3983 }
3984 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3985
3986 test_32o() {
3987         touch $DIR/$tfile
3988         test_mkdir -p $DIR/d32o/tmp
3989         TMP_DIR=$DIR/d32o/tmp
3990         ln -s $DIR/$tfile $TMP_DIR/symlink12
3991         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3992         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3993                 error "symlink12 not a link"
3994         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3995         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3996                 error "$DIR/d32o/tmp/symlink12 not file type"
3997         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3998                 error "$DIR/d32o/symlink02 not file type"
3999 }
4000 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4001
4002 test_32p() {
4003         log 32p_1
4004         rm -fr $DIR/d32p
4005         log 32p_2
4006         rm -f $DIR/$tfile
4007         log 32p_3
4008         touch $DIR/$tfile
4009         log 32p_4
4010         test_mkdir -p $DIR/d32p/tmp
4011         log 32p_5
4012         TMP_DIR=$DIR/d32p/tmp
4013         log 32p_6
4014         ln -s $DIR/$tfile $TMP_DIR/symlink12
4015         log 32p_7
4016         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4017         log 32p_8
4018         cat $DIR/d32p/tmp/symlink12 ||
4019                 error "Can't open $DIR/d32p/tmp/symlink12"
4020         log 32p_9
4021         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4022         log 32p_10
4023 }
4024 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4025
4026 test_32q() {
4027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4028
4029         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4030         trap cleanup_test32_mount EXIT
4031         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4032         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4033         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4034                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4035         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4036         cleanup_test32_mount
4037 }
4038 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4039
4040 test_32r() {
4041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4042
4043         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4044         trap cleanup_test32_mount EXIT
4045         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4046         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4047         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4048                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4049         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4050         cleanup_test32_mount
4051 }
4052 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4053
4054 test_33aa() {
4055         rm -f $DIR/$tfile
4056         touch $DIR/$tfile
4057         chmod 444 $DIR/$tfile
4058         chown $RUNAS_ID $DIR/$tfile
4059         log 33_1
4060         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4061         log 33_2
4062 }
4063 run_test 33aa "write file with mode 444 (should return error)"
4064
4065 test_33a() {
4066         rm -fr $DIR/$tdir
4067         test_mkdir $DIR/$tdir
4068         chown $RUNAS_ID $DIR/$tdir
4069         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4070                 error "$RUNAS create $tdir/$tfile failed"
4071         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4072                 error "open RDWR" || true
4073 }
4074 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4075
4076 test_33b() {
4077         rm -fr $DIR/$tdir
4078         test_mkdir $DIR/$tdir
4079         chown $RUNAS_ID $DIR/$tdir
4080         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4081 }
4082 run_test 33b "test open file with malformed flags (No panic)"
4083
4084 test_33c() {
4085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4086         remote_ost_nodsh && skip "remote OST with nodsh"
4087
4088         local ostnum
4089         local ostname
4090         local write_bytes
4091         local all_zeros
4092
4093         all_zeros=true
4094         test_mkdir $DIR/$tdir
4095         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4096
4097         sync
4098         for ostnum in $(seq $OSTCOUNT); do
4099                 # test-framework's OST numbering is one-based, while Lustre's
4100                 # is zero-based
4101                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4102                 # check if at least some write_bytes stats are counted
4103                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4104                               obdfilter.$ostname.stats |
4105                               awk '/^write_bytes/ {print $7}' )
4106                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4107                 if (( ${write_bytes:-0} > 0 )); then
4108                         all_zeros=false
4109                         break
4110                 fi
4111         done
4112
4113         $all_zeros || return 0
4114
4115         # Write four bytes
4116         echo foo > $DIR/$tdir/bar
4117         # Really write them
4118         sync
4119
4120         # Total up write_bytes after writing.  We'd better find non-zeros.
4121         for ostnum in $(seq $OSTCOUNT); do
4122                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4123                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4124                               obdfilter/$ostname/stats |
4125                               awk '/^write_bytes/ {print $7}' )
4126                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4127                 if (( ${write_bytes:-0} > 0 )); then
4128                         all_zeros=false
4129                         break
4130                 fi
4131         done
4132
4133         if $all_zeros; then
4134                 for ostnum in $(seq $OSTCOUNT); do
4135                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4136                         echo "Check write_bytes is in obdfilter.*.stats:"
4137                         do_facet ost$ostnum lctl get_param -n \
4138                                 obdfilter.$ostname.stats
4139                 done
4140                 error "OST not keeping write_bytes stats (b=22312)"
4141         fi
4142 }
4143 run_test 33c "test write_bytes stats"
4144
4145 test_33d() {
4146         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4148
4149         local MDTIDX=1
4150         local remote_dir=$DIR/$tdir/remote_dir
4151
4152         test_mkdir $DIR/$tdir
4153         $LFS mkdir -i $MDTIDX $remote_dir ||
4154                 error "create remote directory failed"
4155
4156         touch $remote_dir/$tfile
4157         chmod 444 $remote_dir/$tfile
4158         chown $RUNAS_ID $remote_dir/$tfile
4159
4160         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4161
4162         chown $RUNAS_ID $remote_dir
4163         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4164                                         error "create" || true
4165         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4166                                     error "open RDWR" || true
4167         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4168 }
4169 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4170
4171 test_33e() {
4172         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4173
4174         mkdir $DIR/$tdir
4175
4176         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4177         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4178         mkdir $DIR/$tdir/local_dir
4179
4180         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4181         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4182         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4183
4184         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4185                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4186
4187         rmdir $DIR/$tdir/* || error "rmdir failed"
4188
4189         umask 777
4190         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4191         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4192         mkdir $DIR/$tdir/local_dir
4193
4194         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4195         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4196         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4197
4198         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4199                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4200
4201         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4202
4203         umask 000
4204         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4205         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4206         mkdir $DIR/$tdir/local_dir
4207
4208         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4209         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4210         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4211
4212         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4213                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4214 }
4215 run_test 33e "mkdir and striped directory should have same mode"
4216
4217 cleanup_33f() {
4218         trap 0
4219         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4220 }
4221
4222 test_33f() {
4223         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4224         remote_mds_nodsh && skip "remote MDS with nodsh"
4225
4226         mkdir $DIR/$tdir
4227         chmod go+rwx $DIR/$tdir
4228         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4229         trap cleanup_33f EXIT
4230
4231         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4232                 error "cannot create striped directory"
4233
4234         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4235                 error "cannot create files in striped directory"
4236
4237         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4238                 error "cannot remove files in striped directory"
4239
4240         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4241                 error "cannot remove striped directory"
4242
4243         cleanup_33f
4244 }
4245 run_test 33f "nonroot user can create, access, and remove a striped directory"
4246
4247 test_33g() {
4248         mkdir -p $DIR/$tdir/dir2
4249
4250         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4251         echo $err
4252         [[ $err =~ "exists" ]] || error "Not exists error"
4253 }
4254 run_test 33g "nonroot user create already existing root created file"
4255
4256 test_33h() {
4257         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4258         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4259                 skip "Need MDS version at least 2.13.50"
4260
4261         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4262                 error "mkdir $tdir failed"
4263         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4264
4265         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4266         local index2
4267
4268         for fname in $DIR/$tdir/$tfile.bak \
4269                      $DIR/$tdir/$tfile.SAV \
4270                      $DIR/$tdir/$tfile.orig \
4271                      $DIR/$tdir/$tfile~; do
4272                 touch $fname  || error "touch $fname failed"
4273                 index2=$($LFS getstripe -m $fname)
4274                 [ $index -eq $index2 ] ||
4275                         error "$fname MDT index mismatch $index != $index2"
4276         done
4277
4278         local failed=0
4279         for i in {1..250}; do
4280                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4281                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4282                         touch $fname  || error "touch $fname failed"
4283                         index2=$($LFS getstripe -m $fname)
4284                         if [[ $index != $index2 ]]; then
4285                                 failed=$((failed + 1))
4286                                 echo "$fname MDT index mismatch $index != $index2"
4287                         fi
4288                 done
4289         done
4290         echo "$failed MDT index mismatches"
4291         (( failed < 20 )) || error "MDT index mismatch $failed times"
4292
4293 }
4294 run_test 33h "temp file is located on the same MDT as target"
4295
4296 test_33i()
4297 {
4298         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4299
4300         local FNAME=$(str_repeat 'f' 250)
4301
4302         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4303         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4304
4305         local count
4306         local total
4307
4308         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4309
4310         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4311
4312         lctl --device %$MDC deactivate
4313         stack_trap "lctl --device %$MDC activate"
4314         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4315         total=$(\ls -l $DIR/$tdir | wc -l)
4316         # "ls -l" will list total in the first line
4317         total=$((total - 1))
4318         (( total + count == 1000 )) ||
4319                 error "ls list $total files, $count files on MDT1"
4320 }
4321 run_test 33i "striped directory can be accessed when one MDT is down"
4322
4323 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4324 test_34a() {
4325         rm -f $DIR/f34
4326         $MCREATE $DIR/f34 || error "mcreate failed"
4327         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4328                 error "getstripe failed"
4329         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4330         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4331                 error "getstripe failed"
4332         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4333                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4334 }
4335 run_test 34a "truncate file that has not been opened ==========="
4336
4337 test_34b() {
4338         [ ! -f $DIR/f34 ] && test_34a
4339         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4340                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4341         $OPENFILE -f O_RDONLY $DIR/f34
4342         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4343                 error "getstripe failed"
4344         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4345                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4346 }
4347 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4348
4349 test_34c() {
4350         [ ! -f $DIR/f34 ] && test_34a
4351         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4352                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4353         $OPENFILE -f O_RDWR $DIR/f34
4354         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4355                 error "$LFS getstripe failed"
4356         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4357                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4358 }
4359 run_test 34c "O_RDWR opening file-with-size works =============="
4360
4361 test_34d() {
4362         [ ! -f $DIR/f34 ] && test_34a
4363         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4364                 error "dd failed"
4365         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4366                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4367         rm $DIR/f34
4368 }
4369 run_test 34d "write to sparse file ============================="
4370
4371 test_34e() {
4372         rm -f $DIR/f34e
4373         $MCREATE $DIR/f34e || error "mcreate failed"
4374         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4375         $CHECKSTAT -s 1000 $DIR/f34e ||
4376                 error "Size of $DIR/f34e not equal to 1000 bytes"
4377         $OPENFILE -f O_RDWR $DIR/f34e
4378         $CHECKSTAT -s 1000 $DIR/f34e ||
4379                 error "Size of $DIR/f34e not equal to 1000 bytes"
4380 }
4381 run_test 34e "create objects, some with size and some without =="
4382
4383 test_34f() { # bug 6242, 6243
4384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4385
4386         SIZE34F=48000
4387         rm -f $DIR/f34f
4388         $MCREATE $DIR/f34f || error "mcreate failed"
4389         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4390         dd if=$DIR/f34f of=$TMP/f34f
4391         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4392         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4393         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4394         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4395         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4396 }
4397 run_test 34f "read from a file with no objects until EOF ======="
4398
4399 test_34g() {
4400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4401
4402         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4403                 error "dd failed"
4404         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4405         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4406                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4407         cancel_lru_locks osc
4408         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4409                 error "wrong size after lock cancel"
4410
4411         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4412         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4413                 error "expanding truncate failed"
4414         cancel_lru_locks osc
4415         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4416                 error "wrong expanded size after lock cancel"
4417 }
4418 run_test 34g "truncate long file ==============================="
4419
4420 test_34h() {
4421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4422
4423         local gid=10
4424         local sz=1000
4425
4426         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4427         sync # Flush the cache so that multiop below does not block on cache
4428              # flush when getting the group lock
4429         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4430         MULTIPID=$!
4431
4432         # Since just timed wait is not good enough, let's do a sync write
4433         # that way we are sure enough time for a roundtrip + processing
4434         # passed + 2 seconds of extra margin.
4435         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4436         rm $DIR/${tfile}-1
4437         sleep 2
4438
4439         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4440                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4441                 kill -9 $MULTIPID
4442         fi
4443         wait $MULTIPID
4444         local nsz=`stat -c %s $DIR/$tfile`
4445         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4446 }
4447 run_test 34h "ftruncate file under grouplock should not block"
4448
4449 test_35a() {
4450         cp /bin/sh $DIR/f35a
4451         chmod 444 $DIR/f35a
4452         chown $RUNAS_ID $DIR/f35a
4453         $RUNAS $DIR/f35a && error || true
4454         rm $DIR/f35a
4455 }
4456 run_test 35a "exec file with mode 444 (should return and not leak)"
4457
4458 test_36a() {
4459         rm -f $DIR/f36
4460         utime $DIR/f36 || error "utime failed for MDS"
4461 }
4462 run_test 36a "MDS utime check (mknod, utime)"
4463
4464 test_36b() {
4465         echo "" > $DIR/f36
4466         utime $DIR/f36 || error "utime failed for OST"
4467 }
4468 run_test 36b "OST utime check (open, utime)"
4469
4470 test_36c() {
4471         rm -f $DIR/d36/f36
4472         test_mkdir $DIR/d36
4473         chown $RUNAS_ID $DIR/d36
4474         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4475 }
4476 run_test 36c "non-root MDS utime check (mknod, utime)"
4477
4478 test_36d() {
4479         [ ! -d $DIR/d36 ] && test_36c
4480         echo "" > $DIR/d36/f36
4481         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4482 }
4483 run_test 36d "non-root OST utime check (open, utime)"
4484
4485 test_36e() {
4486         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4487
4488         test_mkdir $DIR/$tdir
4489         touch $DIR/$tdir/$tfile
4490         $RUNAS utime $DIR/$tdir/$tfile &&
4491                 error "utime worked, expected failure" || true
4492 }
4493 run_test 36e "utime on non-owned file (should return error)"
4494
4495 subr_36fh() {
4496         local fl="$1"
4497         local LANG_SAVE=$LANG
4498         local LC_LANG_SAVE=$LC_LANG
4499         export LANG=C LC_LANG=C # for date language
4500
4501         DATESTR="Dec 20  2000"
4502         test_mkdir $DIR/$tdir
4503         lctl set_param fail_loc=$fl
4504         date; date +%s
4505         cp /etc/hosts $DIR/$tdir/$tfile
4506         sync & # write RPC generated with "current" inode timestamp, but delayed
4507         sleep 1
4508         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4509         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4510         cancel_lru_locks $OSC
4511         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4512         date; date +%s
4513         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4514                 echo "BEFORE: $LS_BEFORE" && \
4515                 echo "AFTER : $LS_AFTER" && \
4516                 echo "WANT  : $DATESTR" && \
4517                 error "$DIR/$tdir/$tfile timestamps changed" || true
4518
4519         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4520 }
4521
4522 test_36f() {
4523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4524
4525         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4526         subr_36fh "0x80000214"
4527 }
4528 run_test 36f "utime on file racing with OST BRW write =========="
4529
4530 test_36g() {
4531         remote_ost_nodsh && skip "remote OST with nodsh"
4532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4533         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4534                 skip "Need MDS version at least 2.12.51"
4535
4536         local fmd_max_age
4537         local fmd
4538         local facet="ost1"
4539         local tgt="obdfilter"
4540
4541         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4542
4543         test_mkdir $DIR/$tdir
4544         fmd_max_age=$(do_facet $facet \
4545                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4546                 head -n 1")
4547
4548         echo "FMD max age: ${fmd_max_age}s"
4549         touch $DIR/$tdir/$tfile
4550         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4551                 gawk '{cnt=cnt+$1}  END{print cnt}')
4552         echo "FMD before: $fmd"
4553         [[ $fmd == 0 ]] &&
4554                 error "FMD wasn't create by touch"
4555         sleep $((fmd_max_age + 12))
4556         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4557                 gawk '{cnt=cnt+$1}  END{print cnt}')
4558         echo "FMD after: $fmd"
4559         [[ $fmd == 0 ]] ||
4560                 error "FMD wasn't expired by ping"
4561 }
4562 run_test 36g "FMD cache expiry ====================="
4563
4564 test_36h() {
4565         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4566
4567         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4568         subr_36fh "0x80000227"
4569 }
4570 run_test 36h "utime on file racing with OST BRW write =========="
4571
4572 test_36i() {
4573         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4574
4575         test_mkdir $DIR/$tdir
4576         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4577
4578         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4579         local new_mtime=$((mtime + 200))
4580
4581         #change Modify time of striped dir
4582         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4583                         error "change mtime failed"
4584
4585         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4586
4587         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4588 }
4589 run_test 36i "change mtime on striped directory"
4590
4591 # test_37 - duplicate with tests 32q 32r
4592
4593 test_38() {
4594         local file=$DIR/$tfile
4595         touch $file
4596         openfile -f O_DIRECTORY $file
4597         local RC=$?
4598         local ENOTDIR=20
4599         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4600         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4601 }
4602 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4603
4604 test_39a() { # was test_39
4605         touch $DIR/$tfile
4606         touch $DIR/${tfile}2
4607 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4608 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4609 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4610         sleep 2
4611         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4612         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4613                 echo "mtime"
4614                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4615                 echo "atime"
4616                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4617                 echo "ctime"
4618                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4619                 error "O_TRUNC didn't change timestamps"
4620         fi
4621 }
4622 run_test 39a "mtime changed on create"
4623
4624 test_39b() {
4625         test_mkdir -c1 $DIR/$tdir
4626         cp -p /etc/passwd $DIR/$tdir/fopen
4627         cp -p /etc/passwd $DIR/$tdir/flink
4628         cp -p /etc/passwd $DIR/$tdir/funlink
4629         cp -p /etc/passwd $DIR/$tdir/frename
4630         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4631
4632         sleep 1
4633         echo "aaaaaa" >> $DIR/$tdir/fopen
4634         echo "aaaaaa" >> $DIR/$tdir/flink
4635         echo "aaaaaa" >> $DIR/$tdir/funlink
4636         echo "aaaaaa" >> $DIR/$tdir/frename
4637
4638         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4639         local link_new=`stat -c %Y $DIR/$tdir/flink`
4640         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4641         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4642
4643         cat $DIR/$tdir/fopen > /dev/null
4644         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4645         rm -f $DIR/$tdir/funlink2
4646         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4647
4648         for (( i=0; i < 2; i++ )) ; do
4649                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4650                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4651                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4652                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4653
4654                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4655                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4656                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4657                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4658
4659                 cancel_lru_locks $OSC
4660                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4661         done
4662 }
4663 run_test 39b "mtime change on open, link, unlink, rename  ======"
4664
4665 # this should be set to past
4666 TEST_39_MTIME=`date -d "1 year ago" +%s`
4667
4668 # bug 11063
4669 test_39c() {
4670         touch $DIR1/$tfile
4671         sleep 2
4672         local mtime0=`stat -c %Y $DIR1/$tfile`
4673
4674         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4675         local mtime1=`stat -c %Y $DIR1/$tfile`
4676         [ "$mtime1" = $TEST_39_MTIME ] || \
4677                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4678
4679         local d1=`date +%s`
4680         echo hello >> $DIR1/$tfile
4681         local d2=`date +%s`
4682         local mtime2=`stat -c %Y $DIR1/$tfile`
4683         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4684                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4685
4686         mv $DIR1/$tfile $DIR1/$tfile-1
4687
4688         for (( i=0; i < 2; i++ )) ; do
4689                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4690                 [ "$mtime2" = "$mtime3" ] || \
4691                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4692
4693                 cancel_lru_locks $OSC
4694                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4695         done
4696 }
4697 run_test 39c "mtime change on rename ==========================="
4698
4699 # bug 21114
4700 test_39d() {
4701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4702
4703         touch $DIR1/$tfile
4704         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4705
4706         for (( i=0; i < 2; i++ )) ; do
4707                 local mtime=`stat -c %Y $DIR1/$tfile`
4708                 [ $mtime = $TEST_39_MTIME ] || \
4709                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4710
4711                 cancel_lru_locks $OSC
4712                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4713         done
4714 }
4715 run_test 39d "create, utime, stat =============================="
4716
4717 # bug 21114
4718 test_39e() {
4719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4720
4721         touch $DIR1/$tfile
4722         local mtime1=`stat -c %Y $DIR1/$tfile`
4723
4724         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4725
4726         for (( i=0; i < 2; i++ )) ; do
4727                 local mtime2=`stat -c %Y $DIR1/$tfile`
4728                 [ $mtime2 = $TEST_39_MTIME ] || \
4729                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4730
4731                 cancel_lru_locks $OSC
4732                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4733         done
4734 }
4735 run_test 39e "create, stat, utime, stat ========================"
4736
4737 # bug 21114
4738 test_39f() {
4739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4740
4741         touch $DIR1/$tfile
4742         mtime1=`stat -c %Y $DIR1/$tfile`
4743
4744         sleep 2
4745         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4746
4747         for (( i=0; i < 2; i++ )) ; do
4748                 local mtime2=`stat -c %Y $DIR1/$tfile`
4749                 [ $mtime2 = $TEST_39_MTIME ] || \
4750                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4751
4752                 cancel_lru_locks $OSC
4753                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4754         done
4755 }
4756 run_test 39f "create, stat, sleep, utime, stat ================="
4757
4758 # bug 11063
4759 test_39g() {
4760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4761
4762         echo hello >> $DIR1/$tfile
4763         local mtime1=`stat -c %Y $DIR1/$tfile`
4764
4765         sleep 2
4766         chmod o+r $DIR1/$tfile
4767
4768         for (( i=0; i < 2; i++ )) ; do
4769                 local mtime2=`stat -c %Y $DIR1/$tfile`
4770                 [ "$mtime1" = "$mtime2" ] || \
4771                         error "lost mtime: $mtime2, should be $mtime1"
4772
4773                 cancel_lru_locks $OSC
4774                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4775         done
4776 }
4777 run_test 39g "write, chmod, stat ==============================="
4778
4779 # bug 11063
4780 test_39h() {
4781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4782
4783         touch $DIR1/$tfile
4784         sleep 1
4785
4786         local d1=`date`
4787         echo hello >> $DIR1/$tfile
4788         local mtime1=`stat -c %Y $DIR1/$tfile`
4789
4790         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4791         local d2=`date`
4792         if [ "$d1" != "$d2" ]; then
4793                 echo "write and touch not within one second"
4794         else
4795                 for (( i=0; i < 2; i++ )) ; do
4796                         local mtime2=`stat -c %Y $DIR1/$tfile`
4797                         [ "$mtime2" = $TEST_39_MTIME ] || \
4798                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4799
4800                         cancel_lru_locks $OSC
4801                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4802                 done
4803         fi
4804 }
4805 run_test 39h "write, utime within one second, stat ============="
4806
4807 test_39i() {
4808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4809
4810         touch $DIR1/$tfile
4811         sleep 1
4812
4813         echo hello >> $DIR1/$tfile
4814         local mtime1=`stat -c %Y $DIR1/$tfile`
4815
4816         mv $DIR1/$tfile $DIR1/$tfile-1
4817
4818         for (( i=0; i < 2; i++ )) ; do
4819                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4820
4821                 [ "$mtime1" = "$mtime2" ] || \
4822                         error "lost mtime: $mtime2, should be $mtime1"
4823
4824                 cancel_lru_locks $OSC
4825                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4826         done
4827 }
4828 run_test 39i "write, rename, stat =============================="
4829
4830 test_39j() {
4831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4832
4833         start_full_debug_logging
4834         touch $DIR1/$tfile
4835         sleep 1
4836
4837         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4838         lctl set_param fail_loc=0x80000412
4839         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4840                 error "multiop failed"
4841         local multipid=$!
4842         local mtime1=`stat -c %Y $DIR1/$tfile`
4843
4844         mv $DIR1/$tfile $DIR1/$tfile-1
4845
4846         kill -USR1 $multipid
4847         wait $multipid || error "multiop close failed"
4848
4849         for (( i=0; i < 2; i++ )) ; do
4850                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4851                 [ "$mtime1" = "$mtime2" ] ||
4852                         error "mtime is lost on close: $mtime2, " \
4853                               "should be $mtime1"
4854
4855                 cancel_lru_locks
4856                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4857         done
4858         lctl set_param fail_loc=0
4859         stop_full_debug_logging
4860 }
4861 run_test 39j "write, rename, close, stat ======================="
4862
4863 test_39k() {
4864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4865
4866         touch $DIR1/$tfile
4867         sleep 1
4868
4869         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4870         local multipid=$!
4871         local mtime1=`stat -c %Y $DIR1/$tfile`
4872
4873         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4874
4875         kill -USR1 $multipid
4876         wait $multipid || error "multiop close failed"
4877
4878         for (( i=0; i < 2; i++ )) ; do
4879                 local mtime2=`stat -c %Y $DIR1/$tfile`
4880
4881                 [ "$mtime2" = $TEST_39_MTIME ] || \
4882                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4883
4884                 cancel_lru_locks
4885                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4886         done
4887 }
4888 run_test 39k "write, utime, close, stat ========================"
4889
4890 # this should be set to future
4891 TEST_39_ATIME=`date -d "1 year" +%s`
4892
4893 test_39l() {
4894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4895         remote_mds_nodsh && skip "remote MDS with nodsh"
4896
4897         local atime_diff=$(do_facet $SINGLEMDS \
4898                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4899         rm -rf $DIR/$tdir
4900         mkdir_on_mdt0 $DIR/$tdir
4901
4902         # test setting directory atime to future
4903         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4904         local atime=$(stat -c %X $DIR/$tdir)
4905         [ "$atime" = $TEST_39_ATIME ] ||
4906                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4907
4908         # test setting directory atime from future to now
4909         local now=$(date +%s)
4910         touch -a -d @$now $DIR/$tdir
4911
4912         atime=$(stat -c %X $DIR/$tdir)
4913         [ "$atime" -eq "$now"  ] ||
4914                 error "atime is not updated from future: $atime, $now"
4915
4916         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4917         sleep 3
4918
4919         # test setting directory atime when now > dir atime + atime_diff
4920         local d1=$(date +%s)
4921         ls $DIR/$tdir
4922         local d2=$(date +%s)
4923         cancel_lru_locks mdc
4924         atime=$(stat -c %X $DIR/$tdir)
4925         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4926                 error "atime is not updated  : $atime, should be $d2"
4927
4928         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4929         sleep 3
4930
4931         # test not setting directory atime when now < dir atime + atime_diff
4932         ls $DIR/$tdir
4933         cancel_lru_locks mdc
4934         atime=$(stat -c %X $DIR/$tdir)
4935         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4936                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4937
4938         do_facet $SINGLEMDS \
4939                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4940 }
4941 run_test 39l "directory atime update ==========================="
4942
4943 test_39m() {
4944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4945
4946         touch $DIR1/$tfile
4947         sleep 2
4948         local far_past_mtime=$(date -d "May 29 1953" +%s)
4949         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4950
4951         touch -m -d @$far_past_mtime $DIR1/$tfile
4952         touch -a -d @$far_past_atime $DIR1/$tfile
4953
4954         for (( i=0; i < 2; i++ )) ; do
4955                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4956                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4957                         error "atime or mtime set incorrectly"
4958
4959                 cancel_lru_locks $OSC
4960                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4961         done
4962 }
4963 run_test 39m "test atime and mtime before 1970"
4964
4965 test_39n() { # LU-3832
4966         remote_mds_nodsh && skip "remote MDS with nodsh"
4967
4968         local atime_diff=$(do_facet $SINGLEMDS \
4969                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4970         local atime0
4971         local atime1
4972         local atime2
4973
4974         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4975
4976         rm -rf $DIR/$tfile
4977         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4978         atime0=$(stat -c %X $DIR/$tfile)
4979
4980         sleep 5
4981         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4982         atime1=$(stat -c %X $DIR/$tfile)
4983
4984         sleep 5
4985         cancel_lru_locks mdc
4986         cancel_lru_locks osc
4987         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4988         atime2=$(stat -c %X $DIR/$tfile)
4989
4990         do_facet $SINGLEMDS \
4991                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4992
4993         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4994         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4995 }
4996 run_test 39n "check that O_NOATIME is honored"
4997
4998 test_39o() {
4999         TESTDIR=$DIR/$tdir/$tfile
5000         [ -e $TESTDIR ] && rm -rf $TESTDIR
5001         mkdir -p $TESTDIR
5002         cd $TESTDIR
5003         links1=2
5004         ls
5005         mkdir a b
5006         ls
5007         links2=$(stat -c %h .)
5008         [ $(($links1 + 2)) != $links2 ] &&
5009                 error "wrong links count $(($links1 + 2)) != $links2"
5010         rmdir b
5011         links3=$(stat -c %h .)
5012         [ $(($links1 + 1)) != $links3 ] &&
5013                 error "wrong links count $links1 != $links3"
5014         return 0
5015 }
5016 run_test 39o "directory cached attributes updated after create"
5017
5018 test_39p() {
5019         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5020
5021         local MDTIDX=1
5022         TESTDIR=$DIR/$tdir/$tdir
5023         [ -e $TESTDIR ] && rm -rf $TESTDIR
5024         test_mkdir -p $TESTDIR
5025         cd $TESTDIR
5026         links1=2
5027         ls
5028         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5029         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5030         ls
5031         links2=$(stat -c %h .)
5032         [ $(($links1 + 2)) != $links2 ] &&
5033                 error "wrong links count $(($links1 + 2)) != $links2"
5034         rmdir remote_dir2
5035         links3=$(stat -c %h .)
5036         [ $(($links1 + 1)) != $links3 ] &&
5037                 error "wrong links count $links1 != $links3"
5038         return 0
5039 }
5040 run_test 39p "remote directory cached attributes updated after create ========"
5041
5042 test_39r() {
5043         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5044                 skip "no atime update on old OST"
5045         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5046                 skip_env "ldiskfs only test"
5047         fi
5048
5049         local saved_adiff
5050         saved_adiff=$(do_facet ost1 \
5051                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5052         stack_trap "do_facet ost1 \
5053                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5054
5055         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5056
5057         $LFS setstripe -i 0 $DIR/$tfile
5058         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5059                 error "can't write initial file"
5060         cancel_lru_locks osc
5061
5062         # exceed atime_diff and access file
5063         sleep 6
5064         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5065                 error "can't udpate atime"
5066
5067         local atime_cli=$(stat -c %X $DIR/$tfile)
5068         echo "client atime: $atime_cli"
5069         # allow atime update to be written to device
5070         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5071         sleep 5
5072
5073         local ostdev=$(ostdevname 1)
5074         local fid=($(lfs getstripe -y $DIR/$tfile |
5075                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
5076         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
5077         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5078
5079         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5080         local atime_ost=$(do_facet ost1 "$cmd" |&
5081                           awk -F'[: ]' '/atime:/ { print $4 }')
5082         (( atime_cli == atime_ost )) ||
5083                 error "atime on client $atime_cli != ost $atime_ost"
5084 }
5085 run_test 39r "lazy atime update on OST"
5086
5087 test_39q() { # LU-8041
5088         local testdir=$DIR/$tdir
5089         mkdir -p $testdir
5090         multiop_bg_pause $testdir D_c || error "multiop failed"
5091         local multipid=$!
5092         cancel_lru_locks mdc
5093         kill -USR1 $multipid
5094         local atime=$(stat -c %X $testdir)
5095         [ "$atime" -ne 0 ] || error "atime is zero"
5096 }
5097 run_test 39q "close won't zero out atime"
5098
5099 test_40() {
5100         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5101         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5102                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5103         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5104                 error "$tfile is not 4096 bytes in size"
5105 }
5106 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5107
5108 test_41() {
5109         # bug 1553
5110         small_write $DIR/f41 18
5111 }
5112 run_test 41 "test small file write + fstat ====================="
5113
5114 count_ost_writes() {
5115         lctl get_param -n ${OSC}.*.stats |
5116                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5117                         END { printf("%0.0f", writes) }'
5118 }
5119
5120 # decent default
5121 WRITEBACK_SAVE=500
5122 DIRTY_RATIO_SAVE=40
5123 MAX_DIRTY_RATIO=50
5124 BG_DIRTY_RATIO_SAVE=10
5125 MAX_BG_DIRTY_RATIO=25
5126
5127 start_writeback() {
5128         trap 0
5129         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5130         # dirty_ratio, dirty_background_ratio
5131         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5132                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5133                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5134                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5135         else
5136                 # if file not here, we are a 2.4 kernel
5137                 kill -CONT `pidof kupdated`
5138         fi
5139 }
5140
5141 stop_writeback() {
5142         # setup the trap first, so someone cannot exit the test at the
5143         # exact wrong time and mess up a machine
5144         trap start_writeback EXIT
5145         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5146         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5147                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5148                 sysctl -w vm.dirty_writeback_centisecs=0
5149                 sysctl -w vm.dirty_writeback_centisecs=0
5150                 # save and increase /proc/sys/vm/dirty_ratio
5151                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5152                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5153                 # save and increase /proc/sys/vm/dirty_background_ratio
5154                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5155                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5156         else
5157                 # if file not here, we are a 2.4 kernel
5158                 kill -STOP `pidof kupdated`
5159         fi
5160 }
5161
5162 # ensure that all stripes have some grant before we test client-side cache
5163 setup_test42() {
5164         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5165                 dd if=/dev/zero of=$i bs=4k count=1
5166                 rm $i
5167         done
5168 }
5169
5170 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5171 # file truncation, and file removal.
5172 test_42a() {
5173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5174
5175         setup_test42
5176         cancel_lru_locks $OSC
5177         stop_writeback
5178         sync; sleep 1; sync # just to be safe
5179         BEFOREWRITES=`count_ost_writes`
5180         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5181         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5182         AFTERWRITES=`count_ost_writes`
5183         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5184                 error "$BEFOREWRITES < $AFTERWRITES"
5185         start_writeback
5186 }
5187 run_test 42a "ensure that we don't flush on close"
5188
5189 test_42b() {
5190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5191
5192         setup_test42
5193         cancel_lru_locks $OSC
5194         stop_writeback
5195         sync
5196         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5197         BEFOREWRITES=$(count_ost_writes)
5198         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5199         AFTERWRITES=$(count_ost_writes)
5200         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5201                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5202         fi
5203         BEFOREWRITES=$(count_ost_writes)
5204         sync || error "sync: $?"
5205         AFTERWRITES=$(count_ost_writes)
5206         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5207                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5208         fi
5209         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5210         start_writeback
5211         return 0
5212 }
5213 run_test 42b "test destroy of file with cached dirty data ======"
5214
5215 # if these tests just want to test the effect of truncation,
5216 # they have to be very careful.  consider:
5217 # - the first open gets a {0,EOF}PR lock
5218 # - the first write conflicts and gets a {0, count-1}PW
5219 # - the rest of the writes are under {count,EOF}PW
5220 # - the open for truncate tries to match a {0,EOF}PR
5221 #   for the filesize and cancels the PWs.
5222 # any number of fixes (don't get {0,EOF} on open, match
5223 # composite locks, do smarter file size management) fix
5224 # this, but for now we want these tests to verify that
5225 # the cancellation with truncate intent works, so we
5226 # start the file with a full-file pw lock to match against
5227 # until the truncate.
5228 trunc_test() {
5229         test=$1
5230         file=$DIR/$test
5231         offset=$2
5232         cancel_lru_locks $OSC
5233         stop_writeback
5234         # prime the file with 0,EOF PW to match
5235         touch $file
5236         $TRUNCATE $file 0
5237         sync; sync
5238         # now the real test..
5239         dd if=/dev/zero of=$file bs=1024 count=100
5240         BEFOREWRITES=`count_ost_writes`
5241         $TRUNCATE $file $offset
5242         cancel_lru_locks $OSC
5243         AFTERWRITES=`count_ost_writes`
5244         start_writeback
5245 }
5246
5247 test_42c() {
5248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5249
5250         trunc_test 42c 1024
5251         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5252                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5253         rm $file
5254 }
5255 run_test 42c "test partial truncate of file with cached dirty data"
5256
5257 test_42d() {
5258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5259
5260         trunc_test 42d 0
5261         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5262                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5263         rm $file
5264 }
5265 run_test 42d "test complete truncate of file with cached dirty data"
5266
5267 test_42e() { # bug22074
5268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5269
5270         local TDIR=$DIR/${tdir}e
5271         local pages=16 # hardcoded 16 pages, don't change it.
5272         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5273         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5274         local max_dirty_mb
5275         local warmup_files
5276
5277         test_mkdir $DIR/${tdir}e
5278         $LFS setstripe -c 1 $TDIR
5279         createmany -o $TDIR/f $files
5280
5281         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5282
5283         # we assume that with $OSTCOUNT files, at least one of them will
5284         # be allocated on OST0.
5285         warmup_files=$((OSTCOUNT * max_dirty_mb))
5286         createmany -o $TDIR/w $warmup_files
5287
5288         # write a large amount of data into one file and sync, to get good
5289         # avail_grant number from OST.
5290         for ((i=0; i<$warmup_files; i++)); do
5291                 idx=$($LFS getstripe -i $TDIR/w$i)
5292                 [ $idx -ne 0 ] && continue
5293                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5294                 break
5295         done
5296         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5297         sync
5298         $LCTL get_param $proc_osc0/cur_dirty_bytes
5299         $LCTL get_param $proc_osc0/cur_grant_bytes
5300
5301         # create as much dirty pages as we can while not to trigger the actual
5302         # RPCs directly. but depends on the env, VFS may trigger flush during this
5303         # period, hopefully we are good.
5304         for ((i=0; i<$warmup_files; i++)); do
5305                 idx=$($LFS getstripe -i $TDIR/w$i)
5306                 [ $idx -ne 0 ] && continue
5307                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5308         done
5309         $LCTL get_param $proc_osc0/cur_dirty_bytes
5310         $LCTL get_param $proc_osc0/cur_grant_bytes
5311
5312         # perform the real test
5313         $LCTL set_param $proc_osc0/rpc_stats 0
5314         for ((;i<$files; i++)); do
5315                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5316                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5317         done
5318         sync
5319         $LCTL get_param $proc_osc0/rpc_stats
5320
5321         local percent=0
5322         local have_ppr=false
5323         $LCTL get_param $proc_osc0/rpc_stats |
5324                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5325                         # skip lines until we are at the RPC histogram data
5326                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5327                         $have_ppr || continue
5328
5329                         # we only want the percent stat for < 16 pages
5330                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5331
5332                         percent=$((percent + WPCT))
5333                         if [[ $percent -gt 15 ]]; then
5334                                 error "less than 16-pages write RPCs" \
5335                                       "$percent% > 15%"
5336                                 break
5337                         fi
5338                 done
5339         rm -rf $TDIR
5340 }
5341 run_test 42e "verify sub-RPC writes are not done synchronously"
5342
5343 test_43A() { # was test_43
5344         test_mkdir $DIR/$tdir
5345         cp -p /bin/ls $DIR/$tdir/$tfile
5346         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5347         pid=$!
5348         # give multiop a chance to open
5349         sleep 1
5350
5351         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5352         kill -USR1 $pid
5353         # Wait for multiop to exit
5354         wait $pid
5355 }
5356 run_test 43A "execution of file opened for write should return -ETXTBSY"
5357
5358 test_43a() {
5359         test_mkdir $DIR/$tdir
5360         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5361         $DIR/$tdir/sleep 60 &
5362         SLEEP_PID=$!
5363         # Make sure exec of $tdir/sleep wins race with truncate
5364         sleep 1
5365         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5366         kill $SLEEP_PID
5367 }
5368 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5369
5370 test_43b() {
5371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5372
5373         test_mkdir $DIR/$tdir
5374         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5375         $DIR/$tdir/sleep 60 &
5376         SLEEP_PID=$!
5377         # Make sure exec of $tdir/sleep wins race with truncate
5378         sleep 1
5379         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5380         kill $SLEEP_PID
5381 }
5382 run_test 43b "truncate of file being executed should return -ETXTBSY"
5383
5384 test_43c() {
5385         local testdir="$DIR/$tdir"
5386         test_mkdir $testdir
5387         cp $SHELL $testdir/
5388         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5389                 ( cd $testdir && md5sum -c )
5390 }
5391 run_test 43c "md5sum of copy into lustre"
5392
5393 test_44A() { # was test_44
5394         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5395
5396         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5397         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5398 }
5399 run_test 44A "zero length read from a sparse stripe"
5400
5401 test_44a() {
5402         local nstripe=$($LFS getstripe -c -d $DIR)
5403         [ -z "$nstripe" ] && skip "can't get stripe info"
5404         [[ $nstripe -gt $OSTCOUNT ]] &&
5405                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5406
5407         local stride=$($LFS getstripe -S -d $DIR)
5408         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5409                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5410         fi
5411
5412         OFFSETS="0 $((stride/2)) $((stride-1))"
5413         for offset in $OFFSETS; do
5414                 for i in $(seq 0 $((nstripe-1))); do
5415                         local GLOBALOFFSETS=""
5416                         # size in Bytes
5417                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5418                         local myfn=$DIR/d44a-$size
5419                         echo "--------writing $myfn at $size"
5420                         ll_sparseness_write $myfn $size ||
5421                                 error "ll_sparseness_write"
5422                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5423                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5424                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5425
5426                         for j in $(seq 0 $((nstripe-1))); do
5427                                 # size in Bytes
5428                                 size=$((((j + $nstripe )*$stride + $offset)))
5429                                 ll_sparseness_write $myfn $size ||
5430                                         error "ll_sparseness_write"
5431                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5432                         done
5433                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5434                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5435                         rm -f $myfn
5436                 done
5437         done
5438 }
5439 run_test 44a "test sparse pwrite ==============================="
5440
5441 dirty_osc_total() {
5442         tot=0
5443         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5444                 tot=$(($tot + $d))
5445         done
5446         echo $tot
5447 }
5448 do_dirty_record() {
5449         before=`dirty_osc_total`
5450         echo executing "\"$*\""
5451         eval $*
5452         after=`dirty_osc_total`
5453         echo before $before, after $after
5454 }
5455 test_45() {
5456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5457
5458         f="$DIR/f45"
5459         # Obtain grants from OST if it supports it
5460         echo blah > ${f}_grant
5461         stop_writeback
5462         sync
5463         do_dirty_record "echo blah > $f"
5464         [[ $before -eq $after ]] && error "write wasn't cached"
5465         do_dirty_record "> $f"
5466         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5467         do_dirty_record "echo blah > $f"
5468         [[ $before -eq $after ]] && error "write wasn't cached"
5469         do_dirty_record "sync"
5470         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5471         do_dirty_record "echo blah > $f"
5472         [[ $before -eq $after ]] && error "write wasn't cached"
5473         do_dirty_record "cancel_lru_locks osc"
5474         [[ $before -gt $after ]] ||
5475                 error "lock cancellation didn't lower dirty count"
5476         start_writeback
5477 }
5478 run_test 45 "osc io page accounting ============================"
5479
5480 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5481 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5482 # objects offset and an assert hit when an rpc was built with 1023's mapped
5483 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5484 test_46() {
5485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5486
5487         f="$DIR/f46"
5488         stop_writeback
5489         sync
5490         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5491         sync
5492         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5493         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5494         sync
5495         start_writeback
5496 }
5497 run_test 46 "dirtying a previously written page ================"
5498
5499 # test_47 is removed "Device nodes check" is moved to test_28
5500
5501 test_48a() { # bug 2399
5502         [ "$mds1_FSTYPE" = "zfs" ] &&
5503         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5504                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5505
5506         test_mkdir $DIR/$tdir
5507         cd $DIR/$tdir
5508         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5509         test_mkdir $DIR/$tdir
5510         touch foo || error "'touch foo' failed after recreating cwd"
5511         test_mkdir bar
5512         touch .foo || error "'touch .foo' failed after recreating cwd"
5513         test_mkdir .bar
5514         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5515         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5516         cd . || error "'cd .' failed after recreating cwd"
5517         mkdir . && error "'mkdir .' worked after recreating cwd"
5518         rmdir . && error "'rmdir .' worked after recreating cwd"
5519         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5520         cd .. || error "'cd ..' failed after recreating cwd"
5521 }
5522 run_test 48a "Access renamed working dir (should return errors)="
5523
5524 test_48b() { # bug 2399
5525         rm -rf $DIR/$tdir
5526         test_mkdir $DIR/$tdir
5527         cd $DIR/$tdir
5528         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5529         touch foo && error "'touch foo' worked after removing cwd"
5530         mkdir foo && error "'mkdir foo' worked after removing cwd"
5531         touch .foo && error "'touch .foo' worked after removing cwd"
5532         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5533         ls . > /dev/null && error "'ls .' worked after removing cwd"
5534         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5535         mkdir . && error "'mkdir .' worked after removing cwd"
5536         rmdir . && error "'rmdir .' worked after removing cwd"
5537         ln -s . foo && error "'ln -s .' worked after removing cwd"
5538         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5539 }
5540 run_test 48b "Access removed working dir (should return errors)="
5541
5542 test_48c() { # bug 2350
5543         #lctl set_param debug=-1
5544         #set -vx
5545         rm -rf $DIR/$tdir
5546         test_mkdir -p $DIR/$tdir/dir
5547         cd $DIR/$tdir/dir
5548         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5549         $TRACE touch foo && error "touch foo worked after removing cwd"
5550         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5551         touch .foo && error "touch .foo worked after removing cwd"
5552         mkdir .foo && error "mkdir .foo worked after removing cwd"
5553         $TRACE ls . && error "'ls .' worked after removing cwd"
5554         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5555         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5556         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5557         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5558         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5559 }
5560 run_test 48c "Access removed working subdir (should return errors)"
5561
5562 test_48d() { # bug 2350
5563         #lctl set_param debug=-1
5564         #set -vx
5565         rm -rf $DIR/$tdir
5566         test_mkdir -p $DIR/$tdir/dir
5567         cd $DIR/$tdir/dir
5568         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5569         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5570         $TRACE touch foo && error "'touch foo' worked after removing parent"
5571         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5572         touch .foo && error "'touch .foo' worked after removing parent"
5573         mkdir .foo && error "mkdir .foo worked after removing parent"
5574         $TRACE ls . && error "'ls .' worked after removing parent"
5575         $TRACE ls .. && error "'ls ..' worked after removing parent"
5576         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5577         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5578         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5579         true
5580 }
5581 run_test 48d "Access removed parent subdir (should return errors)"
5582
5583 test_48e() { # bug 4134
5584         #lctl set_param debug=-1
5585         #set -vx
5586         rm -rf $DIR/$tdir
5587         test_mkdir -p $DIR/$tdir/dir
5588         cd $DIR/$tdir/dir
5589         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5590         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5591         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5592         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5593         # On a buggy kernel addition of "touch foo" after cd .. will
5594         # produce kernel oops in lookup_hash_it
5595         touch ../foo && error "'cd ..' worked after recreate parent"
5596         cd $DIR
5597         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5598 }
5599 run_test 48e "Access to recreated parent subdir (should return errors)"
5600
5601 test_48f() {
5602         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5603                 skip "need MDS >= 2.13.55"
5604         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5605         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5606                 skip "needs different host for mdt1 mdt2"
5607         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5608
5609         $LFS mkdir -i0 $DIR/$tdir
5610         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5611
5612         for d in sub1 sub2 sub3; do
5613                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5614                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5615                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5616         done
5617
5618         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5619 }
5620 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5621
5622 test_49() { # LU-1030
5623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5624         remote_ost_nodsh && skip "remote OST with nodsh"
5625
5626         # get ost1 size - $FSNAME-OST0000
5627         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5628                 awk '{ print $4 }')
5629         # write 800M at maximum
5630         [[ $ost1_size -lt 2 ]] && ost1_size=2
5631         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5632
5633         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5634         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5635         local dd_pid=$!
5636
5637         # change max_pages_per_rpc while writing the file
5638         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5639         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5640         # loop until dd process exits
5641         while ps ax -opid | grep -wq $dd_pid; do
5642                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5643                 sleep $((RANDOM % 5 + 1))
5644         done
5645         # restore original max_pages_per_rpc
5646         $LCTL set_param $osc1_mppc=$orig_mppc
5647         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5648 }
5649 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5650
5651 test_50() {
5652         # bug 1485
5653         test_mkdir $DIR/$tdir
5654         cd $DIR/$tdir
5655         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5656 }
5657 run_test 50 "special situations: /proc symlinks  ==============="
5658
5659 test_51a() {    # was test_51
5660         # bug 1516 - create an empty entry right after ".." then split dir
5661         test_mkdir -c1 $DIR/$tdir
5662         touch $DIR/$tdir/foo
5663         $MCREATE $DIR/$tdir/bar
5664         rm $DIR/$tdir/foo
5665         createmany -m $DIR/$tdir/longfile 201
5666         FNUM=202
5667         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5668                 $MCREATE $DIR/$tdir/longfile$FNUM
5669                 FNUM=$(($FNUM + 1))
5670                 echo -n "+"
5671         done
5672         echo
5673         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5674 }
5675 run_test 51a "special situations: split htree with empty entry =="
5676
5677 cleanup_print_lfs_df () {
5678         trap 0
5679         $LFS df
5680         $LFS df -i
5681 }
5682
5683 test_51b() {
5684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5685
5686         local dir=$DIR/$tdir
5687         local nrdirs=$((65536 + 100))
5688
5689         # cleanup the directory
5690         rm -fr $dir
5691
5692         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5693
5694         $LFS df
5695         $LFS df -i
5696         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5697         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5698         [[ $numfree -lt $nrdirs ]] &&
5699                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5700
5701         # need to check free space for the directories as well
5702         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5703         numfree=$(( blkfree / $(fs_inode_ksize) ))
5704         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5705
5706         trap cleanup_print_lfs_df EXIT
5707
5708         # create files
5709         createmany -d $dir/d $nrdirs || {
5710                 unlinkmany $dir/d $nrdirs
5711                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5712         }
5713
5714         # really created :
5715         nrdirs=$(ls -U $dir | wc -l)
5716
5717         # unlink all but 100 subdirectories, then check it still works
5718         local left=100
5719         local delete=$((nrdirs - left))
5720
5721         $LFS df
5722         $LFS df -i
5723
5724         # for ldiskfs the nlink count should be 1, but this is OSD specific
5725         # and so this is listed for informational purposes only
5726         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5727         unlinkmany -d $dir/d $delete ||
5728                 error "unlink of first $delete subdirs failed"
5729
5730         echo "nlink between: $(stat -c %h $dir)"
5731         local found=$(ls -U $dir | wc -l)
5732         [ $found -ne $left ] &&
5733                 error "can't find subdirs: found only $found, expected $left"
5734
5735         unlinkmany -d $dir/d $delete $left ||
5736                 error "unlink of second $left subdirs failed"
5737         # regardless of whether the backing filesystem tracks nlink accurately
5738         # or not, the nlink count shouldn't be more than "." and ".." here
5739         local after=$(stat -c %h $dir)
5740         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5741                 echo "nlink after: $after"
5742
5743         cleanup_print_lfs_df
5744 }
5745 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5746
5747 test_51d() {
5748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5749         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5750         local qos_old
5751
5752         test_mkdir $DIR/$tdir
5753         $LFS setstripe -c $OSTCOUNT $DIR/$tdir
5754
5755         qos_old=$(do_facet mds1 \
5756                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5757         do_nodes $(comma_list $(mdts_nodes)) \
5758                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5759         stack_trap "do_nodes $(comma_list $(mdts_nodes)) \
5760                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5761
5762         createmany -o $DIR/$tdir/t- 1000
5763         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5764         for ((n = 0; n < $OSTCOUNT; n++)); do
5765                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5766                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5767                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5768                             '($1 == '$n') { objs += 1 } \
5769                             END { printf("%0.0f", objs) }')
5770                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5771         done
5772         unlinkmany $DIR/$tdir/t- 1000
5773
5774         nlast=0
5775         for ((n = 0; n < $OSTCOUNT; n++)); do
5776                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5777                         { $LFS df && $LFS df -i &&
5778                         error "OST $n has fewer objects vs. OST $nlast" \
5779                               " (${objs[$n]} < ${objs[$nlast]}"; }
5780                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5781                         { $LFS df && $LFS df -i &&
5782                         error "OST $n has fewer objects vs. OST $nlast" \
5783                               " (${objs[$n]} < ${objs[$nlast]}"; }
5784
5785                 (( ${objs0[$n]} > ${objs0[$nlast]} * 4 / 5 )) ||
5786                         { $LFS df && $LFS df -i &&
5787                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5788                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5789                 (( ${objs0[$n]} < ${objs0[$nlast]} * 5 / 4 )) ||
5790                         { $LFS df && $LFS df -i &&
5791                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5792                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5793                 nlast=$n
5794         done
5795 }
5796 run_test 51d "check object distribution"
5797
5798 test_51e() {
5799         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5800                 skip_env "ldiskfs only test"
5801         fi
5802
5803         test_mkdir -c1 $DIR/$tdir
5804         test_mkdir -c1 $DIR/$tdir/d0
5805
5806         touch $DIR/$tdir/d0/foo
5807         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5808                 error "file exceed 65000 nlink limit!"
5809         unlinkmany $DIR/$tdir/d0/f- 65001
5810         return 0
5811 }
5812 run_test 51e "check file nlink limit"
5813
5814 test_51f() {
5815         test_mkdir $DIR/$tdir
5816
5817         local max=100000
5818         local ulimit_old=$(ulimit -n)
5819         local spare=20 # number of spare fd's for scripts/libraries, etc.
5820         local mdt=$($LFS getstripe -m $DIR/$tdir)
5821         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5822
5823         echo "MDT$mdt numfree=$numfree, max=$max"
5824         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5825         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5826                 while ! ulimit -n $((numfree + spare)); do
5827                         numfree=$((numfree * 3 / 4))
5828                 done
5829                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5830         else
5831                 echo "left ulimit at $ulimit_old"
5832         fi
5833
5834         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5835                 unlinkmany $DIR/$tdir/f $numfree
5836                 error "create+open $numfree files in $DIR/$tdir failed"
5837         }
5838         ulimit -n $ulimit_old
5839
5840         # if createmany exits at 120s there will be fewer than $numfree files
5841         unlinkmany $DIR/$tdir/f $numfree || true
5842 }
5843 run_test 51f "check many open files limit"
5844
5845 test_52a() {
5846         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5847         test_mkdir $DIR/$tdir
5848         touch $DIR/$tdir/foo
5849         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5850         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5851         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5852         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5853         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5854                                         error "link worked"
5855         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5856         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5857         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5858                                                      error "lsattr"
5859         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5860         cp -r $DIR/$tdir $TMP/
5861         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5862 }
5863 run_test 52a "append-only flag test (should return errors)"
5864
5865 test_52b() {
5866         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5867         test_mkdir $DIR/$tdir
5868         touch $DIR/$tdir/foo
5869         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5870         cat test > $DIR/$tdir/foo && error "cat test worked"
5871         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5872         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5873         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5874                                         error "link worked"
5875         echo foo >> $DIR/$tdir/foo && error "echo worked"
5876         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5877         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5878         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5879         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5880                                                         error "lsattr"
5881         chattr -i $DIR/$tdir/foo || error "chattr failed"
5882
5883         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5884 }
5885 run_test 52b "immutable flag test (should return errors) ======="
5886
5887 test_53() {
5888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5889         remote_mds_nodsh && skip "remote MDS with nodsh"
5890         remote_ost_nodsh && skip "remote OST with nodsh"
5891
5892         local param
5893         local param_seq
5894         local ostname
5895         local mds_last
5896         local mds_last_seq
5897         local ost_last
5898         local ost_last_seq
5899         local ost_last_id
5900         local ostnum
5901         local node
5902         local found=false
5903         local support_last_seq=true
5904
5905         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5906                 support_last_seq=false
5907
5908         # only test MDT0000
5909         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5910         local value
5911         for value in $(do_facet $SINGLEMDS \
5912                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5913                 param=$(echo ${value[0]} | cut -d "=" -f1)
5914                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5915
5916                 if $support_last_seq; then
5917                         param_seq=$(echo $param |
5918                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5919                         mds_last_seq=$(do_facet $SINGLEMDS \
5920                                        $LCTL get_param -n $param_seq)
5921                 fi
5922                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5923
5924                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5925                 node=$(facet_active_host ost$((ostnum+1)))
5926                 param="obdfilter.$ostname.last_id"
5927                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5928                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5929                         ost_last_id=$ost_last
5930
5931                         if $support_last_seq; then
5932                                 ost_last_id=$(echo $ost_last |
5933                                               awk -F':' '{print $2}' |
5934                                               sed -e "s/^0x//g")
5935                                 ost_last_seq=$(echo $ost_last |
5936                                                awk -F':' '{print $1}')
5937                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5938                         fi
5939
5940                         if [[ $ost_last_id != $mds_last ]]; then
5941                                 error "$ost_last_id != $mds_last"
5942                         else
5943                                 found=true
5944                                 break
5945                         fi
5946                 done
5947         done
5948         $found || error "can not match last_seq/last_id for $mdtosc"
5949         return 0
5950 }
5951 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5952
5953 test_54a() {
5954         perl -MSocket -e ';' || skip "no Socket perl module installed"
5955
5956         $SOCKETSERVER $DIR/socket ||
5957                 error "$SOCKETSERVER $DIR/socket failed: $?"
5958         $SOCKETCLIENT $DIR/socket ||
5959                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5960         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5961 }
5962 run_test 54a "unix domain socket test =========================="
5963
5964 test_54b() {
5965         f="$DIR/f54b"
5966         mknod $f c 1 3
5967         chmod 0666 $f
5968         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5969 }
5970 run_test 54b "char device works in lustre ======================"
5971
5972 find_loop_dev() {
5973         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5974         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5975         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5976
5977         for i in $(seq 3 7); do
5978                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5979                 LOOPDEV=$LOOPBASE$i
5980                 LOOPNUM=$i
5981                 break
5982         done
5983 }
5984
5985 cleanup_54c() {
5986         local rc=0
5987         loopdev="$DIR/loop54c"
5988
5989         trap 0
5990         $UMOUNT $DIR/$tdir || rc=$?
5991         losetup -d $loopdev || true
5992         losetup -d $LOOPDEV || true
5993         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5994         return $rc
5995 }
5996
5997 test_54c() {
5998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5999
6000         loopdev="$DIR/loop54c"
6001
6002         find_loop_dev
6003         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6004         trap cleanup_54c EXIT
6005         mknod $loopdev b 7 $LOOPNUM
6006         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6007         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6008         losetup $loopdev $DIR/$tfile ||
6009                 error "can't set up $loopdev for $DIR/$tfile"
6010         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6011         test_mkdir $DIR/$tdir
6012         mount -t ext2 $loopdev $DIR/$tdir ||
6013                 error "error mounting $loopdev on $DIR/$tdir"
6014         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6015                 error "dd write"
6016         df $DIR/$tdir
6017         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6018                 error "dd read"
6019         cleanup_54c
6020 }
6021 run_test 54c "block device works in lustre ====================="
6022
6023 test_54d() {
6024         f="$DIR/f54d"
6025         string="aaaaaa"
6026         mknod $f p
6027         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
6028 }
6029 run_test 54d "fifo device works in lustre ======================"
6030
6031 test_54e() {
6032         f="$DIR/f54e"
6033         string="aaaaaa"
6034         cp -aL /dev/console $f
6035         echo $string > $f || error "echo $string to $f failed"
6036 }
6037 run_test 54e "console/tty device works in lustre ======================"
6038
6039 test_56a() {
6040         local numfiles=3
6041         local numdirs=2
6042         local dir=$DIR/$tdir
6043
6044         rm -rf $dir
6045         test_mkdir -p $dir/dir
6046         for i in $(seq $numfiles); do
6047                 touch $dir/file$i
6048                 touch $dir/dir/file$i
6049         done
6050
6051         local numcomp=$($LFS getstripe --component-count $dir)
6052
6053         [[ $numcomp == 0 ]] && numcomp=1
6054
6055         # test lfs getstripe with --recursive
6056         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6057
6058         [[ $filenum -eq $((numfiles * 2)) ]] ||
6059                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6060         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6061         [[ $filenum -eq $numfiles ]] ||
6062                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6063         echo "$LFS getstripe showed obdidx or l_ost_idx"
6064
6065         # test lfs getstripe with file instead of dir
6066         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6067         [[ $filenum -eq 1 ]] ||
6068                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6069         echo "$LFS getstripe file1 passed"
6070
6071         #test lfs getstripe with --verbose
6072         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6073         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6074                 error "$LFS getstripe --verbose $dir: "\
6075                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6076         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6077                 error "$LFS getstripe $dir: showed lmm_magic"
6078
6079         #test lfs getstripe with -v prints lmm_fid
6080         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6081         local countfids=$((numdirs + numfiles * numcomp))
6082         [[ $filenum -eq $countfids ]] ||
6083                 error "$LFS getstripe -v $dir: "\
6084                       "got $filenum want $countfids lmm_fid"
6085         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6086                 error "$LFS getstripe $dir: showed lmm_fid by default"
6087         echo "$LFS getstripe --verbose passed"
6088
6089         #check for FID information
6090         local fid1=$($LFS getstripe --fid $dir/file1)
6091         local fid2=$($LFS getstripe --verbose $dir/file1 |
6092                      awk '/lmm_fid: / { print $2; exit; }')
6093         local fid3=$($LFS path2fid $dir/file1)
6094
6095         [ "$fid1" != "$fid2" ] &&
6096                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6097         [ "$fid1" != "$fid3" ] &&
6098                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6099         echo "$LFS getstripe --fid passed"
6100
6101         #test lfs getstripe with --obd
6102         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6103                 error "$LFS getstripe --obd wrong_uuid: should return error"
6104
6105         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6106
6107         local ostidx=1
6108         local obduuid=$(ostuuid_from_index $ostidx)
6109         local found=$($LFS getstripe -r --obd $obduuid $dir |
6110                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6111
6112         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6113         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6114                 ((filenum--))
6115         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6116                 ((filenum--))
6117
6118         [[ $found -eq $filenum ]] ||
6119                 error "$LFS getstripe --obd: found $found expect $filenum"
6120         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6121                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6122                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6123                 error "$LFS getstripe --obd: should not show file on other obd"
6124         echo "$LFS getstripe --obd passed"
6125 }
6126 run_test 56a "check $LFS getstripe"
6127
6128 test_56b() {
6129         local dir=$DIR/$tdir
6130         local numdirs=3
6131
6132         test_mkdir $dir
6133         for i in $(seq $numdirs); do
6134                 test_mkdir $dir/dir$i
6135         done
6136
6137         # test lfs getdirstripe default mode is non-recursion, which is
6138         # different from lfs getstripe
6139         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6140
6141         [[ $dircnt -eq 1 ]] ||
6142                 error "$LFS getdirstripe: found $dircnt, not 1"
6143         dircnt=$($LFS getdirstripe --recursive $dir |
6144                 grep -c lmv_stripe_count)
6145         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6146                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6147 }
6148 run_test 56b "check $LFS getdirstripe"
6149
6150 test_56c() {
6151         remote_ost_nodsh && skip "remote OST with nodsh"
6152
6153         local ost_idx=0
6154         local ost_name=$(ostname_from_index $ost_idx)
6155         local old_status=$(ost_dev_status $ost_idx)
6156         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6157
6158         [[ -z "$old_status" ]] ||
6159                 skip_env "OST $ost_name is in $old_status status"
6160
6161         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6162         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6163                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6164         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6165                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6166                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6167         fi
6168
6169         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6170                 error "$LFS df -v showing inactive devices"
6171         sleep_maxage
6172
6173         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6174
6175         [[ "$new_status" =~ "D" ]] ||
6176                 error "$ost_name status is '$new_status', missing 'D'"
6177         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6178                 [[ "$new_status" =~ "N" ]] ||
6179                         error "$ost_name status is '$new_status', missing 'N'"
6180         fi
6181         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6182                 [[ "$new_status" =~ "f" ]] ||
6183                         error "$ost_name status is '$new_status', missing 'f'"
6184         fi
6185
6186         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6187         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6188                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6189         [[ -z "$p" ]] && restore_lustre_params < $p || true
6190         sleep_maxage
6191
6192         new_status=$(ost_dev_status $ost_idx)
6193         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6194                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6195         # can't check 'f' as devices may actually be on flash
6196 }
6197 run_test 56c "check 'lfs df' showing device status"
6198
6199 test_56d() {
6200         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6201         local osts=$($LFS df -v $MOUNT | grep -c OST)
6202
6203         $LFS df $MOUNT
6204
6205         (( mdts == MDSCOUNT )) ||
6206                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6207         (( osts == OSTCOUNT )) ||
6208                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6209 }
6210 run_test 56d "'lfs df -v' prints only configured devices"
6211
6212 test_56e() {
6213         err_enoent=2 # No such file or directory
6214         err_eopnotsupp=95 # Operation not supported
6215
6216         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6217         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6218
6219         # Check for handling of path not exists
6220         output=$($LFS df $enoent_mnt 2>&1)
6221         ret=$?
6222
6223         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6224         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6225                 error "expect failure $err_enoent, not $ret"
6226
6227         # Check for handling of non-Lustre FS
6228         output=$($LFS df $notsup_mnt)
6229         ret=$?
6230
6231         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6232         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6233                 error "expect success $err_eopnotsupp, not $ret"
6234
6235         # Check for multiple LustreFS argument
6236         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6237         ret=$?
6238
6239         [[ $output -eq 3 && $ret -eq 0 ]] ||
6240                 error "expect success 3, not $output, rc = $ret"
6241
6242         # Check for correct non-Lustre FS handling among multiple
6243         # LustreFS argument
6244         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6245                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6246         ret=$?
6247
6248         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6249                 error "expect success 2, not $output, rc = $ret"
6250 }
6251 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6252
6253 NUMFILES=3
6254 NUMDIRS=3
6255 setup_56() {
6256         local local_tdir="$1"
6257         local local_numfiles="$2"
6258         local local_numdirs="$3"
6259         local dir_params="$4"
6260         local dir_stripe_params="$5"
6261
6262         if [ ! -d "$local_tdir" ] ; then
6263                 test_mkdir -p $dir_stripe_params $local_tdir
6264                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6265                 for i in $(seq $local_numfiles) ; do
6266                         touch $local_tdir/file$i
6267                 done
6268                 for i in $(seq $local_numdirs) ; do
6269                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6270                         for j in $(seq $local_numfiles) ; do
6271                                 touch $local_tdir/dir$i/file$j
6272                         done
6273                 done
6274         fi
6275 }
6276
6277 setup_56_special() {
6278         local local_tdir=$1
6279         local local_numfiles=$2
6280         local local_numdirs=$3
6281
6282         setup_56 $local_tdir $local_numfiles $local_numdirs
6283
6284         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6285                 for i in $(seq $local_numfiles) ; do
6286                         mknod $local_tdir/loop${i}b b 7 $i
6287                         mknod $local_tdir/null${i}c c 1 3
6288                         ln -s $local_tdir/file1 $local_tdir/link${i}
6289                 done
6290                 for i in $(seq $local_numdirs) ; do
6291                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6292                         mknod $local_tdir/dir$i/null${i}c c 1 3
6293                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6294                 done
6295         fi
6296 }
6297
6298 test_56g() {
6299         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6300         local expected=$(($NUMDIRS + 2))
6301
6302         setup_56 $dir $NUMFILES $NUMDIRS
6303
6304         # test lfs find with -name
6305         for i in $(seq $NUMFILES) ; do
6306                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6307
6308                 [ $nums -eq $expected ] ||
6309                         error "lfs find -name '*$i' $dir wrong: "\
6310                               "found $nums, expected $expected"
6311         done
6312 }
6313 run_test 56g "check lfs find -name"
6314
6315 test_56h() {
6316         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6317         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6318
6319         setup_56 $dir $NUMFILES $NUMDIRS
6320
6321         # test lfs find with ! -name
6322         for i in $(seq $NUMFILES) ; do
6323                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6324
6325                 [ $nums -eq $expected ] ||
6326                         error "lfs find ! -name '*$i' $dir wrong: "\
6327                               "found $nums, expected $expected"
6328         done
6329 }
6330 run_test 56h "check lfs find ! -name"
6331
6332 test_56i() {
6333         local dir=$DIR/$tdir
6334
6335         test_mkdir $dir
6336
6337         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6338         local out=$($cmd)
6339
6340         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6341 }
6342 run_test 56i "check 'lfs find -ost UUID' skips directories"
6343
6344 test_56j() {
6345         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6346
6347         setup_56_special $dir $NUMFILES $NUMDIRS
6348
6349         local expected=$((NUMDIRS + 1))
6350         local cmd="$LFS find -type d $dir"
6351         local nums=$($cmd | wc -l)
6352
6353         [ $nums -eq $expected ] ||
6354                 error "'$cmd' wrong: found $nums, expected $expected"
6355 }
6356 run_test 56j "check lfs find -type d"
6357
6358 test_56k() {
6359         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6360
6361         setup_56_special $dir $NUMFILES $NUMDIRS
6362
6363         local expected=$(((NUMDIRS + 1) * NUMFILES))
6364         local cmd="$LFS find -type f $dir"
6365         local nums=$($cmd | wc -l)
6366
6367         [ $nums -eq $expected ] ||
6368                 error "'$cmd' wrong: found $nums, expected $expected"
6369 }
6370 run_test 56k "check lfs find -type f"
6371
6372 test_56l() {
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 b $dir"
6379         local nums=$($cmd | wc -l)
6380
6381         [ $nums -eq $expected ] ||
6382                 error "'$cmd' wrong: found $nums, expected $expected"
6383 }
6384 run_test 56l "check lfs find -type b"
6385
6386 test_56m() {
6387         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6388
6389         setup_56_special $dir $NUMFILES $NUMDIRS
6390
6391         local expected=$((NUMDIRS + NUMFILES))
6392         local cmd="$LFS find -type c $dir"
6393         local nums=$($cmd | wc -l)
6394         [ $nums -eq $expected ] ||
6395                 error "'$cmd' wrong: found $nums, expected $expected"
6396 }
6397 run_test 56m "check lfs find -type c"
6398
6399 test_56n() {
6400         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6401         setup_56_special $dir $NUMFILES $NUMDIRS
6402
6403         local expected=$((NUMDIRS + NUMFILES))
6404         local cmd="$LFS find -type l $dir"
6405         local nums=$($cmd | wc -l)
6406
6407         [ $nums -eq $expected ] ||
6408                 error "'$cmd' wrong: found $nums, expected $expected"
6409 }
6410 run_test 56n "check lfs find -type l"
6411
6412 test_56o() {
6413         local dir=$DIR/$tdir
6414
6415         setup_56 $dir $NUMFILES $NUMDIRS
6416         utime $dir/file1 > /dev/null || error "utime (1)"
6417         utime $dir/file2 > /dev/null || error "utime (2)"
6418         utime $dir/dir1 > /dev/null || error "utime (3)"
6419         utime $dir/dir2 > /dev/null || error "utime (4)"
6420         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6421         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6422
6423         local expected=4
6424         local nums=$($LFS find -mtime +0 $dir | wc -l)
6425
6426         [ $nums -eq $expected ] ||
6427                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6428
6429         expected=12
6430         cmd="$LFS find -mtime 0 $dir"
6431         nums=$($cmd | wc -l)
6432         [ $nums -eq $expected ] ||
6433                 error "'$cmd' wrong: found $nums, expected $expected"
6434 }
6435 run_test 56o "check lfs find -mtime for old files"
6436
6437 test_56ob() {
6438         local dir=$DIR/$tdir
6439         local expected=1
6440         local count=0
6441
6442         # just to make sure there is something that won't be found
6443         test_mkdir $dir
6444         touch $dir/$tfile.now
6445
6446         for age in year week day hour min; do
6447                 count=$((count + 1))
6448
6449                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6450                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6451                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6452
6453                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6454                 local nums=$($cmd | wc -l)
6455                 [ $nums -eq $expected ] ||
6456                         error "'$cmd' wrong: found $nums, expected $expected"
6457
6458                 cmd="$LFS find $dir -atime $count${age:0:1}"
6459                 nums=$($cmd | wc -l)
6460                 [ $nums -eq $expected ] ||
6461                         error "'$cmd' wrong: found $nums, expected $expected"
6462         done
6463
6464         sleep 2
6465         cmd="$LFS find $dir -ctime +1s -type f"
6466         nums=$($cmd | wc -l)
6467         (( $nums == $count * 2 + 1)) ||
6468                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6469 }
6470 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6471
6472 test_newerXY_base() {
6473         local x=$1
6474         local y=$2
6475         local dir=$DIR/$tdir
6476         local ref
6477         local negref
6478
6479         if [ $y == "t" ]; then
6480                 if [ $x == "b" ]; then
6481                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6482                 else
6483                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6484                 fi
6485         else
6486                 ref=$DIR/$tfile.newer.$x$y
6487                 touch $ref || error "touch $ref failed"
6488         fi
6489
6490         echo "before = $ref"
6491         sleep 2
6492         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6493         sleep 2
6494         if [ $y == "t" ]; then
6495                 if [ $x == "b" ]; then
6496                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6497                 else
6498                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6499                 fi
6500         else
6501                 negref=$DIR/$tfile.negnewer.$x$y
6502                 touch $negref || error "touch $negref failed"
6503         fi
6504
6505         echo "after = $negref"
6506         local cmd="$LFS find $dir -newer$x$y $ref"
6507         local nums=$(eval $cmd | wc -l)
6508         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6509
6510         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6511                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6512
6513         cmd="$LFS find $dir ! -newer$x$y $negref"
6514         nums=$(eval $cmd | wc -l)
6515         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6516                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6517
6518         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6519         nums=$(eval $cmd | wc -l)
6520         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6521                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6522
6523         rm -rf $DIR/*
6524 }
6525
6526 test_56oc() {
6527         test_newerXY_base "a" "a"
6528         test_newerXY_base "a" "m"
6529         test_newerXY_base "a" "c"
6530         test_newerXY_base "m" "a"
6531         test_newerXY_base "m" "m"
6532         test_newerXY_base "m" "c"
6533         test_newerXY_base "c" "a"
6534         test_newerXY_base "c" "m"
6535         test_newerXY_base "c" "c"
6536
6537         [[ -n "$sles_version" ]] &&
6538                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6539
6540         test_newerXY_base "a" "t"
6541         test_newerXY_base "m" "t"
6542         test_newerXY_base "c" "t"
6543
6544         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6545            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6546                 ! btime_supported && echo "btime unsupported" && return 0
6547
6548         test_newerXY_base "b" "b"
6549         test_newerXY_base "b" "t"
6550 }
6551 run_test 56oc "check lfs find -newerXY work"
6552
6553 btime_supported() {
6554         local dir=$DIR/$tdir
6555         local rc
6556
6557         mkdir -p $dir
6558         touch $dir/$tfile
6559         $LFS find $dir -btime -1d -type f
6560         rc=$?
6561         rm -rf $dir
6562         return $rc
6563 }
6564
6565 test_56od() {
6566         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6567                 ! btime_supported && skip "btime unsupported on MDS"
6568
6569         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6570                 ! btime_supported && skip "btime unsupported on clients"
6571
6572         local dir=$DIR/$tdir
6573         local ref=$DIR/$tfile.ref
6574         local negref=$DIR/$tfile.negref
6575
6576         mkdir $dir || error "mkdir $dir failed"
6577         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6578         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6579         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6580         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6581         touch $ref || error "touch $ref failed"
6582         # sleep 3 seconds at least
6583         sleep 3
6584
6585         local before=$(do_facet mds1 date +%s)
6586         local skew=$(($(date +%s) - before + 1))
6587
6588         if (( skew < 0 && skew > -5 )); then
6589                 sleep $((0 - skew + 1))
6590                 skew=0
6591         fi
6592
6593         # Set the dir stripe params to limit files all on MDT0,
6594         # otherwise we need to calc the max clock skew between
6595         # the client and MDTs.
6596         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6597         sleep 2
6598         touch $negref || error "touch $negref failed"
6599
6600         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6601         local nums=$($cmd | wc -l)
6602         local expected=$(((NUMFILES + 1) * NUMDIRS))
6603
6604         [ $nums -eq $expected ] ||
6605                 error "'$cmd' wrong: found $nums, expected $expected"
6606
6607         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6608         nums=$($cmd | wc -l)
6609         expected=$((NUMFILES + 1))
6610         [ $nums -eq $expected ] ||
6611                 error "'$cmd' wrong: found $nums, expected $expected"
6612
6613         [ $skew -lt 0 ] && return
6614
6615         local after=$(do_facet mds1 date +%s)
6616         local age=$((after - before + 1 + skew))
6617
6618         cmd="$LFS find $dir -btime -${age}s -type f"
6619         nums=$($cmd | wc -l)
6620         expected=$(((NUMFILES + 1) * NUMDIRS))
6621
6622         echo "Clock skew between client and server: $skew, age:$age"
6623         [ $nums -eq $expected ] ||
6624                 error "'$cmd' wrong: found $nums, expected $expected"
6625
6626         expected=$(($NUMDIRS + 1))
6627         cmd="$LFS find $dir -btime -${age}s -type d"
6628         nums=$($cmd | wc -l)
6629         [ $nums -eq $expected ] ||
6630                 error "'$cmd' wrong: found $nums, expected $expected"
6631         rm -f $ref $negref || error "Failed to remove $ref $negref"
6632 }
6633 run_test 56od "check lfs find -btime with units"
6634
6635 test_56p() {
6636         [ $RUNAS_ID -eq $UID ] &&
6637                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6638
6639         local dir=$DIR/$tdir
6640
6641         setup_56 $dir $NUMFILES $NUMDIRS
6642         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6643
6644         local expected=$NUMFILES
6645         local cmd="$LFS find -uid $RUNAS_ID $dir"
6646         local nums=$($cmd | wc -l)
6647
6648         [ $nums -eq $expected ] ||
6649                 error "'$cmd' wrong: found $nums, expected $expected"
6650
6651         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6652         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6653         nums=$($cmd | wc -l)
6654         [ $nums -eq $expected ] ||
6655                 error "'$cmd' wrong: found $nums, expected $expected"
6656 }
6657 run_test 56p "check lfs find -uid and ! -uid"
6658
6659 test_56q() {
6660         [ $RUNAS_ID -eq $UID ] &&
6661                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6662
6663         local dir=$DIR/$tdir
6664
6665         setup_56 $dir $NUMFILES $NUMDIRS
6666         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6667
6668         local expected=$NUMFILES
6669         local cmd="$LFS find -gid $RUNAS_GID $dir"
6670         local nums=$($cmd | wc -l)
6671
6672         [ $nums -eq $expected ] ||
6673                 error "'$cmd' wrong: found $nums, expected $expected"
6674
6675         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6676         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6677         nums=$($cmd | wc -l)
6678         [ $nums -eq $expected ] ||
6679                 error "'$cmd' wrong: found $nums, expected $expected"
6680 }
6681 run_test 56q "check lfs find -gid and ! -gid"
6682
6683 test_56r() {
6684         local dir=$DIR/$tdir
6685
6686         setup_56 $dir $NUMFILES $NUMDIRS
6687
6688         local expected=12
6689         local cmd="$LFS find -size 0 -type f -lazy $dir"
6690         local nums=$($cmd | wc -l)
6691
6692         [ $nums -eq $expected ] ||
6693                 error "'$cmd' wrong: found $nums, expected $expected"
6694         cmd="$LFS find -size 0 -type f $dir"
6695         nums=$($cmd | wc -l)
6696         [ $nums -eq $expected ] ||
6697                 error "'$cmd' wrong: found $nums, expected $expected"
6698
6699         expected=0
6700         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6701         nums=$($cmd | wc -l)
6702         [ $nums -eq $expected ] ||
6703                 error "'$cmd' wrong: found $nums, expected $expected"
6704         cmd="$LFS find ! -size 0 -type f $dir"
6705         nums=$($cmd | wc -l)
6706         [ $nums -eq $expected ] ||
6707                 error "'$cmd' wrong: found $nums, expected $expected"
6708
6709         echo "test" > $dir/$tfile
6710         echo "test2" > $dir/$tfile.2 && sync
6711         expected=1
6712         cmd="$LFS find -size 5 -type f -lazy $dir"
6713         nums=$($cmd | wc -l)
6714         [ $nums -eq $expected ] ||
6715                 error "'$cmd' wrong: found $nums, expected $expected"
6716         cmd="$LFS find -size 5 -type f $dir"
6717         nums=$($cmd | wc -l)
6718         [ $nums -eq $expected ] ||
6719                 error "'$cmd' wrong: found $nums, expected $expected"
6720
6721         expected=1
6722         cmd="$LFS find -size +5 -type f -lazy $dir"
6723         nums=$($cmd | wc -l)
6724         [ $nums -eq $expected ] ||
6725                 error "'$cmd' wrong: found $nums, expected $expected"
6726         cmd="$LFS find -size +5 -type f $dir"
6727         nums=$($cmd | wc -l)
6728         [ $nums -eq $expected ] ||
6729                 error "'$cmd' wrong: found $nums, expected $expected"
6730
6731         expected=2
6732         cmd="$LFS find -size +0 -type f -lazy $dir"
6733         nums=$($cmd | wc -l)
6734         [ $nums -eq $expected ] ||
6735                 error "'$cmd' wrong: found $nums, expected $expected"
6736         cmd="$LFS find -size +0 -type f $dir"
6737         nums=$($cmd | wc -l)
6738         [ $nums -eq $expected ] ||
6739                 error "'$cmd' wrong: found $nums, expected $expected"
6740
6741         expected=2
6742         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6743         nums=$($cmd | wc -l)
6744         [ $nums -eq $expected ] ||
6745                 error "'$cmd' wrong: found $nums, expected $expected"
6746         cmd="$LFS find ! -size -5 -type f $dir"
6747         nums=$($cmd | wc -l)
6748         [ $nums -eq $expected ] ||
6749                 error "'$cmd' wrong: found $nums, expected $expected"
6750
6751         expected=12
6752         cmd="$LFS find -size -5 -type f -lazy $dir"
6753         nums=$($cmd | wc -l)
6754         [ $nums -eq $expected ] ||
6755                 error "'$cmd' wrong: found $nums, expected $expected"
6756         cmd="$LFS find -size -5 -type f $dir"
6757         nums=$($cmd | wc -l)
6758         [ $nums -eq $expected ] ||
6759                 error "'$cmd' wrong: found $nums, expected $expected"
6760 }
6761 run_test 56r "check lfs find -size works"
6762
6763 test_56ra_sub() {
6764         local expected=$1
6765         local glimpses=$2
6766         local cmd="$3"
6767
6768         cancel_lru_locks $OSC
6769
6770         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6771         local nums=$($cmd | wc -l)
6772
6773         [ $nums -eq $expected ] ||
6774                 error "'$cmd' wrong: found $nums, expected $expected"
6775
6776         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6777
6778         if (( rpcs_before + glimpses != rpcs_after )); then
6779                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6780                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6781
6782                 if [[ $glimpses == 0 ]]; then
6783                         error "'$cmd' should not send glimpse RPCs to OST"
6784                 else
6785                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6786                 fi
6787         fi
6788 }
6789
6790 test_56ra() {
6791         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6792                 skip "MDS < 2.12.58 doesn't return LSOM data"
6793         local dir=$DIR/$tdir
6794         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6795
6796         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6797
6798         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6799         $LCTL set_param -n llite.*.statahead_agl=0
6800         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6801
6802         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6803         # open and close all files to ensure LSOM is updated
6804         cancel_lru_locks $OSC
6805         find $dir -type f | xargs cat > /dev/null
6806
6807         #   expect_found  glimpse_rpcs  command_to_run
6808         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6809         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6810         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6811         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6812
6813         echo "test" > $dir/$tfile
6814         echo "test2" > $dir/$tfile.2 && sync
6815         cancel_lru_locks $OSC
6816         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6817
6818         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6819         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6820         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6821         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6822
6823         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6824         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6825         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6826         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6827         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6828         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6829 }
6830 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6831
6832 test_56rb() {
6833         local dir=$DIR/$tdir
6834         local tmp=$TMP/$tfile.log
6835         local mdt_idx;
6836
6837         test_mkdir -p $dir || error "failed to mkdir $dir"
6838         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6839                 error "failed to setstripe $dir/$tfile"
6840         mdt_idx=$($LFS getdirstripe -i $dir)
6841         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6842
6843         stack_trap "rm -f $tmp" EXIT
6844         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6845         ! grep -q obd_uuid $tmp ||
6846                 error "failed to find --size +100K --ost 0 $dir"
6847         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6848         ! grep -q obd_uuid $tmp ||
6849                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6850 }
6851 run_test 56rb "check lfs find --size --ost/--mdt works"
6852
6853 test_56rc() {
6854         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6855         local dir=$DIR/$tdir
6856         local found
6857
6858         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6859         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6860         (( $MDSCOUNT > 2 )) &&
6861                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6862         mkdir $dir/$tdir-{1..10}
6863         touch $dir/$tfile-{1..10}
6864
6865         found=$($LFS find $dir --mdt-count 2 | wc -l)
6866         expect=11
6867         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6868
6869         found=$($LFS find $dir -T +1 | wc -l)
6870         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6871         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6872
6873         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6874         expect=11
6875         (( $found == $expect )) || error "found $found all_char, expect $expect"
6876
6877         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
6878         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
6879         (( $found == $expect )) || error "found $found all_char, expect $expect"
6880 }
6881 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
6882
6883 test_56s() { # LU-611 #LU-9369
6884         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6885
6886         local dir=$DIR/$tdir
6887         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6888
6889         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6890         for i in $(seq $NUMDIRS); do
6891                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6892         done
6893
6894         local expected=$NUMDIRS
6895         local cmd="$LFS find -c $OSTCOUNT $dir"
6896         local nums=$($cmd | wc -l)
6897
6898         [ $nums -eq $expected ] || {
6899                 $LFS getstripe -R $dir
6900                 error "'$cmd' wrong: found $nums, expected $expected"
6901         }
6902
6903         expected=$((NUMDIRS + onestripe))
6904         cmd="$LFS find -stripe-count +0 -type f $dir"
6905         nums=$($cmd | wc -l)
6906         [ $nums -eq $expected ] || {
6907                 $LFS getstripe -R $dir
6908                 error "'$cmd' wrong: found $nums, expected $expected"
6909         }
6910
6911         expected=$onestripe
6912         cmd="$LFS find -stripe-count 1 -type f $dir"
6913         nums=$($cmd | wc -l)
6914         [ $nums -eq $expected ] || {
6915                 $LFS getstripe -R $dir
6916                 error "'$cmd' wrong: found $nums, expected $expected"
6917         }
6918
6919         cmd="$LFS find -stripe-count -2 -type f $dir"
6920         nums=$($cmd | wc -l)
6921         [ $nums -eq $expected ] || {
6922                 $LFS getstripe -R $dir
6923                 error "'$cmd' wrong: found $nums, expected $expected"
6924         }
6925
6926         expected=0
6927         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6928         nums=$($cmd | wc -l)
6929         [ $nums -eq $expected ] || {
6930                 $LFS getstripe -R $dir
6931                 error "'$cmd' wrong: found $nums, expected $expected"
6932         }
6933 }
6934 run_test 56s "check lfs find -stripe-count works"
6935
6936 test_56t() { # LU-611 #LU-9369
6937         local dir=$DIR/$tdir
6938
6939         setup_56 $dir 0 $NUMDIRS
6940         for i in $(seq $NUMDIRS); do
6941                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6942         done
6943
6944         local expected=$NUMDIRS
6945         local cmd="$LFS find -S 8M $dir"
6946         local nums=$($cmd | wc -l)
6947
6948         [ $nums -eq $expected ] || {
6949                 $LFS getstripe -R $dir
6950                 error "'$cmd' wrong: found $nums, expected $expected"
6951         }
6952         rm -rf $dir
6953
6954         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6955
6956         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6957
6958         expected=$(((NUMDIRS + 1) * NUMFILES))
6959         cmd="$LFS find -stripe-size 512k -type f $dir"
6960         nums=$($cmd | wc -l)
6961         [ $nums -eq $expected ] ||
6962                 error "'$cmd' wrong: found $nums, expected $expected"
6963
6964         cmd="$LFS find -stripe-size +320k -type f $dir"
6965         nums=$($cmd | wc -l)
6966         [ $nums -eq $expected ] ||
6967                 error "'$cmd' wrong: found $nums, expected $expected"
6968
6969         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6970         cmd="$LFS find -stripe-size +200k -type f $dir"
6971         nums=$($cmd | wc -l)
6972         [ $nums -eq $expected ] ||
6973                 error "'$cmd' wrong: found $nums, expected $expected"
6974
6975         cmd="$LFS find -stripe-size -640k -type f $dir"
6976         nums=$($cmd | wc -l)
6977         [ $nums -eq $expected ] ||
6978                 error "'$cmd' wrong: found $nums, expected $expected"
6979
6980         expected=4
6981         cmd="$LFS find -stripe-size 256k -type f $dir"
6982         nums=$($cmd | wc -l)
6983         [ $nums -eq $expected ] ||
6984                 error "'$cmd' wrong: found $nums, expected $expected"
6985
6986         cmd="$LFS find -stripe-size -320k -type f $dir"
6987         nums=$($cmd | wc -l)
6988         [ $nums -eq $expected ] ||
6989                 error "'$cmd' wrong: found $nums, expected $expected"
6990
6991         expected=0
6992         cmd="$LFS find -stripe-size 1024k -type f $dir"
6993         nums=$($cmd | wc -l)
6994         [ $nums -eq $expected ] ||
6995                 error "'$cmd' wrong: found $nums, expected $expected"
6996 }
6997 run_test 56t "check lfs find -stripe-size works"
6998
6999 test_56u() { # LU-611
7000         local dir=$DIR/$tdir
7001
7002         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7003
7004         if [[ $OSTCOUNT -gt 1 ]]; then
7005                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7006                 onestripe=4
7007         else
7008                 onestripe=0
7009         fi
7010
7011         local expected=$(((NUMDIRS + 1) * NUMFILES))
7012         local cmd="$LFS find -stripe-index 0 -type f $dir"
7013         local nums=$($cmd | wc -l)
7014
7015         [ $nums -eq $expected ] ||
7016                 error "'$cmd' wrong: found $nums, expected $expected"
7017
7018         expected=$onestripe
7019         cmd="$LFS find -stripe-index 1 -type f $dir"
7020         nums=$($cmd | wc -l)
7021         [ $nums -eq $expected ] ||
7022                 error "'$cmd' wrong: found $nums, expected $expected"
7023
7024         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7025         nums=$($cmd | wc -l)
7026         [ $nums -eq $expected ] ||
7027                 error "'$cmd' wrong: found $nums, expected $expected"
7028
7029         expected=0
7030         # This should produce an error and not return any files
7031         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7032         nums=$($cmd 2>/dev/null | wc -l)
7033         [ $nums -eq $expected ] ||
7034                 error "'$cmd' wrong: found $nums, expected $expected"
7035
7036         if [[ $OSTCOUNT -gt 1 ]]; then
7037                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7038                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7039                 nums=$($cmd | wc -l)
7040                 [ $nums -eq $expected ] ||
7041                         error "'$cmd' wrong: found $nums, expected $expected"
7042         fi
7043 }
7044 run_test 56u "check lfs find -stripe-index works"
7045
7046 test_56v() {
7047         local mdt_idx=0
7048         local dir=$DIR/$tdir
7049
7050         setup_56 $dir $NUMFILES $NUMDIRS
7051
7052         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7053         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7054
7055         for file in $($LFS find -m $UUID $dir); do
7056                 file_midx=$($LFS getstripe -m $file)
7057                 [ $file_midx -eq $mdt_idx ] ||
7058                         error "lfs find -m $UUID != getstripe -m $file_midx"
7059         done
7060 }
7061 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7062
7063 test_56w() {
7064         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7066
7067         local dir=$DIR/$tdir
7068
7069         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7070
7071         local stripe_size=$($LFS getstripe -S -d $dir) ||
7072                 error "$LFS getstripe -S -d $dir failed"
7073         stripe_size=${stripe_size%% *}
7074
7075         local file_size=$((stripe_size * OSTCOUNT))
7076         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7077         local required_space=$((file_num * file_size))
7078         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7079                            head -n1)
7080         [[ $free_space -le $((required_space / 1024)) ]] &&
7081                 skip_env "need $required_space, have $free_space kbytes"
7082
7083         local dd_bs=65536
7084         local dd_count=$((file_size / dd_bs))
7085
7086         # write data into the files
7087         local i
7088         local j
7089         local file
7090
7091         for i in $(seq $NUMFILES); do
7092                 file=$dir/file$i
7093                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7094                         error "write data into $file failed"
7095         done
7096         for i in $(seq $NUMDIRS); do
7097                 for j in $(seq $NUMFILES); do
7098                         file=$dir/dir$i/file$j
7099                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7100                                 error "write data into $file failed"
7101                 done
7102         done
7103
7104         # $LFS_MIGRATE will fail if hard link migration is unsupported
7105         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7106                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7107                         error "creating links to $dir/dir1/file1 failed"
7108         fi
7109
7110         local expected=-1
7111
7112         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7113
7114         # lfs_migrate file
7115         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7116
7117         echo "$cmd"
7118         eval $cmd || error "$cmd failed"
7119
7120         check_stripe_count $dir/file1 $expected
7121
7122         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7123         then
7124                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7125                 # OST 1 if it is on OST 0. This file is small enough to
7126                 # be on only one stripe.
7127                 file=$dir/migr_1_ost
7128                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7129                         error "write data into $file failed"
7130                 local obdidx=$($LFS getstripe -i $file)
7131                 local oldmd5=$(md5sum $file)
7132                 local newobdidx=0
7133
7134                 [[ $obdidx -eq 0 ]] && newobdidx=1
7135                 cmd="$LFS migrate -i $newobdidx $file"
7136                 echo $cmd
7137                 eval $cmd || error "$cmd failed"
7138
7139                 local realobdix=$($LFS getstripe -i $file)
7140                 local newmd5=$(md5sum $file)
7141
7142                 [[ $newobdidx -ne $realobdix ]] &&
7143                         error "new OST is different (was=$obdidx, "\
7144                               "wanted=$newobdidx, got=$realobdix)"
7145                 [[ "$oldmd5" != "$newmd5" ]] &&
7146                         error "md5sum differ: $oldmd5, $newmd5"
7147         fi
7148
7149         # lfs_migrate dir
7150         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7151         echo "$cmd"
7152         eval $cmd || error "$cmd failed"
7153
7154         for j in $(seq $NUMFILES); do
7155                 check_stripe_count $dir/dir1/file$j $expected
7156         done
7157
7158         # lfs_migrate works with lfs find
7159         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7160              $LFS_MIGRATE -y -c $expected"
7161         echo "$cmd"
7162         eval $cmd || error "$cmd failed"
7163
7164         for i in $(seq 2 $NUMFILES); do
7165                 check_stripe_count $dir/file$i $expected
7166         done
7167         for i in $(seq 2 $NUMDIRS); do
7168                 for j in $(seq $NUMFILES); do
7169                 check_stripe_count $dir/dir$i/file$j $expected
7170                 done
7171         done
7172 }
7173 run_test 56w "check lfs_migrate -c stripe_count works"
7174
7175 test_56wb() {
7176         local file1=$DIR/$tdir/file1
7177         local create_pool=false
7178         local initial_pool=$($LFS getstripe -p $DIR)
7179         local pool_list=()
7180         local pool=""
7181
7182         echo -n "Creating test dir..."
7183         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7184         echo "done."
7185
7186         echo -n "Creating test file..."
7187         touch $file1 || error "cannot create file"
7188         echo "done."
7189
7190         echo -n "Detecting existing pools..."
7191         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7192
7193         if [ ${#pool_list[@]} -gt 0 ]; then
7194                 echo "${pool_list[@]}"
7195                 for thispool in "${pool_list[@]}"; do
7196                         if [[ -z "$initial_pool" ||
7197                               "$initial_pool" != "$thispool" ]]; then
7198                                 pool="$thispool"
7199                                 echo "Using existing pool '$pool'"
7200                                 break
7201                         fi
7202                 done
7203         else
7204                 echo "none detected."
7205         fi
7206         if [ -z "$pool" ]; then
7207                 pool=${POOL:-testpool}
7208                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7209                 echo -n "Creating pool '$pool'..."
7210                 create_pool=true
7211                 pool_add $pool &> /dev/null ||
7212                         error "pool_add failed"
7213                 echo "done."
7214
7215                 echo -n "Adding target to pool..."
7216                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7217                         error "pool_add_targets failed"
7218                 echo "done."
7219         fi
7220
7221         echo -n "Setting pool using -p option..."
7222         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7223                 error "migrate failed rc = $?"
7224         echo "done."
7225
7226         echo -n "Verifying test file is in pool after migrating..."
7227         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7228                 error "file was not migrated to pool $pool"
7229         echo "done."
7230
7231         echo -n "Removing test file from pool '$pool'..."
7232         # "lfs migrate $file" won't remove the file from the pool
7233         # until some striping information is changed.
7234         $LFS migrate -c 1 $file1 &> /dev/null ||
7235                 error "cannot remove from pool"
7236         [ "$($LFS getstripe -p $file1)" ] &&
7237                 error "pool still set"
7238         echo "done."
7239
7240         echo -n "Setting pool using --pool option..."
7241         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7242                 error "migrate failed rc = $?"
7243         echo "done."
7244
7245         # Clean up
7246         rm -f $file1
7247         if $create_pool; then
7248                 destroy_test_pools 2> /dev/null ||
7249                         error "destroy test pools failed"
7250         fi
7251 }
7252 run_test 56wb "check lfs_migrate pool support"
7253
7254 test_56wc() {
7255         local file1="$DIR/$tdir/file1"
7256         local parent_ssize
7257         local parent_scount
7258         local cur_ssize
7259         local cur_scount
7260         local orig_ssize
7261
7262         echo -n "Creating test dir..."
7263         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7264         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7265                 error "cannot set stripe by '-S 1M -c 1'"
7266         echo "done"
7267
7268         echo -n "Setting initial stripe for test file..."
7269         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7270                 error "cannot set stripe"
7271         cur_ssize=$($LFS getstripe -S "$file1")
7272         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7273         echo "done."
7274
7275         # File currently set to -S 512K -c 1
7276
7277         # Ensure -c and -S options are rejected when -R is set
7278         echo -n "Verifying incompatible options are detected..."
7279         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7280                 error "incompatible -c and -R options not detected"
7281         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7282                 error "incompatible -S and -R options not detected"
7283         echo "done."
7284
7285         # Ensure unrecognized options are passed through to 'lfs migrate'
7286         echo -n "Verifying -S option is passed through to lfs migrate..."
7287         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7288                 error "migration failed"
7289         cur_ssize=$($LFS getstripe -S "$file1")
7290         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7291         echo "done."
7292
7293         # File currently set to -S 1M -c 1
7294
7295         # Ensure long options are supported
7296         echo -n "Verifying long options supported..."
7297         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7298                 error "long option without argument not supported"
7299         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7300                 error "long option with argument not supported"
7301         cur_ssize=$($LFS getstripe -S "$file1")
7302         [ $cur_ssize -eq 524288 ] ||
7303                 error "migrate --stripe-size $cur_ssize != 524288"
7304         echo "done."
7305
7306         # File currently set to -S 512K -c 1
7307
7308         if [ "$OSTCOUNT" -gt 1 ]; then
7309                 echo -n "Verifying explicit stripe count can be set..."
7310                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7311                         error "migrate failed"
7312                 cur_scount=$($LFS getstripe -c "$file1")
7313                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7314                 echo "done."
7315         fi
7316
7317         # File currently set to -S 512K -c 1 or -S 512K -c 2
7318
7319         # Ensure parent striping is used if -R is set, and no stripe
7320         # count or size is specified
7321         echo -n "Setting stripe for parent directory..."
7322         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7323                 error "cannot set stripe '-S 2M -c 1'"
7324         echo "done."
7325
7326         echo -n "Verifying restripe option uses parent stripe settings..."
7327         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7328         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7329         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7330                 error "migrate failed"
7331         cur_ssize=$($LFS getstripe -S "$file1")
7332         [ $cur_ssize -eq $parent_ssize ] ||
7333                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7334         cur_scount=$($LFS getstripe -c "$file1")
7335         [ $cur_scount -eq $parent_scount ] ||
7336                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7337         echo "done."
7338
7339         # File currently set to -S 1M -c 1
7340
7341         # Ensure striping is preserved if -R is not set, and no stripe
7342         # count or size is specified
7343         echo -n "Verifying striping size preserved when not specified..."
7344         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7345         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7346                 error "cannot set stripe on parent directory"
7347         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7348                 error "migrate failed"
7349         cur_ssize=$($LFS getstripe -S "$file1")
7350         [ $cur_ssize -eq $orig_ssize ] ||
7351                 error "migrate by default $cur_ssize != $orig_ssize"
7352         echo "done."
7353
7354         # Ensure file name properly detected when final option has no argument
7355         echo -n "Verifying file name properly detected..."
7356         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7357                 error "file name interpreted as option argument"
7358         echo "done."
7359
7360         # Clean up
7361         rm -f "$file1"
7362 }
7363 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7364
7365 test_56wd() {
7366         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7367
7368         local file1=$DIR/$tdir/file1
7369
7370         echo -n "Creating test dir..."
7371         test_mkdir $DIR/$tdir || error "cannot create dir"
7372         echo "done."
7373
7374         echo -n "Creating test file..."
7375         touch $file1
7376         echo "done."
7377
7378         # Ensure 'lfs migrate' will fail by using a non-existent option,
7379         # and make sure rsync is not called to recover
7380         echo -n "Make sure --no-rsync option works..."
7381         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7382                 grep -q 'refusing to fall back to rsync' ||
7383                 error "rsync was called with --no-rsync set"
7384         echo "done."
7385
7386         # Ensure rsync is called without trying 'lfs migrate' first
7387         echo -n "Make sure --rsync option works..."
7388         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7389                 grep -q 'falling back to rsync' &&
7390                 error "lfs migrate was called with --rsync set"
7391         echo "done."
7392
7393         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7394         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7395                 grep -q 'at the same time' ||
7396                 error "--rsync and --no-rsync accepted concurrently"
7397         echo "done."
7398
7399         # Clean up
7400         rm -f $file1
7401 }
7402 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7403
7404 test_56we() {
7405         local td=$DIR/$tdir
7406         local tf=$td/$tfile
7407
7408         test_mkdir $td || error "cannot create $td"
7409         touch $tf || error "cannot touch $tf"
7410
7411         echo -n "Make sure --non-direct|-D works..."
7412         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7413                 grep -q "lfs migrate --non-direct" ||
7414                 error "--non-direct option cannot work correctly"
7415         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7416                 grep -q "lfs migrate -D" ||
7417                 error "-D option cannot work correctly"
7418         echo "done."
7419 }
7420 run_test 56we "check lfs_migrate --non-direct|-D support"
7421
7422 test_56x() {
7423         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7424         check_swap_layouts_support
7425
7426         local dir=$DIR/$tdir
7427         local ref1=/etc/passwd
7428         local file1=$dir/file1
7429
7430         test_mkdir $dir || error "creating dir $dir"
7431         $LFS setstripe -c 2 $file1
7432         cp $ref1 $file1
7433         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7434         stripe=$($LFS getstripe -c $file1)
7435         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7436         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7437
7438         # clean up
7439         rm -f $file1
7440 }
7441 run_test 56x "lfs migration support"
7442
7443 test_56xa() {
7444         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7445         check_swap_layouts_support
7446
7447         local dir=$DIR/$tdir/$testnum
7448
7449         test_mkdir -p $dir
7450
7451         local ref1=/etc/passwd
7452         local file1=$dir/file1
7453
7454         $LFS setstripe -c 2 $file1
7455         cp $ref1 $file1
7456         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7457
7458         local stripe=$($LFS getstripe -c $file1)
7459
7460         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7461         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7462
7463         # clean up
7464         rm -f $file1
7465 }
7466 run_test 56xa "lfs migration --block support"
7467
7468 check_migrate_links() {
7469         local dir="$1"
7470         local file1="$dir/file1"
7471         local begin="$2"
7472         local count="$3"
7473         local runas="$4"
7474         local total_count=$(($begin + $count - 1))
7475         local symlink_count=10
7476         local uniq_count=10
7477
7478         if [ ! -f "$file1" ]; then
7479                 echo -n "creating initial file..."
7480                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7481                         error "cannot setstripe initial file"
7482                 echo "done"
7483
7484                 echo -n "creating symlinks..."
7485                 for s in $(seq 1 $symlink_count); do
7486                         ln -s "$file1" "$dir/slink$s" ||
7487                                 error "cannot create symlinks"
7488                 done
7489                 echo "done"
7490
7491                 echo -n "creating nonlinked files..."
7492                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7493                         error "cannot create nonlinked files"
7494                 echo "done"
7495         fi
7496
7497         # create hard links
7498         if [ ! -f "$dir/file$total_count" ]; then
7499                 echo -n "creating hard links $begin:$total_count..."
7500                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7501                         /dev/null || error "cannot create hard links"
7502                 echo "done"
7503         fi
7504
7505         echo -n "checking number of hard links listed in xattrs..."
7506         local fid=$($LFS getstripe -F "$file1")
7507         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7508
7509         echo "${#paths[*]}"
7510         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7511                         skip "hard link list has unexpected size, skipping test"
7512         fi
7513         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7514                         error "link names should exceed xattrs size"
7515         fi
7516
7517         echo -n "migrating files..."
7518         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7519         local rc=$?
7520         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7521         echo "done"
7522
7523         # make sure all links have been properly migrated
7524         echo -n "verifying files..."
7525         fid=$($LFS getstripe -F "$file1") ||
7526                 error "cannot get fid for file $file1"
7527         for i in $(seq 2 $total_count); do
7528                 local fid2=$($LFS getstripe -F $dir/file$i)
7529
7530                 [ "$fid2" == "$fid" ] ||
7531                         error "migrated hard link has mismatched FID"
7532         done
7533
7534         # make sure hard links were properly detected, and migration was
7535         # performed only once for the entire link set; nonlinked files should
7536         # also be migrated
7537         local actual=$(grep -c 'done' <<< "$migrate_out")
7538         local expected=$(($uniq_count + 1))
7539
7540         [ "$actual" -eq  "$expected" ] ||
7541                 error "hard links individually migrated ($actual != $expected)"
7542
7543         # make sure the correct number of hard links are present
7544         local hardlinks=$(stat -c '%h' "$file1")
7545
7546         [ $hardlinks -eq $total_count ] ||
7547                 error "num hard links $hardlinks != $total_count"
7548         echo "done"
7549
7550         return 0
7551 }
7552
7553 test_56xb() {
7554         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7555                 skip "Need MDS version at least 2.10.55"
7556
7557         local dir="$DIR/$tdir"
7558
7559         test_mkdir "$dir" || error "cannot create dir $dir"
7560
7561         echo "testing lfs migrate mode when all links fit within xattrs"
7562         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7563
7564         echo "testing rsync mode when all links fit within xattrs"
7565         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7566
7567         echo "testing lfs migrate mode when all links do not fit within xattrs"
7568         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7569
7570         echo "testing rsync mode when all links do not fit within xattrs"
7571         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7572
7573         chown -R $RUNAS_ID $dir
7574         echo "testing non-root lfs migrate mode when not all links are in xattr"
7575         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7576
7577         # clean up
7578         rm -rf $dir
7579 }
7580 run_test 56xb "lfs migration hard link support"
7581
7582 test_56xc() {
7583         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7584
7585         local dir="$DIR/$tdir"
7586
7587         test_mkdir "$dir" || error "cannot create dir $dir"
7588
7589         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7590         echo -n "Setting initial stripe for 20MB test file..."
7591         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7592                 error "cannot setstripe 20MB file"
7593         echo "done"
7594         echo -n "Sizing 20MB test file..."
7595         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7596         echo "done"
7597         echo -n "Verifying small file autostripe count is 1..."
7598         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7599                 error "cannot migrate 20MB file"
7600         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7601                 error "cannot get stripe for $dir/20mb"
7602         [ $stripe_count -eq 1 ] ||
7603                 error "unexpected stripe count $stripe_count for 20MB file"
7604         rm -f "$dir/20mb"
7605         echo "done"
7606
7607         # Test 2: File is small enough to fit within the available space on
7608         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7609         # have at least an additional 1KB for each desired stripe for test 3
7610         echo -n "Setting stripe for 1GB test file..."
7611         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7612         echo "done"
7613         echo -n "Sizing 1GB test file..."
7614         # File size is 1GB + 3KB
7615         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7616         echo "done"
7617
7618         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7619         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7620         if (( avail > 524288 * OSTCOUNT )); then
7621                 echo -n "Migrating 1GB file..."
7622                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7623                         error "cannot migrate 1GB file"
7624                 echo "done"
7625                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7626                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7627                         error "cannot getstripe for 1GB file"
7628                 [ $stripe_count -eq 2 ] ||
7629                         error "unexpected stripe count $stripe_count != 2"
7630                 echo "done"
7631         fi
7632
7633         # Test 3: File is too large to fit within the available space on
7634         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7635         if [ $OSTCOUNT -ge 3 ]; then
7636                 # The required available space is calculated as
7637                 # file size (1GB + 3KB) / OST count (3).
7638                 local kb_per_ost=349526
7639
7640                 echo -n "Migrating 1GB file with limit..."
7641                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7642                         error "cannot migrate 1GB file with limit"
7643                 echo "done"
7644
7645                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7646                 echo -n "Verifying 1GB autostripe count with limited space..."
7647                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7648                         error "unexpected stripe count $stripe_count (min 3)"
7649                 echo "done"
7650         fi
7651
7652         # clean up
7653         rm -rf $dir
7654 }
7655 run_test 56xc "lfs migration autostripe"
7656
7657 test_56xd() {
7658         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7659
7660         local dir=$DIR/$tdir
7661         local f_mgrt=$dir/$tfile.mgrt
7662         local f_yaml=$dir/$tfile.yaml
7663         local f_copy=$dir/$tfile.copy
7664         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7665         local layout_copy="-c 2 -S 2M -i 1"
7666         local yamlfile=$dir/yamlfile
7667         local layout_before;
7668         local layout_after;
7669
7670         test_mkdir "$dir" || error "cannot create dir $dir"
7671         $LFS setstripe $layout_yaml $f_yaml ||
7672                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7673         $LFS getstripe --yaml $f_yaml > $yamlfile
7674         $LFS setstripe $layout_copy $f_copy ||
7675                 error "cannot setstripe $f_copy with layout $layout_copy"
7676         touch $f_mgrt
7677         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7678
7679         # 1. test option --yaml
7680         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7681                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7682         layout_before=$(get_layout_param $f_yaml)
7683         layout_after=$(get_layout_param $f_mgrt)
7684         [ "$layout_after" == "$layout_before" ] ||
7685                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7686
7687         # 2. test option --copy
7688         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7689                 error "cannot migrate $f_mgrt with --copy $f_copy"
7690         layout_before=$(get_layout_param $f_copy)
7691         layout_after=$(get_layout_param $f_mgrt)
7692         [ "$layout_after" == "$layout_before" ] ||
7693                 error "lfs_migrate --copy: $layout_after != $layout_before"
7694 }
7695 run_test 56xd "check lfs_migrate --yaml and --copy support"
7696
7697 test_56xe() {
7698         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7699
7700         local dir=$DIR/$tdir
7701         local f_comp=$dir/$tfile
7702         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7703         local layout_before=""
7704         local layout_after=""
7705
7706         test_mkdir "$dir" || error "cannot create dir $dir"
7707         $LFS setstripe $layout $f_comp ||
7708                 error "cannot setstripe $f_comp with layout $layout"
7709         layout_before=$(get_layout_param $f_comp)
7710         dd if=/dev/zero of=$f_comp bs=1M count=4
7711
7712         # 1. migrate a comp layout file by lfs_migrate
7713         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7714         layout_after=$(get_layout_param $f_comp)
7715         [ "$layout_before" == "$layout_after" ] ||
7716                 error "lfs_migrate: $layout_before != $layout_after"
7717
7718         # 2. migrate a comp layout file by lfs migrate
7719         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7720         layout_after=$(get_layout_param $f_comp)
7721         [ "$layout_before" == "$layout_after" ] ||
7722                 error "lfs migrate: $layout_before != $layout_after"
7723 }
7724 run_test 56xe "migrate a composite layout file"
7725
7726 test_56xf() {
7727         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7728
7729         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7730                 skip "Need server version at least 2.13.53"
7731
7732         local dir=$DIR/$tdir
7733         local f_comp=$dir/$tfile
7734         local layout="-E 1M -c1 -E -1 -c2"
7735         local fid_before=""
7736         local fid_after=""
7737
7738         test_mkdir "$dir" || error "cannot create dir $dir"
7739         $LFS setstripe $layout $f_comp ||
7740                 error "cannot setstripe $f_comp with layout $layout"
7741         fid_before=$($LFS getstripe --fid $f_comp)
7742         dd if=/dev/zero of=$f_comp bs=1M count=4
7743
7744         # 1. migrate a comp layout file to a comp layout
7745         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7746         fid_after=$($LFS getstripe --fid $f_comp)
7747         [ "$fid_before" == "$fid_after" ] ||
7748                 error "comp-to-comp migrate: $fid_before != $fid_after"
7749
7750         # 2. migrate a comp layout file to a plain layout
7751         $LFS migrate -c2 $f_comp ||
7752                 error "cannot migrate $f_comp by lfs migrate"
7753         fid_after=$($LFS getstripe --fid $f_comp)
7754         [ "$fid_before" == "$fid_after" ] ||
7755                 error "comp-to-plain migrate: $fid_before != $fid_after"
7756
7757         # 3. migrate a plain layout file to a comp layout
7758         $LFS migrate $layout $f_comp ||
7759                 error "cannot migrate $f_comp by lfs migrate"
7760         fid_after=$($LFS getstripe --fid $f_comp)
7761         [ "$fid_before" == "$fid_after" ] ||
7762                 error "plain-to-comp migrate: $fid_before != $fid_after"
7763 }
7764 run_test 56xf "FID is not lost during migration of a composite layout file"
7765
7766 check_file_ost_range() {
7767         local file="$1"
7768         shift
7769         local range="$*"
7770         local -a file_range
7771         local idx
7772
7773         file_range=($($LFS getstripe -y "$file" |
7774                 awk '/l_ost_idx:/ { print $NF }'))
7775
7776         if [[ "${#file_range[@]}" = 0 ]]; then
7777                 echo "No osts found for $file"
7778                 return 1
7779         fi
7780
7781         for idx in "${file_range[@]}"; do
7782                 [[ " $range " =~ " $idx " ]] ||
7783                         return 1
7784         done
7785
7786         return 0
7787 }
7788
7789 sub_test_56xg() {
7790         local stripe_opt="$1"
7791         local pool="$2"
7792         shift 2
7793         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7794
7795         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7796                 error "Fail to migrate $tfile on $pool"
7797         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7798                 error "$tfile is not in pool $pool"
7799         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7800                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7801 }
7802
7803 test_56xg() {
7804         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7805         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7806         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7807                 skip "Need MDS version newer than 2.14.52"
7808
7809         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7810         local -a pool_ranges=("0 0" "1 1" "0 1")
7811
7812         # init pools
7813         for i in "${!pool_names[@]}"; do
7814                 pool_add ${pool_names[$i]} ||
7815                         error "pool_add failed (pool: ${pool_names[$i]})"
7816                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7817                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7818         done
7819
7820         # init the file to migrate
7821         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7822                 error "Unable to create $tfile on OST1"
7823         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7824                 error "Unable to write on $tfile"
7825
7826         echo "1. migrate $tfile on pool ${pool_names[0]}"
7827         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7828
7829         echo "2. migrate $tfile on pool ${pool_names[2]}"
7830         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7831
7832         echo "3. migrate $tfile on pool ${pool_names[1]}"
7833         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7834
7835         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7836         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7837         echo
7838
7839         # Clean pools
7840         destroy_test_pools ||
7841                 error "pool_destroy failed"
7842 }
7843 run_test 56xg "lfs migrate pool support"
7844
7845 test_56y() {
7846         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7847                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7848
7849         local res=""
7850         local dir=$DIR/$tdir
7851         local f1=$dir/file1
7852         local f2=$dir/file2
7853
7854         test_mkdir -p $dir || error "creating dir $dir"
7855         touch $f1 || error "creating std file $f1"
7856         $MULTIOP $f2 H2c || error "creating released file $f2"
7857
7858         # a directory can be raid0, so ask only for files
7859         res=$($LFS find $dir -L raid0 -type f | wc -l)
7860         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7861
7862         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7863         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7864
7865         # only files can be released, so no need to force file search
7866         res=$($LFS find $dir -L released)
7867         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7868
7869         res=$($LFS find $dir -type f \! -L released)
7870         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7871 }
7872 run_test 56y "lfs find -L raid0|released"
7873
7874 test_56z() { # LU-4824
7875         # This checks to make sure 'lfs find' continues after errors
7876         # There are two classes of errors that should be caught:
7877         # - If multiple paths are provided, all should be searched even if one
7878         #   errors out
7879         # - If errors are encountered during the search, it should not terminate
7880         #   early
7881         local dir=$DIR/$tdir
7882         local i
7883
7884         test_mkdir $dir
7885         for i in d{0..9}; do
7886                 test_mkdir $dir/$i
7887                 touch $dir/$i/$tfile
7888         done
7889         $LFS find $DIR/non_existent_dir $dir &&
7890                 error "$LFS find did not return an error"
7891         # Make a directory unsearchable. This should NOT be the last entry in
7892         # directory order.  Arbitrarily pick the 6th entry
7893         chmod 700 $($LFS find $dir -type d | sed '6!d')
7894
7895         $RUNAS $LFS find $DIR/non_existent $dir
7896         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7897
7898         # The user should be able to see 10 directories and 9 files
7899         (( count == 19 )) ||
7900                 error "$LFS find found $count != 19 entries after error"
7901 }
7902 run_test 56z "lfs find should continue after an error"
7903
7904 test_56aa() { # LU-5937
7905         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7906
7907         local dir=$DIR/$tdir
7908
7909         mkdir $dir
7910         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7911
7912         createmany -o $dir/striped_dir/${tfile}- 1024
7913         local dirs=$($LFS find --size +8k $dir/)
7914
7915         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7916 }
7917 run_test 56aa "lfs find --size under striped dir"
7918
7919 test_56ab() { # LU-10705
7920         test_mkdir $DIR/$tdir
7921         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7922         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7923         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7924         # Flush writes to ensure valid blocks.  Need to be more thorough for
7925         # ZFS, since blocks are not allocated/returned to client immediately.
7926         sync_all_data
7927         wait_zfs_commit ost1 2
7928         cancel_lru_locks osc
7929         ls -ls $DIR/$tdir
7930
7931         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7932
7933         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7934
7935         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7936         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7937
7938         rm -f $DIR/$tdir/$tfile.[123]
7939 }
7940 run_test 56ab "lfs find --blocks"
7941
7942 # LU-11188
7943 test_56aca() {
7944         local dir="$DIR/$tdir"
7945         local perms=(001 002 003 004 005 006 007
7946                      010 020 030 040 050 060 070
7947                      100 200 300 400 500 600 700
7948                      111 222 333 444 555 666 777)
7949         local perm_minus=(8 8 4 8 4 4 2
7950                           8 8 4 8 4 4 2
7951                           8 8 4 8 4 4 2
7952                           4 4 2 4 2 2 1)
7953         local perm_slash=(8  8 12  8 12 12 14
7954                           8  8 12  8 12 12 14
7955                           8  8 12  8 12 12 14
7956                          16 16 24 16 24 24 28)
7957
7958         test_mkdir "$dir"
7959         for perm in ${perms[*]}; do
7960                 touch "$dir/$tfile.$perm"
7961                 chmod $perm "$dir/$tfile.$perm"
7962         done
7963
7964         for ((i = 0; i < ${#perms[*]}; i++)); do
7965                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7966                 (( $num == 1 )) ||
7967                         error "lfs find -perm ${perms[i]}:"\
7968                               "$num != 1"
7969
7970                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7971                 (( $num == ${perm_minus[i]} )) ||
7972                         error "lfs find -perm -${perms[i]}:"\
7973                               "$num != ${perm_minus[i]}"
7974
7975                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7976                 (( $num == ${perm_slash[i]} )) ||
7977                         error "lfs find -perm /${perms[i]}:"\
7978                               "$num != ${perm_slash[i]}"
7979         done
7980 }
7981 run_test 56aca "check lfs find -perm with octal representation"
7982
7983 test_56acb() {
7984         local dir=$DIR/$tdir
7985         # p is the permission of write and execute for user, group and other
7986         # without the umask. It is used to test +wx.
7987         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7988         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7989         local symbolic=(+t  a+t u+t g+t o+t
7990                         g+s u+s o+s +s o+sr
7991                         o=r,ug+o,u+w
7992                         u+ g+ o+ a+ ugo+
7993                         u- g- o- a- ugo-
7994                         u= g= o= a= ugo=
7995                         o=r,ug+o,u+w u=r,a+u,u+w
7996                         g=r,ugo=g,u+w u+x,+X +X
7997                         u+x,u+X u+X u+x,g+X o+r,+X
7998                         u+x,go+X +wx +rwx)
7999
8000         test_mkdir $dir
8001         for perm in ${perms[*]}; do
8002                 touch "$dir/$tfile.$perm"
8003                 chmod $perm "$dir/$tfile.$perm"
8004         done
8005
8006         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8007                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8008
8009                 (( $num == 1 )) ||
8010                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8011         done
8012 }
8013 run_test 56acb "check lfs find -perm with symbolic representation"
8014
8015 test_56acc() {
8016         local dir=$DIR/$tdir
8017         local tests="17777 787 789 abcd
8018                 ug=uu ug=a ug=gu uo=ou urw
8019                 u+xg+x a=r,u+x,"
8020
8021         test_mkdir $dir
8022         for err in $tests; do
8023                 if $LFS find $dir -perm $err 2>/dev/null; then
8024                         error "lfs find -perm $err: parsing should have failed"
8025                 fi
8026         done
8027 }
8028 run_test 56acc "check parsing error for lfs find -perm"
8029
8030 test_56ba() {
8031         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8032                 skip "Need MDS version at least 2.10.50"
8033
8034         # Create composite files with one component
8035         local dir=$DIR/$tdir
8036
8037         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8038         # Create composite files with three components
8039         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8040         # Create non-composite files
8041         createmany -o $dir/${tfile}- 10
8042
8043         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8044
8045         [[ $nfiles == 10 ]] ||
8046                 error "lfs find -E 1M found $nfiles != 10 files"
8047
8048         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8049         [[ $nfiles == 25 ]] ||
8050                 error "lfs find ! -E 1M found $nfiles != 25 files"
8051
8052         # All files have a component that starts at 0
8053         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8054         [[ $nfiles == 35 ]] ||
8055                 error "lfs find --component-start 0 - $nfiles != 35 files"
8056
8057         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8058         [[ $nfiles == 15 ]] ||
8059                 error "lfs find --component-start 2M - $nfiles != 15 files"
8060
8061         # All files created here have a componenet that does not starts at 2M
8062         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8063         [[ $nfiles == 35 ]] ||
8064                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8065
8066         # Find files with a specified number of components
8067         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8068         [[ $nfiles == 15 ]] ||
8069                 error "lfs find --component-count 3 - $nfiles != 15 files"
8070
8071         # Remember non-composite files have a component count of zero
8072         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8073         [[ $nfiles == 10 ]] ||
8074                 error "lfs find --component-count 0 - $nfiles != 10 files"
8075
8076         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8077         [[ $nfiles == 20 ]] ||
8078                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8079
8080         # All files have a flag called "init"
8081         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8082         [[ $nfiles == 35 ]] ||
8083                 error "lfs find --component-flags init - $nfiles != 35 files"
8084
8085         # Multi-component files will have a component not initialized
8086         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8087         [[ $nfiles == 15 ]] ||
8088                 error "lfs find !--component-flags init - $nfiles != 15 files"
8089
8090         rm -rf $dir
8091
8092 }
8093 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8094
8095 test_56ca() {
8096         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8097                 skip "Need MDS version at least 2.10.57"
8098
8099         local td=$DIR/$tdir
8100         local tf=$td/$tfile
8101         local dir
8102         local nfiles
8103         local cmd
8104         local i
8105         local j
8106
8107         # create mirrored directories and mirrored files
8108         mkdir $td || error "mkdir $td failed"
8109         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8110         createmany -o $tf- 10 || error "create $tf- failed"
8111
8112         for i in $(seq 2); do
8113                 dir=$td/dir$i
8114                 mkdir $dir || error "mkdir $dir failed"
8115                 $LFS mirror create -N$((3 + i)) $dir ||
8116                         error "create mirrored dir $dir failed"
8117                 createmany -o $dir/$tfile- 10 ||
8118                         error "create $dir/$tfile- failed"
8119         done
8120
8121         # change the states of some mirrored files
8122         echo foo > $tf-6
8123         for i in $(seq 2); do
8124                 dir=$td/dir$i
8125                 for j in $(seq 4 9); do
8126                         echo foo > $dir/$tfile-$j
8127                 done
8128         done
8129
8130         # find mirrored files with specific mirror count
8131         cmd="$LFS find --mirror-count 3 --type f $td"
8132         nfiles=$($cmd | wc -l)
8133         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8134
8135         cmd="$LFS find ! --mirror-count 3 --type f $td"
8136         nfiles=$($cmd | wc -l)
8137         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8138
8139         cmd="$LFS find --mirror-count +2 --type f $td"
8140         nfiles=$($cmd | wc -l)
8141         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8142
8143         cmd="$LFS find --mirror-count -6 --type f $td"
8144         nfiles=$($cmd | wc -l)
8145         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8146
8147         # find mirrored files with specific file state
8148         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8149         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8150
8151         cmd="$LFS find --mirror-state=ro --type f $td"
8152         nfiles=$($cmd | wc -l)
8153         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8154
8155         cmd="$LFS find ! --mirror-state=ro --type f $td"
8156         nfiles=$($cmd | wc -l)
8157         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8158
8159         cmd="$LFS find --mirror-state=wp --type f $td"
8160         nfiles=$($cmd | wc -l)
8161         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8162
8163         cmd="$LFS find ! --mirror-state=sp --type f $td"
8164         nfiles=$($cmd | wc -l)
8165         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8166 }
8167 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8168
8169 test_56da() { # LU-14179
8170         local path=$DIR/$tdir
8171
8172         test_mkdir $path
8173         cd $path
8174
8175         local longdir=$(str_repeat 'a' 255)
8176
8177         for i in {1..15}; do
8178                 path=$path/$longdir
8179                 test_mkdir $longdir
8180                 cd $longdir
8181         done
8182
8183         local len=${#path}
8184         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8185
8186         test_mkdir $lastdir
8187         cd $lastdir
8188         # PATH_MAX-1
8189         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8190
8191         # NAME_MAX
8192         touch $(str_repeat 'f' 255)
8193
8194         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8195                 error "lfs find reported an error"
8196
8197         rm -rf $DIR/$tdir
8198 }
8199 run_test 56da "test lfs find with long paths"
8200
8201 test_56ea() { #LU-10378
8202         local path=$DIR/$tdir
8203         local pool=$TESTNAME
8204
8205         # Create ost pool
8206         pool_add $pool || error "pool_add $pool failed"
8207         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8208                 error "adding targets to $pool failed"
8209
8210         # Set default pool on directory before creating file
8211         mkdir $path || error "mkdir $path failed"
8212         $LFS setstripe -p $pool $path ||
8213                 error "set OST pool on $pool failed"
8214         touch $path/$tfile || error "touch $path/$tfile failed"
8215
8216         # Compare basic file attributes from -printf and stat
8217         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8218         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8219
8220         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8221                 error "Attrs from lfs find and stat don't match"
8222
8223         # Compare Lustre attributes from lfs find and lfs getstripe
8224         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8225         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8226         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8227         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8228         local fpool=$($LFS getstripe --pool $path/$tfile)
8229         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8230
8231         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8232                 error "Attrs from lfs find and lfs getstripe don't match"
8233
8234         # Verify behavior for unknown escape/format sequences
8235         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8236
8237         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8238                 error "Escape/format codes don't match"
8239 }
8240 run_test 56ea "test lfs find -printf option"
8241
8242 test_57a() {
8243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8244         # note test will not do anything if MDS is not local
8245         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8246                 skip_env "ldiskfs only test"
8247         fi
8248         remote_mds_nodsh && skip "remote MDS with nodsh"
8249
8250         local MNTDEV="osd*.*MDT*.mntdev"
8251         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8252         [ -z "$DEV" ] && error "can't access $MNTDEV"
8253         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8254                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8255                         error "can't access $DEV"
8256                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8257                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8258                 rm $TMP/t57a.dump
8259         done
8260 }
8261 run_test 57a "verify MDS filesystem created with large inodes =="
8262
8263 test_57b() {
8264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8265         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8266                 skip_env "ldiskfs only test"
8267         fi
8268         remote_mds_nodsh && skip "remote MDS with nodsh"
8269
8270         local dir=$DIR/$tdir
8271         local filecount=100
8272         local file1=$dir/f1
8273         local fileN=$dir/f$filecount
8274
8275         rm -rf $dir || error "removing $dir"
8276         test_mkdir -c1 $dir
8277         local mdtidx=$($LFS getstripe -m $dir)
8278         local mdtname=MDT$(printf %04x $mdtidx)
8279         local facet=mds$((mdtidx + 1))
8280
8281         echo "mcreating $filecount files"
8282         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8283
8284         # verify that files do not have EAs yet
8285         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8286                 error "$file1 has an EA"
8287         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8288                 error "$fileN has an EA"
8289
8290         sync
8291         sleep 1
8292         df $dir  #make sure we get new statfs data
8293         local mdsfree=$(do_facet $facet \
8294                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8295         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8296         local file
8297
8298         echo "opening files to create objects/EAs"
8299         for file in $(seq -f $dir/f%g 1 $filecount); do
8300                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8301                         error "opening $file"
8302         done
8303
8304         # verify that files have EAs now
8305         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8306         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8307
8308         sleep 1  #make sure we get new statfs data
8309         df $dir
8310         local mdsfree2=$(do_facet $facet \
8311                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8312         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8313
8314         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8315                 if [ "$mdsfree" != "$mdsfree2" ]; then
8316                         error "MDC before $mdcfree != after $mdcfree2"
8317                 else
8318                         echo "MDC before $mdcfree != after $mdcfree2"
8319                         echo "unable to confirm if MDS has large inodes"
8320                 fi
8321         fi
8322         rm -rf $dir
8323 }
8324 run_test 57b "default LOV EAs are stored inside large inodes ==="
8325
8326 test_58() {
8327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8328         [ -z "$(which wiretest 2>/dev/null)" ] &&
8329                         skip_env "could not find wiretest"
8330
8331         wiretest
8332 }
8333 run_test 58 "verify cross-platform wire constants =============="
8334
8335 test_59() {
8336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8337
8338         echo "touch 130 files"
8339         createmany -o $DIR/f59- 130
8340         echo "rm 130 files"
8341         unlinkmany $DIR/f59- 130
8342         sync
8343         # wait for commitment of removal
8344         wait_delete_completed
8345 }
8346 run_test 59 "verify cancellation of llog records async ========="
8347
8348 TEST60_HEAD="test_60 run $RANDOM"
8349 test_60a() {
8350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8351         remote_mgs_nodsh && skip "remote MGS with nodsh"
8352         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8353                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8354                         skip_env "missing subtest run-llog.sh"
8355
8356         log "$TEST60_HEAD - from kernel mode"
8357         do_facet mgs "$LCTL dk > /dev/null"
8358         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8359         do_facet mgs $LCTL dk > $TMP/$tfile
8360
8361         # LU-6388: test llog_reader
8362         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8363         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8364         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8365                         skip_env "missing llog_reader"
8366         local fstype=$(facet_fstype mgs)
8367         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8368                 skip_env "Only for ldiskfs or zfs type mgs"
8369
8370         local mntpt=$(facet_mntpt mgs)
8371         local mgsdev=$(mgsdevname 1)
8372         local fid_list
8373         local fid
8374         local rec_list
8375         local rec
8376         local rec_type
8377         local obj_file
8378         local path
8379         local seq
8380         local oid
8381         local pass=true
8382
8383         #get fid and record list
8384         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8385                 tail -n 4))
8386         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8387                 tail -n 4))
8388         #remount mgs as ldiskfs or zfs type
8389         stop mgs || error "stop mgs failed"
8390         mount_fstype mgs || error "remount mgs failed"
8391         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8392                 fid=${fid_list[i]}
8393                 rec=${rec_list[i]}
8394                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8395                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8396                 oid=$((16#$oid))
8397
8398                 case $fstype in
8399                         ldiskfs )
8400                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8401                         zfs )
8402                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8403                 esac
8404                 echo "obj_file is $obj_file"
8405                 do_facet mgs $llog_reader $obj_file
8406
8407                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8408                         awk '{ print $3 }' | sed -e "s/^type=//g")
8409                 if [ $rec_type != $rec ]; then
8410                         echo "FAILED test_60a wrong record type $rec_type," \
8411                               "should be $rec"
8412                         pass=false
8413                         break
8414                 fi
8415
8416                 #check obj path if record type is LLOG_LOGID_MAGIC
8417                 if [ "$rec" == "1064553b" ]; then
8418                         path=$(do_facet mgs $llog_reader $obj_file |
8419                                 grep "path=" | awk '{ print $NF }' |
8420                                 sed -e "s/^path=//g")
8421                         if [ $obj_file != $mntpt/$path ]; then
8422                                 echo "FAILED test_60a wrong obj path" \
8423                                       "$montpt/$path, should be $obj_file"
8424                                 pass=false
8425                                 break
8426                         fi
8427                 fi
8428         done
8429         rm -f $TMP/$tfile
8430         #restart mgs before "error", otherwise it will block the next test
8431         stop mgs || error "stop mgs failed"
8432         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8433         $pass || error "test failed, see FAILED test_60a messages for specifics"
8434 }
8435 run_test 60a "llog_test run from kernel module and test llog_reader"
8436
8437 test_60b() { # bug 6411
8438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8439
8440         dmesg > $DIR/$tfile
8441         LLOG_COUNT=$(do_facet mgs dmesg |
8442                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8443                           /llog_[a-z]*.c:[0-9]/ {
8444                                 if (marker)
8445                                         from_marker++
8446                                 from_begin++
8447                           }
8448                           END {
8449                                 if (marker)
8450                                         print from_marker
8451                                 else
8452                                         print from_begin
8453                           }")
8454
8455         [[ $LLOG_COUNT -gt 120 ]] &&
8456                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8457 }
8458 run_test 60b "limit repeated messages from CERROR/CWARN"
8459
8460 test_60c() {
8461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8462
8463         echo "create 5000 files"
8464         createmany -o $DIR/f60c- 5000
8465 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8466         lctl set_param fail_loc=0x80000137
8467         unlinkmany $DIR/f60c- 5000
8468         lctl set_param fail_loc=0
8469 }
8470 run_test 60c "unlink file when mds full"
8471
8472 test_60d() {
8473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8474
8475         SAVEPRINTK=$(lctl get_param -n printk)
8476         # verify "lctl mark" is even working"
8477         MESSAGE="test message ID $RANDOM $$"
8478         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8479         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8480
8481         lctl set_param printk=0 || error "set lnet.printk failed"
8482         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8483         MESSAGE="new test message ID $RANDOM $$"
8484         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8485         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8486         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8487
8488         lctl set_param -n printk="$SAVEPRINTK"
8489 }
8490 run_test 60d "test printk console message masking"
8491
8492 test_60e() {
8493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8494         remote_mds_nodsh && skip "remote MDS with nodsh"
8495
8496         touch $DIR/$tfile
8497 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8498         do_facet mds1 lctl set_param fail_loc=0x15b
8499         rm $DIR/$tfile
8500 }
8501 run_test 60e "no space while new llog is being created"
8502
8503 test_60f() {
8504         local old_path=$($LCTL get_param -n debug_path)
8505
8506         stack_trap "$LCTL set_param debug_path=$old_path"
8507         stack_trap "rm -f $TMP/$tfile*"
8508         rm -f $TMP/$tfile* 2> /dev/null
8509         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8510         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8511         test_mkdir $DIR/$tdir
8512         # retry in case the open is cached and not released
8513         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8514                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8515                 sleep 0.1
8516         done
8517         ls $TMP/$tfile*
8518         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8519 }
8520 run_test 60f "change debug_path works"
8521
8522 test_60g() {
8523         local pid
8524         local i
8525
8526         test_mkdir -c $MDSCOUNT $DIR/$tdir
8527
8528         (
8529                 local index=0
8530                 while true; do
8531                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8532                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8533                                 2>/dev/null
8534                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8535                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8536                         index=$((index + 1))
8537                 done
8538         ) &
8539
8540         pid=$!
8541
8542         for i in {0..100}; do
8543                 # define OBD_FAIL_OSD_TXN_START    0x19a
8544                 local index=$((i % MDSCOUNT + 1))
8545
8546                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8547                         > /dev/null
8548                 sleep 0.01
8549         done
8550
8551         kill -9 $pid
8552
8553         for i in $(seq $MDSCOUNT); do
8554                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8555         done
8556
8557         mkdir $DIR/$tdir/new || error "mkdir failed"
8558         rmdir $DIR/$tdir/new || error "rmdir failed"
8559
8560         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8561                 -t namespace
8562         for i in $(seq $MDSCOUNT); do
8563                 wait_update_facet mds$i "$LCTL get_param -n \
8564                         mdd.$(facet_svc mds$i).lfsck_namespace |
8565                         awk '/^status/ { print \\\$2 }'" "completed"
8566         done
8567
8568         ls -R $DIR/$tdir
8569         rm -rf $DIR/$tdir || error "rmdir failed"
8570 }
8571 run_test 60g "transaction abort won't cause MDT hung"
8572
8573 test_60h() {
8574         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8575                 skip "Need MDS version at least 2.12.52"
8576         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8577
8578         local f
8579
8580         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8581         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8582         for fail_loc in 0x80000188 0x80000189; do
8583                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8584                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8585                         error "mkdir $dir-$fail_loc failed"
8586                 for i in {0..10}; do
8587                         # create may fail on missing stripe
8588                         echo $i > $DIR/$tdir-$fail_loc/$i
8589                 done
8590                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8591                         error "getdirstripe $tdir-$fail_loc failed"
8592                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8593                         error "migrate $tdir-$fail_loc failed"
8594                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8595                         error "getdirstripe $tdir-$fail_loc failed"
8596                 pushd $DIR/$tdir-$fail_loc
8597                 for f in *; do
8598                         echo $f | cmp $f - || error "$f data mismatch"
8599                 done
8600                 popd
8601                 rm -rf $DIR/$tdir-$fail_loc
8602         done
8603 }
8604 run_test 60h "striped directory with missing stripes can be accessed"
8605
8606 function t60i_load() {
8607         mkdir $DIR/$tdir
8608         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8609         $LCTL set_param fail_loc=0x131c fail_val=1
8610         for ((i=0; i<5000; i++)); do
8611                 touch $DIR/$tdir/f$i
8612         done
8613 }
8614
8615 test_60i() {
8616         changelog_register || error "changelog_register failed"
8617         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8618         changelog_users $SINGLEMDS | grep -q $cl_user ||
8619                 error "User $cl_user not found in changelog_users"
8620         changelog_chmask "ALL"
8621         t60i_load &
8622         local PID=$!
8623         for((i=0; i<100; i++)); do
8624                 changelog_dump >/dev/null ||
8625                         error "can't read changelog"
8626         done
8627         kill $PID
8628         wait $PID
8629         changelog_deregister || error "changelog_deregister failed"
8630         $LCTL set_param fail_loc=0
8631 }
8632 run_test 60i "llog: new record vs reader race"
8633
8634 test_61a() {
8635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8636
8637         f="$DIR/f61"
8638         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8639         cancel_lru_locks osc
8640         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8641         sync
8642 }
8643 run_test 61a "mmap() writes don't make sync hang ================"
8644
8645 test_61b() {
8646         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8647 }
8648 run_test 61b "mmap() of unstriped file is successful"
8649
8650 # bug 2330 - insufficient obd_match error checking causes LBUG
8651 test_62() {
8652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8653
8654         f="$DIR/f62"
8655         echo foo > $f
8656         cancel_lru_locks osc
8657         lctl set_param fail_loc=0x405
8658         cat $f && error "cat succeeded, expect -EIO"
8659         lctl set_param fail_loc=0
8660 }
8661 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8662 # match every page all of the time.
8663 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8664
8665 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8666 # Though this test is irrelevant anymore, it helped to reveal some
8667 # other grant bugs (LU-4482), let's keep it.
8668 test_63a() {   # was test_63
8669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8670
8671         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8672
8673         for i in `seq 10` ; do
8674                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8675                 sleep 5
8676                 kill $!
8677                 sleep 1
8678         done
8679
8680         rm -f $DIR/f63 || true
8681 }
8682 run_test 63a "Verify oig_wait interruption does not crash ======="
8683
8684 # bug 2248 - async write errors didn't return to application on sync
8685 # bug 3677 - async write errors left page locked
8686 test_63b() {
8687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8688
8689         debugsave
8690         lctl set_param debug=-1
8691
8692         # ensure we have a grant to do async writes
8693         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8694         rm $DIR/$tfile
8695
8696         sync    # sync lest earlier test intercept the fail_loc
8697
8698         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8699         lctl set_param fail_loc=0x80000406
8700         $MULTIOP $DIR/$tfile Owy && \
8701                 error "sync didn't return ENOMEM"
8702         sync; sleep 2; sync     # do a real sync this time to flush page
8703         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8704                 error "locked page left in cache after async error" || true
8705         debugrestore
8706 }
8707 run_test 63b "async write errors should be returned to fsync ==="
8708
8709 test_64a () {
8710         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8711
8712         lfs df $DIR
8713         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8714 }
8715 run_test 64a "verify filter grant calculations (in kernel) ====="
8716
8717 test_64b () {
8718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8719
8720         bash oos.sh $MOUNT || error "oos.sh failed: $?"
8721 }
8722 run_test 64b "check out-of-space detection on client"
8723
8724 test_64c() {
8725         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8726 }
8727 run_test 64c "verify grant shrink"
8728
8729 import_param() {
8730         local tgt=$1
8731         local param=$2
8732
8733         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8734 }
8735
8736 # this does exactly what osc_request.c:osc_announce_cached() does in
8737 # order to calculate max amount of grants to ask from server
8738 want_grant() {
8739         local tgt=$1
8740
8741         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8742         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8743
8744         ((rpc_in_flight++));
8745         nrpages=$((nrpages * rpc_in_flight))
8746
8747         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8748
8749         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8750
8751         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8752         local undirty=$((nrpages * PAGE_SIZE))
8753
8754         local max_extent_pages
8755         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8756         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8757         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8758         local grant_extent_tax
8759         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8760
8761         undirty=$((undirty + nrextents * grant_extent_tax))
8762
8763         echo $undirty
8764 }
8765
8766 # this is size of unit for grant allocation. It should be equal to
8767 # what tgt_grant.c:tgt_grant_chunk() calculates
8768 grant_chunk() {
8769         local tgt=$1
8770         local max_brw_size
8771         local grant_extent_tax
8772
8773         max_brw_size=$(import_param $tgt max_brw_size)
8774
8775         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8776
8777         echo $(((max_brw_size + grant_extent_tax) * 2))
8778 }
8779
8780 test_64d() {
8781         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8782                 skip "OST < 2.10.55 doesn't limit grants enough"
8783
8784         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8785
8786         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8787                 skip "no grant_param connect flag"
8788
8789         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8790
8791         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8792         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8793
8794
8795         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8796         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8797
8798         $LFS setstripe $DIR/$tfile -i 0 -c 1
8799         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8800         ddpid=$!
8801
8802         while kill -0 $ddpid; do
8803                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8804
8805                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8806                         kill $ddpid
8807                         error "cur_grant $cur_grant > $max_cur_granted"
8808                 fi
8809
8810                 sleep 1
8811         done
8812 }
8813 run_test 64d "check grant limit exceed"
8814
8815 check_grants() {
8816         local tgt=$1
8817         local expected=$2
8818         local msg=$3
8819         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8820
8821         ((cur_grants == expected)) ||
8822                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8823 }
8824
8825 round_up_p2() {
8826         echo $((($1 + $2 - 1) & ~($2 - 1)))
8827 }
8828
8829 test_64e() {
8830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8831         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8832                 skip "Need OSS version at least 2.11.56"
8833
8834         # Remount client to reset grant
8835         remount_client $MOUNT || error "failed to remount client"
8836         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8837
8838         local init_grants=$(import_param $osc_tgt initial_grant)
8839
8840         check_grants $osc_tgt $init_grants "init grants"
8841
8842         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8843         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8844         local gbs=$(import_param $osc_tgt grant_block_size)
8845
8846         # write random number of bytes from max_brw_size / 4 to max_brw_size
8847         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8848         # align for direct io
8849         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8850         # round to grant consumption unit
8851         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8852
8853         local grants=$((wb_round_up + extent_tax))
8854
8855         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8856
8857         # define OBD_FAIL_TGT_NO_GRANT 0x725
8858         # make the server not grant more back
8859         do_facet ost1 $LCTL set_param fail_loc=0x725
8860         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8861
8862         do_facet ost1 $LCTL set_param fail_loc=0
8863
8864         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8865
8866         rm -f $DIR/$tfile || error "rm failed"
8867
8868         # Remount client to reset grant
8869         remount_client $MOUNT || error "failed to remount client"
8870         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8871
8872         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8873
8874         # define OBD_FAIL_TGT_NO_GRANT 0x725
8875         # make the server not grant more back
8876         do_facet ost1 $LCTL set_param fail_loc=0x725
8877         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8878         do_facet ost1 $LCTL set_param fail_loc=0
8879
8880         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8881 }
8882 run_test 64e "check grant consumption (no grant allocation)"
8883
8884 test_64f() {
8885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8886
8887         # Remount client to reset grant
8888         remount_client $MOUNT || error "failed to remount client"
8889         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8890
8891         local init_grants=$(import_param $osc_tgt initial_grant)
8892         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8893         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8894         local gbs=$(import_param $osc_tgt grant_block_size)
8895         local chunk=$(grant_chunk $osc_tgt)
8896
8897         # write random number of bytes from max_brw_size / 4 to max_brw_size
8898         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8899         # align for direct io
8900         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8901         # round to grant consumption unit
8902         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8903
8904         local grants=$((wb_round_up + extent_tax))
8905
8906         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8907         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8908                 error "error writing to $DIR/$tfile"
8909
8910         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8911                 "direct io with grant allocation"
8912
8913         rm -f $DIR/$tfile || error "rm failed"
8914
8915         # Remount client to reset grant
8916         remount_client $MOUNT || error "failed to remount client"
8917         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8918
8919         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8920
8921         local cmd="oO_WRONLY:w${write_bytes}_yc"
8922
8923         $MULTIOP $DIR/$tfile $cmd &
8924         MULTIPID=$!
8925         sleep 1
8926
8927         check_grants $osc_tgt $((init_grants - grants)) \
8928                 "buffered io, not write rpc"
8929
8930         kill -USR1 $MULTIPID
8931         wait
8932
8933         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8934                 "buffered io, one RPC"
8935 }
8936 run_test 64f "check grant consumption (with grant allocation)"
8937
8938 test_64g() {
8939         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
8940                 skip "Need MDS version at least 2.14.56"
8941
8942         local mdts=$(comma_list $(mdts_nodes))
8943
8944         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
8945                         tr '\n' ' ')
8946         stack_trap "$LCTL set_param $old"
8947
8948         # generate dirty pages and increase dirty granted on MDT
8949         stack_trap "rm -f $DIR/$tfile-*"
8950         for (( i = 0; i < 10; i++)); do
8951                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
8952                         error "can't set stripe"
8953                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
8954                         error "can't dd"
8955                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
8956                         $LFS getstripe $DIR/$tfile-$i
8957                         error "not DoM file"
8958                 }
8959         done
8960
8961         # flush dirty pages
8962         sync
8963
8964         # wait until grant shrink reset grant dirty on MDTs
8965         for ((i = 0; i < 120; i++)); do
8966                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8967                         awk '{sum=sum+$1} END {print sum}')
8968                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
8969                 echo "$grant_dirty grants, $vm_dirty pages"
8970                 (( grant_dirty + vm_dirty == 0 )) && break
8971                 (( i == 3 )) && sync &&
8972                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
8973                 sleep 1
8974         done
8975
8976         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8977                 awk '{sum=sum+$1} END {print sum}')
8978         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
8979 }
8980 run_test 64g "grant shrink on MDT"
8981
8982 test_64h() {
8983         local instance=$($LFS getname -i $DIR)
8984         local osc_tgt="$FSNAME-OST0000-osc-$instance"
8985         local num_exps=$(do_facet ost1 \
8986             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
8987         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8988         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
8989         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8990
8991         # 10MiB is for file to be written, max_brw_size * 16 *
8992         # num_exps is space reserve so that tgt_grant_shrink() decided
8993         # to not shrink
8994         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
8995         (( avail * 1024 < expect )) &&
8996                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
8997
8998         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
8999         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9000         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9001         $LCTL set_param osc.*OST0000*.grant_shrink=1
9002         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9003
9004         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9005         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9006
9007         # drop cache so that coming read would do rpc
9008         cancel_lru_locks osc
9009
9010         # shrink interval is set to 10, pause for 7 seconds so that
9011         # grant thread did not wake up yet but coming read entered
9012         # shrink mode for rpc (osc_should_shrink_grant())
9013         sleep 7
9014
9015         declare -a cur_grant_bytes
9016         declare -a tot_granted
9017         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9018         tot_granted[0]=$(do_facet ost1 \
9019             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9020
9021         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9022
9023         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9024         tot_granted[1]=$(do_facet ost1 \
9025             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9026
9027         # grant change should be equal on both sides
9028         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9029                 tot_granted[0] - tot_granted[1])) ||
9030                 error "grant change mismatch, "                                \
9031                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9032                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9033 }
9034 run_test 64h "grant shrink on read"
9035
9036 test_64i() {
9037         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
9038                 skip "need OST at least 2.14.55 to avoid grant shrink on replay"
9039
9040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9041         remote_ost_nodsh && skip "remote OSTs with nodsh"
9042
9043         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9044
9045         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9046
9047         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9048         local instance=$($LFS getname -i $DIR)
9049
9050         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9051         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9052
9053         # shrink grants and simulate rpc loss
9054         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9055         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9056         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9057
9058         fail ost1
9059
9060         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9061
9062         local testid=$(echo $TESTNAME | tr '_' ' ')
9063
9064         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9065                 grep "GRANT, real grant" &&
9066                 error "client has more grants then it owns" || true
9067 }
9068 run_test 64i "shrink on reconnect"
9069
9070 # bug 1414 - set/get directories' stripe info
9071 test_65a() {
9072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9073
9074         test_mkdir $DIR/$tdir
9075         touch $DIR/$tdir/f1
9076         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9077 }
9078 run_test 65a "directory with no stripe info"
9079
9080 test_65b() {
9081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9082
9083         test_mkdir $DIR/$tdir
9084         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9085
9086         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9087                                                 error "setstripe"
9088         touch $DIR/$tdir/f2
9089         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9090 }
9091 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9092
9093 test_65c() {
9094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9095         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9096
9097         test_mkdir $DIR/$tdir
9098         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9099
9100         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9101                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9102         touch $DIR/$tdir/f3
9103         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9104 }
9105 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9106
9107 test_65d() {
9108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9109
9110         test_mkdir $DIR/$tdir
9111         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9112         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9113
9114         if [[ $STRIPECOUNT -le 0 ]]; then
9115                 sc=1
9116         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9117                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9118                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9119         else
9120                 sc=$(($STRIPECOUNT - 1))
9121         fi
9122         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9123         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9124         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9125                 error "lverify failed"
9126 }
9127 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9128
9129 test_65e() {
9130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9131
9132         test_mkdir $DIR/$tdir
9133
9134         $LFS setstripe $DIR/$tdir || error "setstripe"
9135         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9136                                         error "no stripe info failed"
9137         touch $DIR/$tdir/f6
9138         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9139 }
9140 run_test 65e "directory setstripe defaults"
9141
9142 test_65f() {
9143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9144
9145         test_mkdir $DIR/${tdir}f
9146         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9147                 error "setstripe succeeded" || true
9148 }
9149 run_test 65f "dir setstripe permission (should return error) ==="
9150
9151 test_65g() {
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         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9160         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9161                 error "delete default stripe failed"
9162 }
9163 run_test 65g "directory setstripe -d"
9164
9165 test_65h() {
9166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9167
9168         test_mkdir $DIR/$tdir
9169         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9170
9171         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9172                 error "setstripe -S failed"
9173         test_mkdir $DIR/$tdir/dd1
9174         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9175                 error "stripe info inherit failed"
9176 }
9177 run_test 65h "directory stripe info inherit ===================="
9178
9179 test_65i() {
9180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9181
9182         save_layout_restore_at_exit $MOUNT
9183
9184         # bug6367: set non-default striping on root directory
9185         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9186
9187         # bug12836: getstripe on -1 default directory striping
9188         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9189
9190         # bug12836: getstripe -v on -1 default directory striping
9191         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9192
9193         # bug12836: new find on -1 default directory striping
9194         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9195 }
9196 run_test 65i "various tests to set root directory striping"
9197
9198 test_65j() { # bug6367
9199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9200
9201         sync; sleep 1
9202
9203         # if we aren't already remounting for each test, do so for this test
9204         if [ "$I_MOUNTED" = "yes" ]; then
9205                 cleanup || error "failed to unmount"
9206                 setup
9207         fi
9208
9209         save_layout_restore_at_exit $MOUNT
9210
9211         $LFS setstripe -d $MOUNT || error "setstripe failed"
9212 }
9213 run_test 65j "set default striping on root directory (bug 6367)="
9214
9215 cleanup_65k() {
9216         rm -rf $DIR/$tdir
9217         wait_delete_completed
9218         do_facet $SINGLEMDS "lctl set_param -n \
9219                 osp.$ost*MDT0000.max_create_count=$max_count"
9220         do_facet $SINGLEMDS "lctl set_param -n \
9221                 osp.$ost*MDT0000.create_count=$count"
9222         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9223         echo $INACTIVE_OSC "is Activate"
9224
9225         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9226 }
9227
9228 test_65k() { # bug11679
9229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9230         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9231         remote_mds_nodsh && skip "remote MDS with nodsh"
9232
9233         local disable_precreate=true
9234         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9235                 disable_precreate=false
9236
9237         echo "Check OST status: "
9238         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9239                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9240
9241         for OSC in $MDS_OSCS; do
9242                 echo $OSC "is active"
9243                 do_facet $SINGLEMDS lctl --device %$OSC activate
9244         done
9245
9246         for INACTIVE_OSC in $MDS_OSCS; do
9247                 local ost=$(osc_to_ost $INACTIVE_OSC)
9248                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9249                                lov.*md*.target_obd |
9250                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9251
9252                 mkdir -p $DIR/$tdir
9253                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9254                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9255
9256                 echo "Deactivate: " $INACTIVE_OSC
9257                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9258
9259                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9260                               osp.$ost*MDT0000.create_count")
9261                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9262                                   osp.$ost*MDT0000.max_create_count")
9263                 $disable_precreate &&
9264                         do_facet $SINGLEMDS "lctl set_param -n \
9265                                 osp.$ost*MDT0000.max_create_count=0"
9266
9267                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9268                         [ -f $DIR/$tdir/$idx ] && continue
9269                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9270                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9271                                 { cleanup_65k;
9272                                   error "setstripe $idx should succeed"; }
9273                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9274                 done
9275                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9276                 rmdir $DIR/$tdir
9277
9278                 do_facet $SINGLEMDS "lctl set_param -n \
9279                         osp.$ost*MDT0000.max_create_count=$max_count"
9280                 do_facet $SINGLEMDS "lctl set_param -n \
9281                         osp.$ost*MDT0000.create_count=$count"
9282                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9283                 echo $INACTIVE_OSC "is Activate"
9284
9285                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9286         done
9287 }
9288 run_test 65k "validate manual striping works properly with deactivated OSCs"
9289
9290 test_65l() { # bug 12836
9291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9292
9293         test_mkdir -p $DIR/$tdir/test_dir
9294         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9295         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9296 }
9297 run_test 65l "lfs find on -1 stripe dir ========================"
9298
9299 test_65m() {
9300         local layout=$(save_layout $MOUNT)
9301         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9302                 restore_layout $MOUNT $layout
9303                 error "setstripe should fail by non-root users"
9304         }
9305         true
9306 }
9307 run_test 65m "normal user can't set filesystem default stripe"
9308
9309 test_65n() {
9310         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9311         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9312                 skip "Need MDS version at least 2.12.50"
9313         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9314
9315         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9316         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9317         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9318
9319         save_layout_restore_at_exit $MOUNT
9320
9321         # new subdirectory under root directory should not inherit
9322         # the default layout from root
9323         local dir1=$MOUNT/$tdir-1
9324         mkdir $dir1 || error "mkdir $dir1 failed"
9325         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9326                 error "$dir1 shouldn't have LOV EA"
9327
9328         # delete the default layout on root directory
9329         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9330
9331         local dir2=$MOUNT/$tdir-2
9332         mkdir $dir2 || error "mkdir $dir2 failed"
9333         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9334                 error "$dir2 shouldn't have LOV EA"
9335
9336         # set a new striping pattern on root directory
9337         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9338         local new_def_stripe_size=$((def_stripe_size * 2))
9339         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9340                 error "set stripe size on $MOUNT failed"
9341
9342         # new file created in $dir2 should inherit the new stripe size from
9343         # the filesystem default
9344         local file2=$dir2/$tfile-2
9345         touch $file2 || error "touch $file2 failed"
9346
9347         local file2_stripe_size=$($LFS getstripe -S $file2)
9348         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9349         {
9350                 echo "file2_stripe_size: '$file2_stripe_size'"
9351                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9352                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9353         }
9354
9355         local dir3=$MOUNT/$tdir-3
9356         mkdir $dir3 || error "mkdir $dir3 failed"
9357         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9358         # the root layout, which is the actual default layout that will be used
9359         # when new files are created in $dir3.
9360         local dir3_layout=$(get_layout_param $dir3)
9361         local root_dir_layout=$(get_layout_param $MOUNT)
9362         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9363         {
9364                 echo "dir3_layout: '$dir3_layout'"
9365                 echo "root_dir_layout: '$root_dir_layout'"
9366                 error "$dir3 should show the default layout from $MOUNT"
9367         }
9368
9369         # set OST pool on root directory
9370         local pool=$TESTNAME
9371         pool_add $pool || error "add $pool failed"
9372         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9373                 error "add targets to $pool failed"
9374
9375         $LFS setstripe -p $pool $MOUNT ||
9376                 error "set OST pool on $MOUNT failed"
9377
9378         # new file created in $dir3 should inherit the pool from
9379         # the filesystem default
9380         local file3=$dir3/$tfile-3
9381         touch $file3 || error "touch $file3 failed"
9382
9383         local file3_pool=$($LFS getstripe -p $file3)
9384         [[ "$file3_pool" = "$pool" ]] ||
9385                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9386
9387         local dir4=$MOUNT/$tdir-4
9388         mkdir $dir4 || error "mkdir $dir4 failed"
9389         local dir4_layout=$(get_layout_param $dir4)
9390         root_dir_layout=$(get_layout_param $MOUNT)
9391         echo "$LFS getstripe -d $dir4"
9392         $LFS getstripe -d $dir4
9393         echo "$LFS getstripe -d $MOUNT"
9394         $LFS getstripe -d $MOUNT
9395         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9396         {
9397                 echo "dir4_layout: '$dir4_layout'"
9398                 echo "root_dir_layout: '$root_dir_layout'"
9399                 error "$dir4 should show the default layout from $MOUNT"
9400         }
9401
9402         # new file created in $dir4 should inherit the pool from
9403         # the filesystem default
9404         local file4=$dir4/$tfile-4
9405         touch $file4 || error "touch $file4 failed"
9406
9407         local file4_pool=$($LFS getstripe -p $file4)
9408         [[ "$file4_pool" = "$pool" ]] ||
9409                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9410
9411         # new subdirectory under non-root directory should inherit
9412         # the default layout from its parent directory
9413         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9414                 error "set directory layout on $dir4 failed"
9415
9416         local dir5=$dir4/$tdir-5
9417         mkdir $dir5 || error "mkdir $dir5 failed"
9418
9419         dir4_layout=$(get_layout_param $dir4)
9420         local dir5_layout=$(get_layout_param $dir5)
9421         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9422         {
9423                 echo "dir4_layout: '$dir4_layout'"
9424                 echo "dir5_layout: '$dir5_layout'"
9425                 error "$dir5 should inherit the default layout from $dir4"
9426         }
9427
9428         # though subdir under ROOT doesn't inherit default layout, but
9429         # its sub dir/file should be created with default layout.
9430         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9431         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9432                 skip "Need MDS version at least 2.12.59"
9433
9434         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9435         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9436         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9437
9438         if [ $default_lmv_hash == "none" ]; then
9439                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9440         else
9441                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9442                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9443         fi
9444
9445         $LFS setdirstripe -D -c 2 $MOUNT ||
9446                 error "setdirstripe -D -c 2 failed"
9447         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9448         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9449         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9450
9451         # $dir4 layout includes pool
9452         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9453         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9454                 error "pool lost on setstripe"
9455         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9456         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9457                 error "pool lost on compound layout setstripe"
9458 }
9459 run_test 65n "don't inherit default layout from root for new subdirectories"
9460
9461 # bug 2543 - update blocks count on client
9462 test_66() {
9463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9464
9465         COUNT=${COUNT:-8}
9466         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9467         sync; sync_all_data; sync; sync_all_data
9468         cancel_lru_locks osc
9469         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9470         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9471 }
9472 run_test 66 "update inode blocks count on client ==============="
9473
9474 meminfo() {
9475         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9476 }
9477
9478 swap_used() {
9479         swapon -s | awk '($1 == "'$1'") { print $4 }'
9480 }
9481
9482 # bug5265, obdfilter oa2dentry return -ENOENT
9483 # #define OBD_FAIL_SRV_ENOENT 0x217
9484 test_69() {
9485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9486         remote_ost_nodsh && skip "remote OST with nodsh"
9487
9488         f="$DIR/$tfile"
9489         $LFS setstripe -c 1 -i 0 $f
9490
9491         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9492
9493         do_facet ost1 lctl set_param fail_loc=0x217
9494         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9495         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9496
9497         do_facet ost1 lctl set_param fail_loc=0
9498         $DIRECTIO write $f 0 2 || error "write error"
9499
9500         cancel_lru_locks osc
9501         $DIRECTIO read $f 0 1 || error "read error"
9502
9503         do_facet ost1 lctl set_param fail_loc=0x217
9504         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9505
9506         do_facet ost1 lctl set_param fail_loc=0
9507         rm -f $f
9508 }
9509 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9510
9511 test_71() {
9512         test_mkdir $DIR/$tdir
9513         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9514         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9515 }
9516 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9517
9518 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9520         [ "$RUNAS_ID" = "$UID" ] &&
9521                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9522         # Check that testing environment is properly set up. Skip if not
9523         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9524                 skip_env "User $RUNAS_ID does not exist - skipping"
9525
9526         touch $DIR/$tfile
9527         chmod 777 $DIR/$tfile
9528         chmod ug+s $DIR/$tfile
9529         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9530                 error "$RUNAS dd $DIR/$tfile failed"
9531         # See if we are still setuid/sgid
9532         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9533                 error "S/gid is not dropped on write"
9534         # Now test that MDS is updated too
9535         cancel_lru_locks mdc
9536         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9537                 error "S/gid is not dropped on MDS"
9538         rm -f $DIR/$tfile
9539 }
9540 run_test 72a "Test that remove suid works properly (bug5695) ===="
9541
9542 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9543         local perm
9544
9545         [ "$RUNAS_ID" = "$UID" ] &&
9546                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9547         [ "$RUNAS_ID" -eq 0 ] &&
9548                 skip_env "RUNAS_ID = 0 -- skipping"
9549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9550         # Check that testing environment is properly set up. Skip if not
9551         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9552                 skip_env "User $RUNAS_ID does not exist - skipping"
9553
9554         touch $DIR/${tfile}-f{g,u}
9555         test_mkdir $DIR/${tfile}-dg
9556         test_mkdir $DIR/${tfile}-du
9557         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9558         chmod g+s $DIR/${tfile}-{f,d}g
9559         chmod u+s $DIR/${tfile}-{f,d}u
9560         for perm in 777 2777 4777; do
9561                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9562                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9563                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9564                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9565         done
9566         true
9567 }
9568 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9569
9570 # bug 3462 - multiple simultaneous MDC requests
9571 test_73() {
9572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9573
9574         test_mkdir $DIR/d73-1
9575         test_mkdir $DIR/d73-2
9576         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9577         pid1=$!
9578
9579         lctl set_param fail_loc=0x80000129
9580         $MULTIOP $DIR/d73-1/f73-2 Oc &
9581         sleep 1
9582         lctl set_param fail_loc=0
9583
9584         $MULTIOP $DIR/d73-2/f73-3 Oc &
9585         pid3=$!
9586
9587         kill -USR1 $pid1
9588         wait $pid1 || return 1
9589
9590         sleep 25
9591
9592         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9593         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9594         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9595
9596         rm -rf $DIR/d73-*
9597 }
9598 run_test 73 "multiple MDC requests (should not deadlock)"
9599
9600 test_74a() { # bug 6149, 6184
9601         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9602
9603         touch $DIR/f74a
9604         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9605         #
9606         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9607         # will spin in a tight reconnection loop
9608         $LCTL set_param fail_loc=0x8000030e
9609         # get any lock that won't be difficult - lookup works.
9610         ls $DIR/f74a
9611         $LCTL set_param fail_loc=0
9612         rm -f $DIR/f74a
9613         true
9614 }
9615 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9616
9617 test_74b() { # bug 13310
9618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9619
9620         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9621         #
9622         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9623         # will spin in a tight reconnection loop
9624         $LCTL set_param fail_loc=0x8000030e
9625         # get a "difficult" lock
9626         touch $DIR/f74b
9627         $LCTL set_param fail_loc=0
9628         rm -f $DIR/f74b
9629         true
9630 }
9631 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9632
9633 test_74c() {
9634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9635
9636         #define OBD_FAIL_LDLM_NEW_LOCK
9637         $LCTL set_param fail_loc=0x319
9638         touch $DIR/$tfile && error "touch successful"
9639         $LCTL set_param fail_loc=0
9640         true
9641 }
9642 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9643
9644 slab_lic=/sys/kernel/slab/lustre_inode_cache
9645 num_objects() {
9646         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9647         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9648                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9649 }
9650
9651 test_76a() { # Now for b=20433, added originally in b=1443
9652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9653
9654         cancel_lru_locks osc
9655         # there may be some slab objects cached per core
9656         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9657         local before=$(num_objects)
9658         local count=$((512 * cpus))
9659         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9660         local margin=$((count / 10))
9661         if [[ -f $slab_lic/aliases ]]; then
9662                 local aliases=$(cat $slab_lic/aliases)
9663                 (( aliases > 0 )) && margin=$((margin * aliases))
9664         fi
9665
9666         echo "before slab objects: $before"
9667         for i in $(seq $count); do
9668                 touch $DIR/$tfile
9669                 rm -f $DIR/$tfile
9670         done
9671         cancel_lru_locks osc
9672         local after=$(num_objects)
9673         echo "created: $count, after slab objects: $after"
9674         # shared slab counts are not very accurate, allow significant margin
9675         # the main goal is that the cache growth is not permanently > $count
9676         while (( after > before + margin )); do
9677                 sleep 1
9678                 after=$(num_objects)
9679                 wait=$((wait + 1))
9680                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9681                 if (( wait > 60 )); then
9682                         error "inode slab grew from $before+$margin to $after"
9683                 fi
9684         done
9685 }
9686 run_test 76a "confirm clients recycle inodes properly ===="
9687
9688 test_76b() {
9689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9690         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9691
9692         local count=512
9693         local before=$(num_objects)
9694
9695         for i in $(seq $count); do
9696                 mkdir $DIR/$tdir
9697                 rmdir $DIR/$tdir
9698         done
9699
9700         local after=$(num_objects)
9701         local wait=0
9702
9703         while (( after > before )); do
9704                 sleep 1
9705                 after=$(num_objects)
9706                 wait=$((wait + 1))
9707                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9708                 if (( wait > 60 )); then
9709                         error "inode slab grew from $before to $after"
9710                 fi
9711         done
9712
9713         echo "slab objects before: $before, after: $after"
9714 }
9715 run_test 76b "confirm clients recycle directory inodes properly ===="
9716
9717 export ORIG_CSUM=""
9718 set_checksums()
9719 {
9720         # Note: in sptlrpc modes which enable its own bulk checksum, the
9721         # original crc32_le bulk checksum will be automatically disabled,
9722         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9723         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9724         # In this case set_checksums() will not be no-op, because sptlrpc
9725         # bulk checksum will be enabled all through the test.
9726
9727         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9728         lctl set_param -n osc.*.checksums $1
9729         return 0
9730 }
9731
9732 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9733                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9734 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9735                              tr -d [] | head -n1)}
9736 set_checksum_type()
9737 {
9738         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9739         rc=$?
9740         log "set checksum type to $1, rc = $rc"
9741         return $rc
9742 }
9743
9744 get_osc_checksum_type()
9745 {
9746         # arugment 1: OST name, like OST0000
9747         ost=$1
9748         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9749                         sed 's/.*\[\(.*\)\].*/\1/g')
9750         rc=$?
9751         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9752         echo $checksum_type
9753 }
9754
9755 F77_TMP=$TMP/f77-temp
9756 F77SZ=8
9757 setup_f77() {
9758         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9759                 error "error writing to $F77_TMP"
9760 }
9761
9762 test_77a() { # bug 10889
9763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9764         $GSS && skip_env "could not run with gss"
9765
9766         [ ! -f $F77_TMP ] && setup_f77
9767         set_checksums 1
9768         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9769         set_checksums 0
9770         rm -f $DIR/$tfile
9771 }
9772 run_test 77a "normal checksum read/write operation"
9773
9774 test_77b() { # bug 10889
9775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9776         $GSS && skip_env "could not run with gss"
9777
9778         [ ! -f $F77_TMP ] && setup_f77
9779         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9780         $LCTL set_param fail_loc=0x80000409
9781         set_checksums 1
9782
9783         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9784                 error "dd error: $?"
9785         $LCTL set_param fail_loc=0
9786
9787         for algo in $CKSUM_TYPES; do
9788                 cancel_lru_locks osc
9789                 set_checksum_type $algo
9790                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9791                 $LCTL set_param fail_loc=0x80000408
9792                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9793                 $LCTL set_param fail_loc=0
9794         done
9795         set_checksums 0
9796         set_checksum_type $ORIG_CSUM_TYPE
9797         rm -f $DIR/$tfile
9798 }
9799 run_test 77b "checksum error on client write, read"
9800
9801 cleanup_77c() {
9802         trap 0
9803         set_checksums 0
9804         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9805         $check_ost &&
9806                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9807         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9808         $check_ost && [ -n "$ost_file_prefix" ] &&
9809                 do_facet ost1 rm -f ${ost_file_prefix}\*
9810 }
9811
9812 test_77c() {
9813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9814         $GSS && skip_env "could not run with gss"
9815         remote_ost_nodsh && skip "remote OST with nodsh"
9816
9817         local bad1
9818         local osc_file_prefix
9819         local osc_file
9820         local check_ost=false
9821         local ost_file_prefix
9822         local ost_file
9823         local orig_cksum
9824         local dump_cksum
9825         local fid
9826
9827         # ensure corruption will occur on first OSS/OST
9828         $LFS setstripe -i 0 $DIR/$tfile
9829
9830         [ ! -f $F77_TMP ] && setup_f77
9831         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9832                 error "dd write error: $?"
9833         fid=$($LFS path2fid $DIR/$tfile)
9834
9835         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9836         then
9837                 check_ost=true
9838                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9839                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9840         else
9841                 echo "OSS do not support bulk pages dump upon error"
9842         fi
9843
9844         osc_file_prefix=$($LCTL get_param -n debug_path)
9845         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9846
9847         trap cleanup_77c EXIT
9848
9849         set_checksums 1
9850         # enable bulk pages dump upon error on Client
9851         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9852         # enable bulk pages dump upon error on OSS
9853         $check_ost &&
9854                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9855
9856         # flush Client cache to allow next read to reach OSS
9857         cancel_lru_locks osc
9858
9859         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9860         $LCTL set_param fail_loc=0x80000408
9861         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9862         $LCTL set_param fail_loc=0
9863
9864         rm -f $DIR/$tfile
9865
9866         # check cksum dump on Client
9867         osc_file=$(ls ${osc_file_prefix}*)
9868         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9869         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9870         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9871         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9872         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9873                      cksum)
9874         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9875         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9876                 error "dump content does not match on Client"
9877
9878         $check_ost || skip "No need to check cksum dump on OSS"
9879
9880         # check cksum dump on OSS
9881         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9882         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9883         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9884         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9885         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9886                 error "dump content does not match on OSS"
9887
9888         cleanup_77c
9889 }
9890 run_test 77c "checksum error on client read with debug"
9891
9892 test_77d() { # bug 10889
9893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9894         $GSS && skip_env "could not run with gss"
9895
9896         stack_trap "rm -f $DIR/$tfile"
9897         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9898         $LCTL set_param fail_loc=0x80000409
9899         set_checksums 1
9900         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9901                 error "direct write: rc=$?"
9902         $LCTL set_param fail_loc=0
9903         set_checksums 0
9904
9905         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9906         $LCTL set_param fail_loc=0x80000408
9907         set_checksums 1
9908         cancel_lru_locks osc
9909         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9910                 error "direct read: rc=$?"
9911         $LCTL set_param fail_loc=0
9912         set_checksums 0
9913 }
9914 run_test 77d "checksum error on OST direct write, read"
9915
9916 test_77f() { # bug 10889
9917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9918         $GSS && skip_env "could not run with gss"
9919
9920         set_checksums 1
9921         stack_trap "rm -f $DIR/$tfile"
9922         for algo in $CKSUM_TYPES; do
9923                 cancel_lru_locks osc
9924                 set_checksum_type $algo
9925                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9926                 $LCTL set_param fail_loc=0x409
9927                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9928                         error "direct write succeeded"
9929                 $LCTL set_param fail_loc=0
9930         done
9931         set_checksum_type $ORIG_CSUM_TYPE
9932         set_checksums 0
9933 }
9934 run_test 77f "repeat checksum error on write (expect error)"
9935
9936 test_77g() { # bug 10889
9937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9938         $GSS && skip_env "could not run with gss"
9939         remote_ost_nodsh && skip "remote OST with nodsh"
9940
9941         [ ! -f $F77_TMP ] && setup_f77
9942
9943         local file=$DIR/$tfile
9944         stack_trap "rm -f $file" EXIT
9945
9946         $LFS setstripe -c 1 -i 0 $file
9947         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9948         do_facet ost1 lctl set_param fail_loc=0x8000021a
9949         set_checksums 1
9950         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9951                 error "write error: rc=$?"
9952         do_facet ost1 lctl set_param fail_loc=0
9953         set_checksums 0
9954
9955         cancel_lru_locks osc
9956         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9957         do_facet ost1 lctl set_param fail_loc=0x8000021b
9958         set_checksums 1
9959         cmp $F77_TMP $file || error "file compare failed"
9960         do_facet ost1 lctl set_param fail_loc=0
9961         set_checksums 0
9962 }
9963 run_test 77g "checksum error on OST write, read"
9964
9965 test_77k() { # LU-10906
9966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9967         $GSS && skip_env "could not run with gss"
9968
9969         local cksum_param="osc.$FSNAME*.checksums"
9970         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9971         local checksum
9972         local i
9973
9974         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9975         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9976         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9977
9978         for i in 0 1; do
9979                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9980                         error "failed to set checksum=$i on MGS"
9981                 wait_update $HOSTNAME "$get_checksum" $i
9982                 #remount
9983                 echo "remount client, checksum should be $i"
9984                 remount_client $MOUNT || error "failed to remount client"
9985                 checksum=$(eval $get_checksum)
9986                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9987         done
9988         # remove persistent param to avoid races with checksum mountopt below
9989         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9990                 error "failed to delete checksum on MGS"
9991
9992         for opt in "checksum" "nochecksum"; do
9993                 #remount with mount option
9994                 echo "remount client with option $opt, checksum should be $i"
9995                 umount_client $MOUNT || error "failed to umount client"
9996                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9997                         error "failed to mount client with option '$opt'"
9998                 checksum=$(eval $get_checksum)
9999                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10000                 i=$((i - 1))
10001         done
10002
10003         remount_client $MOUNT || error "failed to remount client"
10004 }
10005 run_test 77k "enable/disable checksum correctly"
10006
10007 test_77l() {
10008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10009         $GSS && skip_env "could not run with gss"
10010
10011         set_checksums 1
10012         stack_trap "set_checksums $ORIG_CSUM" EXIT
10013         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10014
10015         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10016
10017         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10018         for algo in $CKSUM_TYPES; do
10019                 set_checksum_type $algo || error "fail to set checksum type $algo"
10020                 osc_algo=$(get_osc_checksum_type OST0000)
10021                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10022
10023                 # no locks, no reqs to let the connection idle
10024                 cancel_lru_locks osc
10025                 lru_resize_disable osc
10026                 wait_osc_import_state client ost1 IDLE
10027
10028                 # ensure ost1 is connected
10029                 stat $DIR/$tfile >/dev/null || error "can't stat"
10030                 wait_osc_import_state client ost1 FULL
10031
10032                 osc_algo=$(get_osc_checksum_type OST0000)
10033                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10034         done
10035         return 0
10036 }
10037 run_test 77l "preferred checksum type is remembered after reconnected"
10038
10039 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10040 rm -f $F77_TMP
10041 unset F77_TMP
10042
10043 test_77m() {
10044         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10045                 skip "Need at least version 2.14.52"
10046         local param=checksum_speed
10047
10048         $LCTL get_param $param || error "reading $param failed"
10049
10050         csum_speeds=$($LCTL get_param -n $param)
10051
10052         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10053                 error "known checksum types are missing"
10054 }
10055 run_test 77m "Verify checksum_speed is correctly read"
10056
10057 check_filefrag_77n() {
10058         local nr_ext=0
10059         local starts=()
10060         local ends=()
10061
10062         while read extidx a b start end rest; do
10063                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10064                         nr_ext=$(( $nr_ext + 1 ))
10065                         starts+=( ${start%..} )
10066                         ends+=( ${end%:} )
10067                 fi
10068         done < <( filefrag -sv $1 )
10069
10070         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10071         return 1
10072 }
10073
10074 test_77n() {
10075         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10076
10077         touch $DIR/$tfile
10078         $TRUNCATE $DIR/$tfile 0
10079         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10080         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10081         check_filefrag_77n $DIR/$tfile ||
10082                 skip "$tfile blocks not contiguous around hole"
10083
10084         set_checksums 1
10085         stack_trap "set_checksums $ORIG_CSUM" EXIT
10086         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10087         stack_trap "rm -f $DIR/$tfile"
10088
10089         for algo in $CKSUM_TYPES; do
10090                 if [[ "$algo" =~ ^t10 ]]; then
10091                         set_checksum_type $algo ||
10092                                 error "fail to set checksum type $algo"
10093                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10094                                 error "fail to read $tfile with $algo"
10095                 fi
10096         done
10097         rm -f $DIR/$tfile
10098         return 0
10099 }
10100 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10101
10102 test_77o() {
10103         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10104                 skip "Need MDS version at least 2.14.55"
10105         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10106                 skip "Need OST version at least 2.14.55"
10107         local ofd=obdfilter
10108         local mdt=mdt
10109
10110         # print OST checksum_type
10111         echo "$ofd.$FSNAME-*.checksum_type:"
10112         do_nodes $(comma_list $(osts_nodes)) \
10113                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10114
10115         # print MDT checksum_type
10116         echo "$mdt.$FSNAME-*.checksum_type:"
10117         do_nodes $(comma_list $(mdts_nodes)) \
10118                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10119
10120         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10121                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10122
10123         (( $o_count == $OSTCOUNT )) ||
10124                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10125
10126         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10127                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10128
10129         (( $m_count == $MDSCOUNT )) ||
10130                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10131 }
10132 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10133
10134 cleanup_test_78() {
10135         trap 0
10136         rm -f $DIR/$tfile
10137 }
10138
10139 test_78() { # bug 10901
10140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10141         remote_ost || skip_env "local OST"
10142
10143         NSEQ=5
10144         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10145         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10146         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10147         echo "MemTotal: $MEMTOTAL"
10148
10149         # reserve 256MB of memory for the kernel and other running processes,
10150         # and then take 1/2 of the remaining memory for the read/write buffers.
10151         if [ $MEMTOTAL -gt 512 ] ;then
10152                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10153         else
10154                 # for those poor memory-starved high-end clusters...
10155                 MEMTOTAL=$((MEMTOTAL / 2))
10156         fi
10157         echo "Mem to use for directio: $MEMTOTAL"
10158
10159         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10160         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10161         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10162         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10163                 head -n1)
10164         echo "Smallest OST: $SMALLESTOST"
10165         [[ $SMALLESTOST -lt 10240 ]] &&
10166                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10167
10168         trap cleanup_test_78 EXIT
10169
10170         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10171                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10172
10173         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10174         echo "File size: $F78SIZE"
10175         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10176         for i in $(seq 1 $NSEQ); do
10177                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10178                 echo directIO rdwr round $i of $NSEQ
10179                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10180         done
10181
10182         cleanup_test_78
10183 }
10184 run_test 78 "handle large O_DIRECT writes correctly ============"
10185
10186 test_79() { # bug 12743
10187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10188
10189         wait_delete_completed
10190
10191         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10192         BKFREE=$(calc_osc_kbytes kbytesfree)
10193         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10194
10195         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10196         DFTOTAL=`echo $STRING | cut -d, -f1`
10197         DFUSED=`echo $STRING  | cut -d, -f2`
10198         DFAVAIL=`echo $STRING | cut -d, -f3`
10199         DFFREE=$(($DFTOTAL - $DFUSED))
10200
10201         ALLOWANCE=$((64 * $OSTCOUNT))
10202
10203         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10204            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10205                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10206         fi
10207         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10208            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10209                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10210         fi
10211         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10212            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10213                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10214         fi
10215 }
10216 run_test 79 "df report consistency check ======================="
10217
10218 test_80() { # bug 10718
10219         remote_ost_nodsh && skip "remote OST with nodsh"
10220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10221
10222         # relax strong synchronous semantics for slow backends like ZFS
10223         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10224                 local soc="obdfilter.*.sync_lock_cancel"
10225                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10226
10227                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10228                 if [ -z "$save" ]; then
10229                         soc="obdfilter.*.sync_on_lock_cancel"
10230                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10231                 fi
10232
10233                 if [ "$save" != "never" ]; then
10234                         local hosts=$(comma_list $(osts_nodes))
10235
10236                         do_nodes $hosts $LCTL set_param $soc=never
10237                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10238                 fi
10239         fi
10240
10241         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10242         sync; sleep 1; sync
10243         local before=$(date +%s)
10244         cancel_lru_locks osc
10245         local after=$(date +%s)
10246         local diff=$((after - before))
10247         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10248
10249         rm -f $DIR/$tfile
10250 }
10251 run_test 80 "Page eviction is equally fast at high offsets too"
10252
10253 test_81a() { # LU-456
10254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10255         remote_ost_nodsh && skip "remote OST with nodsh"
10256
10257         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10258         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10259         do_facet ost1 lctl set_param fail_loc=0x80000228
10260
10261         # write should trigger a retry and success
10262         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10263         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10264         RC=$?
10265         if [ $RC -ne 0 ] ; then
10266                 error "write should success, but failed for $RC"
10267         fi
10268 }
10269 run_test 81a "OST should retry write when get -ENOSPC ==============="
10270
10271 test_81b() { # LU-456
10272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10273         remote_ost_nodsh && skip "remote OST with nodsh"
10274
10275         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10276         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10277         do_facet ost1 lctl set_param fail_loc=0x228
10278
10279         # write should retry several times and return -ENOSPC finally
10280         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10281         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10282         RC=$?
10283         ENOSPC=28
10284         if [ $RC -ne $ENOSPC ] ; then
10285                 error "dd should fail for -ENOSPC, but succeed."
10286         fi
10287 }
10288 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10289
10290 test_99() {
10291         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10292
10293         test_mkdir $DIR/$tdir.cvsroot
10294         chown $RUNAS_ID $DIR/$tdir.cvsroot
10295
10296         cd $TMP
10297         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10298
10299         cd /etc/init.d
10300         # some versions of cvs import exit(1) when asked to import links or
10301         # files they can't read.  ignore those files.
10302         local toignore=$(find . -type l -printf '-I %f\n' -o \
10303                          ! -perm /4 -printf '-I %f\n')
10304         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10305                 $tdir.reposname vtag rtag
10306
10307         cd $DIR
10308         test_mkdir $DIR/$tdir.reposname
10309         chown $RUNAS_ID $DIR/$tdir.reposname
10310         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10311
10312         cd $DIR/$tdir.reposname
10313         $RUNAS touch foo99
10314         $RUNAS cvs add -m 'addmsg' foo99
10315         $RUNAS cvs update
10316         $RUNAS cvs commit -m 'nomsg' foo99
10317         rm -fr $DIR/$tdir.cvsroot
10318 }
10319 run_test 99 "cvs strange file/directory operations"
10320
10321 test_100() {
10322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10323         [[ "$NETTYPE" =~ tcp ]] ||
10324                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10325         remote_ost_nodsh && skip "remote OST with nodsh"
10326         remote_mds_nodsh && skip "remote MDS with nodsh"
10327         remote_servers ||
10328                 skip "useless for local single node setup"
10329
10330         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10331                 [ "$PROT" != "tcp" ] && continue
10332                 RPORT=$(echo $REMOTE | cut -d: -f2)
10333                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10334
10335                 rc=0
10336                 LPORT=`echo $LOCAL | cut -d: -f2`
10337                 if [ $LPORT -ge 1024 ]; then
10338                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10339                         netstat -tna
10340                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10341                 fi
10342         done
10343         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10344 }
10345 run_test 100 "check local port using privileged port ==========="
10346
10347 function get_named_value()
10348 {
10349     local tag=$1
10350
10351     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10352 }
10353
10354 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10355                    awk '/^max_cached_mb/ { print $2 }')
10356
10357 cleanup_101a() {
10358         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10359         trap 0
10360 }
10361
10362 test_101a() {
10363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10364
10365         local s
10366         local discard
10367         local nreads=10000
10368         local cache_limit=32
10369
10370         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10371         trap cleanup_101a EXIT
10372         $LCTL set_param -n llite.*.read_ahead_stats=0
10373         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10374
10375         #
10376         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10377         #
10378         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10379         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10380
10381         discard=0
10382         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10383                    get_named_value 'read.but.discarded'); do
10384                         discard=$(($discard + $s))
10385         done
10386         cleanup_101a
10387
10388         $LCTL get_param osc.*-osc*.rpc_stats
10389         $LCTL get_param llite.*.read_ahead_stats
10390
10391         # Discard is generally zero, but sometimes a few random reads line up
10392         # and trigger larger readahead, which is wasted & leads to discards.
10393         if [[ $(($discard)) -gt $nreads ]]; then
10394                 error "too many ($discard) discarded pages"
10395         fi
10396         rm -f $DIR/$tfile || true
10397 }
10398 run_test 101a "check read-ahead for random reads"
10399
10400 setup_test101bc() {
10401         test_mkdir $DIR/$tdir
10402         local ssize=$1
10403         local FILE_LENGTH=$2
10404         STRIPE_OFFSET=0
10405
10406         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10407
10408         local list=$(comma_list $(osts_nodes))
10409         set_osd_param $list '' read_cache_enable 0
10410         set_osd_param $list '' writethrough_cache_enable 0
10411
10412         trap cleanup_test101bc EXIT
10413         # prepare the read-ahead file
10414         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10415
10416         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10417                                 count=$FILE_SIZE_MB 2> /dev/null
10418
10419 }
10420
10421 cleanup_test101bc() {
10422         trap 0
10423         rm -rf $DIR/$tdir
10424         rm -f $DIR/$tfile
10425
10426         local list=$(comma_list $(osts_nodes))
10427         set_osd_param $list '' read_cache_enable 1
10428         set_osd_param $list '' writethrough_cache_enable 1
10429 }
10430
10431 calc_total() {
10432         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10433 }
10434
10435 ra_check_101() {
10436         local READ_SIZE=$1
10437         local STRIPE_SIZE=$2
10438         local FILE_LENGTH=$3
10439         local RA_INC=1048576
10440         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
10441         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
10442                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
10443         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
10444                   get_named_value 'read.but.discarded' | calc_total)
10445         if [[ $DISCARD -gt $discard_limit ]]; then
10446                 $LCTL get_param llite.*.read_ahead_stats
10447                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
10448         else
10449                 echo "Read-ahead success for size ${READ_SIZE}"
10450         fi
10451 }
10452
10453 test_101b() {
10454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10455         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10456
10457         local STRIPE_SIZE=1048576
10458         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10459
10460         if [ $SLOW == "yes" ]; then
10461                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10462         else
10463                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10464         fi
10465
10466         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10467
10468         # prepare the read-ahead file
10469         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10470         cancel_lru_locks osc
10471         for BIDX in 2 4 8 16 32 64 128 256
10472         do
10473                 local BSIZE=$((BIDX*4096))
10474                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10475                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10476                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10477                 $LCTL set_param -n llite.*.read_ahead_stats=0
10478                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10479                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10480                 cancel_lru_locks osc
10481                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10482         done
10483         cleanup_test101bc
10484         true
10485 }
10486 run_test 101b "check stride-io mode read-ahead ================="
10487
10488 test_101c() {
10489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10490
10491         local STRIPE_SIZE=1048576
10492         local FILE_LENGTH=$((STRIPE_SIZE*100))
10493         local nreads=10000
10494         local rsize=65536
10495         local osc_rpc_stats
10496
10497         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10498
10499         cancel_lru_locks osc
10500         $LCTL set_param osc.*.rpc_stats=0
10501         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10502         $LCTL get_param osc.*.rpc_stats
10503         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10504                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10505                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10506                 local size
10507
10508                 if [ $lines -le 20 ]; then
10509                         echo "continue debug"
10510                         continue
10511                 fi
10512                 for size in 1 2 4 8; do
10513                         local rpc=$(echo "$stats" |
10514                                     awk '($1 == "'$size':") {print $2; exit; }')
10515                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10516                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10517                 done
10518                 echo "$osc_rpc_stats check passed!"
10519         done
10520         cleanup_test101bc
10521         true
10522 }
10523 run_test 101c "check stripe_size aligned read-ahead"
10524
10525 test_101d() {
10526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10527
10528         local file=$DIR/$tfile
10529         local sz_MB=${FILESIZE_101d:-80}
10530         local ra_MB=${READAHEAD_MB:-40}
10531
10532         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10533         [ $free_MB -lt $sz_MB ] &&
10534                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10535
10536         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10537         $LFS setstripe -c -1 $file || error "setstripe failed"
10538
10539         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10540         echo Cancel LRU locks on lustre client to flush the client cache
10541         cancel_lru_locks osc
10542
10543         echo Disable read-ahead
10544         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10545         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10546         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10547         $LCTL get_param -n llite.*.max_read_ahead_mb
10548
10549         echo "Reading the test file $file with read-ahead disabled"
10550         local sz_KB=$((sz_MB * 1024 / 4))
10551         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10552         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10553         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10554                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10555
10556         echo "Cancel LRU locks on lustre client to flush the client cache"
10557         cancel_lru_locks osc
10558         echo Enable read-ahead with ${ra_MB}MB
10559         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10560
10561         echo "Reading the test file $file with read-ahead enabled"
10562         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10563                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10564
10565         echo "read-ahead disabled time read $raOFF"
10566         echo "read-ahead enabled time read $raON"
10567
10568         rm -f $file
10569         wait_delete_completed
10570
10571         # use awk for this check instead of bash because it handles decimals
10572         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10573                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10574 }
10575 run_test 101d "file read with and without read-ahead enabled"
10576
10577 test_101e() {
10578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10579
10580         local file=$DIR/$tfile
10581         local size_KB=500  #KB
10582         local count=100
10583         local bsize=1024
10584
10585         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10586         local need_KB=$((count * size_KB))
10587         [[ $free_KB -le $need_KB ]] &&
10588                 skip_env "Need free space $need_KB, have $free_KB"
10589
10590         echo "Creating $count ${size_KB}K test files"
10591         for ((i = 0; i < $count; i++)); do
10592                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10593         done
10594
10595         echo "Cancel LRU locks on lustre client to flush the client cache"
10596         cancel_lru_locks $OSC
10597
10598         echo "Reset readahead stats"
10599         $LCTL set_param -n llite.*.read_ahead_stats=0
10600
10601         for ((i = 0; i < $count; i++)); do
10602                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10603         done
10604
10605         $LCTL get_param llite.*.max_cached_mb
10606         $LCTL get_param llite.*.read_ahead_stats
10607         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10608                      get_named_value 'misses' | calc_total)
10609
10610         for ((i = 0; i < $count; i++)); do
10611                 rm -rf $file.$i 2>/dev/null
10612         done
10613
10614         #10000 means 20% reads are missing in readahead
10615         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10616 }
10617 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10618
10619 test_101f() {
10620         which iozone || skip_env "no iozone installed"
10621
10622         local old_debug=$($LCTL get_param debug)
10623         old_debug=${old_debug#*=}
10624         $LCTL set_param debug="reada mmap"
10625
10626         # create a test file
10627         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10628
10629         echo Cancel LRU locks on lustre client to flush the client cache
10630         cancel_lru_locks osc
10631
10632         echo Reset readahead stats
10633         $LCTL set_param -n llite.*.read_ahead_stats=0
10634
10635         echo mmap read the file with small block size
10636         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10637                 > /dev/null 2>&1
10638
10639         echo checking missing pages
10640         $LCTL get_param llite.*.read_ahead_stats
10641         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10642                         get_named_value 'misses' | calc_total)
10643
10644         $LCTL set_param debug="$old_debug"
10645         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10646         rm -f $DIR/$tfile
10647 }
10648 run_test 101f "check mmap read performance"
10649
10650 test_101g_brw_size_test() {
10651         local mb=$1
10652         local pages=$((mb * 1048576 / PAGE_SIZE))
10653         local file=$DIR/$tfile
10654
10655         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10656                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10657         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10658                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10659                         return 2
10660         done
10661
10662         stack_trap "rm -f $file" EXIT
10663         $LCTL set_param -n osc.*.rpc_stats=0
10664
10665         # 10 RPCs should be enough for the test
10666         local count=10
10667         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10668                 { error "dd write ${mb} MB blocks failed"; return 3; }
10669         cancel_lru_locks osc
10670         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10671                 { error "dd write ${mb} MB blocks failed"; return 4; }
10672
10673         # calculate number of full-sized read and write RPCs
10674         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10675                 sed -n '/pages per rpc/,/^$/p' |
10676                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10677                 END { print reads,writes }'))
10678         # allow one extra full-sized read RPC for async readahead
10679         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10680                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10681         [[ ${rpcs[1]} == $count ]] ||
10682                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10683 }
10684
10685 test_101g() {
10686         remote_ost_nodsh && skip "remote OST with nodsh"
10687
10688         local rpcs
10689         local osts=$(get_facets OST)
10690         local list=$(comma_list $(osts_nodes))
10691         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10692         local brw_size="obdfilter.*.brw_size"
10693
10694         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10695
10696         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10697
10698         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10699                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10700                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10701            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10702                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10703                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10704
10705                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10706                         suffix="M"
10707
10708                 if [[ $orig_mb -lt 16 ]]; then
10709                         save_lustre_params $osts "$brw_size" > $p
10710                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10711                                 error "set 16MB RPC size failed"
10712
10713                         echo "remount client to enable new RPC size"
10714                         remount_client $MOUNT || error "remount_client failed"
10715                 fi
10716
10717                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10718                 # should be able to set brw_size=12, but no rpc_stats for that
10719                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10720         fi
10721
10722         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10723
10724         if [[ $orig_mb -lt 16 ]]; then
10725                 restore_lustre_params < $p
10726                 remount_client $MOUNT || error "remount_client restore failed"
10727         fi
10728
10729         rm -f $p $DIR/$tfile
10730 }
10731 run_test 101g "Big bulk(4/16 MiB) readahead"
10732
10733 test_101h() {
10734         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10735
10736         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10737                 error "dd 70M file failed"
10738         echo Cancel LRU locks on lustre client to flush the client cache
10739         cancel_lru_locks osc
10740
10741         echo "Reset readahead stats"
10742         $LCTL set_param -n llite.*.read_ahead_stats 0
10743
10744         echo "Read 10M of data but cross 64M bundary"
10745         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10746         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10747                      get_named_value 'misses' | calc_total)
10748         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10749         rm -f $p $DIR/$tfile
10750 }
10751 run_test 101h "Readahead should cover current read window"
10752
10753 test_101i() {
10754         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10755                 error "dd 10M file failed"
10756
10757         local max_per_file_mb=$($LCTL get_param -n \
10758                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10759         cancel_lru_locks osc
10760         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10761         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10762                 error "set max_read_ahead_per_file_mb to 1 failed"
10763
10764         echo "Reset readahead stats"
10765         $LCTL set_param llite.*.read_ahead_stats=0
10766
10767         dd if=$DIR/$tfile of=/dev/null bs=2M
10768
10769         $LCTL get_param llite.*.read_ahead_stats
10770         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10771                      awk '/misses/ { print $2 }')
10772         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10773         rm -f $DIR/$tfile
10774 }
10775 run_test 101i "allow current readahead to exceed reservation"
10776
10777 test_101j() {
10778         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10779                 error "setstripe $DIR/$tfile failed"
10780         local file_size=$((1048576 * 16))
10781         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10782         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10783
10784         echo Disable read-ahead
10785         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10786
10787         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10788         for blk in $PAGE_SIZE 1048576 $file_size; do
10789                 cancel_lru_locks osc
10790                 echo "Reset readahead stats"
10791                 $LCTL set_param -n llite.*.read_ahead_stats=0
10792                 local count=$(($file_size / $blk))
10793                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10794                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10795                              get_named_value 'failed.to.fast.read' | calc_total)
10796                 $LCTL get_param -n llite.*.read_ahead_stats
10797                 [ $miss -eq $count ] || error "expected $count got $miss"
10798         done
10799
10800         rm -f $p $DIR/$tfile
10801 }
10802 run_test 101j "A complete read block should be submitted when no RA"
10803
10804 setup_test102() {
10805         test_mkdir $DIR/$tdir
10806         chown $RUNAS_ID $DIR/$tdir
10807         STRIPE_SIZE=65536
10808         STRIPE_OFFSET=1
10809         STRIPE_COUNT=$OSTCOUNT
10810         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10811
10812         trap cleanup_test102 EXIT
10813         cd $DIR
10814         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10815         cd $DIR/$tdir
10816         for num in 1 2 3 4; do
10817                 for count in $(seq 1 $STRIPE_COUNT); do
10818                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10819                                 local size=`expr $STRIPE_SIZE \* $num`
10820                                 local file=file"$num-$idx-$count"
10821                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10822                         done
10823                 done
10824         done
10825
10826         cd $DIR
10827         $1 tar cf $TMP/f102.tar $tdir --xattrs
10828 }
10829
10830 cleanup_test102() {
10831         trap 0
10832         rm -f $TMP/f102.tar
10833         rm -rf $DIR/d0.sanity/d102
10834 }
10835
10836 test_102a() {
10837         [ "$UID" != 0 ] && skip "must run as root"
10838         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10839                 skip_env "must have user_xattr"
10840
10841         [ -z "$(which setfattr 2>/dev/null)" ] &&
10842                 skip_env "could not find setfattr"
10843
10844         local testfile=$DIR/$tfile
10845
10846         touch $testfile
10847         echo "set/get xattr..."
10848         setfattr -n trusted.name1 -v value1 $testfile ||
10849                 error "setfattr -n trusted.name1=value1 $testfile failed"
10850         getfattr -n trusted.name1 $testfile 2> /dev/null |
10851           grep "trusted.name1=.value1" ||
10852                 error "$testfile missing trusted.name1=value1"
10853
10854         setfattr -n user.author1 -v author1 $testfile ||
10855                 error "setfattr -n user.author1=author1 $testfile failed"
10856         getfattr -n user.author1 $testfile 2> /dev/null |
10857           grep "user.author1=.author1" ||
10858                 error "$testfile missing trusted.author1=author1"
10859
10860         echo "listxattr..."
10861         setfattr -n trusted.name2 -v value2 $testfile ||
10862                 error "$testfile unable to set trusted.name2"
10863         setfattr -n trusted.name3 -v value3 $testfile ||
10864                 error "$testfile unable to set trusted.name3"
10865         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10866             grep "trusted.name" | wc -l) -eq 3 ] ||
10867                 error "$testfile missing 3 trusted.name xattrs"
10868
10869         setfattr -n user.author2 -v author2 $testfile ||
10870                 error "$testfile unable to set user.author2"
10871         setfattr -n user.author3 -v author3 $testfile ||
10872                 error "$testfile unable to set user.author3"
10873         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10874             grep "user.author" | wc -l) -eq 3 ] ||
10875                 error "$testfile missing 3 user.author xattrs"
10876
10877         echo "remove xattr..."
10878         setfattr -x trusted.name1 $testfile ||
10879                 error "$testfile error deleting trusted.name1"
10880         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10881                 error "$testfile did not delete trusted.name1 xattr"
10882
10883         setfattr -x user.author1 $testfile ||
10884                 error "$testfile error deleting user.author1"
10885         echo "set lustre special xattr ..."
10886         $LFS setstripe -c1 $testfile
10887         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10888                 awk -F "=" '/trusted.lov/ { print $2 }' )
10889         setfattr -n "trusted.lov" -v $lovea $testfile ||
10890                 error "$testfile doesn't ignore setting trusted.lov again"
10891         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10892                 error "$testfile allow setting invalid trusted.lov"
10893         rm -f $testfile
10894 }
10895 run_test 102a "user xattr test =================================="
10896
10897 check_102b_layout() {
10898         local layout="$*"
10899         local testfile=$DIR/$tfile
10900
10901         echo "test layout '$layout'"
10902         $LFS setstripe $layout $testfile || error "setstripe failed"
10903         $LFS getstripe -y $testfile
10904
10905         echo "get/set/list trusted.lov xattr ..." # b=10930
10906         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10907         [[ "$value" =~ "trusted.lov" ]] ||
10908                 error "can't get trusted.lov from $testfile"
10909         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10910                 error "getstripe failed"
10911
10912         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10913
10914         value=$(cut -d= -f2 <<<$value)
10915         # LU-13168: truncated xattr should fail if short lov_user_md header
10916         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10917                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10918         for len in $lens; do
10919                 echo "setfattr $len $testfile.2"
10920                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10921                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10922         done
10923         local stripe_size=$($LFS getstripe -S $testfile.2)
10924         local stripe_count=$($LFS getstripe -c $testfile.2)
10925         [[ $stripe_size -eq 65536 ]] ||
10926                 error "stripe size $stripe_size != 65536"
10927         [[ $stripe_count -eq $stripe_count_orig ]] ||
10928                 error "stripe count $stripe_count != $stripe_count_orig"
10929         rm $testfile $testfile.2
10930 }
10931
10932 test_102b() {
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         # check plain layout
10938         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10939
10940         # and also check composite layout
10941         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10942
10943 }
10944 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10945
10946 test_102c() {
10947         [ -z "$(which setfattr 2>/dev/null)" ] &&
10948                 skip_env "could not find setfattr"
10949         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10950
10951         # b10930: get/set/list lustre.lov xattr
10952         echo "get/set/list lustre.lov xattr ..."
10953         test_mkdir $DIR/$tdir
10954         chown $RUNAS_ID $DIR/$tdir
10955         local testfile=$DIR/$tdir/$tfile
10956         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10957                 error "setstripe failed"
10958         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10959                 error "getstripe failed"
10960         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10961         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10962
10963         local testfile2=${testfile}2
10964         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10965                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10966
10967         $RUNAS $MCREATE $testfile2
10968         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10969         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10970         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10971         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10972         [ $stripe_count -eq $STRIPECOUNT ] ||
10973                 error "stripe count $stripe_count != $STRIPECOUNT"
10974 }
10975 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10976
10977 compare_stripe_info1() {
10978         local stripe_index_all_zero=true
10979
10980         for num in 1 2 3 4; do
10981                 for count in $(seq 1 $STRIPE_COUNT); do
10982                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10983                                 local size=$((STRIPE_SIZE * num))
10984                                 local file=file"$num-$offset-$count"
10985                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10986                                 [[ $stripe_size -ne $size ]] &&
10987                                     error "$file: size $stripe_size != $size"
10988                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10989                                 # allow fewer stripes to be created, ORI-601
10990                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10991                                     error "$file: count $stripe_count != $count"
10992                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10993                                 [[ $stripe_index -ne 0 ]] &&
10994                                         stripe_index_all_zero=false
10995                         done
10996                 done
10997         done
10998         $stripe_index_all_zero &&
10999                 error "all files are being extracted starting from OST index 0"
11000         return 0
11001 }
11002
11003 have_xattrs_include() {
11004         tar --help | grep -q xattrs-include &&
11005                 echo --xattrs-include="lustre.*"
11006 }
11007
11008 test_102d() {
11009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11010         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11011
11012         XINC=$(have_xattrs_include)
11013         setup_test102
11014         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11015         cd $DIR/$tdir/$tdir
11016         compare_stripe_info1
11017 }
11018 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11019
11020 test_102f() {
11021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11022         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11023
11024         XINC=$(have_xattrs_include)
11025         setup_test102
11026         test_mkdir $DIR/$tdir.restore
11027         cd $DIR
11028         tar cf - --xattrs $tdir | tar xf - \
11029                 -C $DIR/$tdir.restore --xattrs $XINC
11030         cd $DIR/$tdir.restore/$tdir
11031         compare_stripe_info1
11032 }
11033 run_test 102f "tar copy files, not keep osts"
11034
11035 grow_xattr() {
11036         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11037                 skip "must have user_xattr"
11038         [ -z "$(which setfattr 2>/dev/null)" ] &&
11039                 skip_env "could not find setfattr"
11040         [ -z "$(which getfattr 2>/dev/null)" ] &&
11041                 skip_env "could not find getfattr"
11042
11043         local xsize=${1:-1024}  # in bytes
11044         local file=$DIR/$tfile
11045         local value="$(generate_string $xsize)"
11046         local xbig=trusted.big
11047         local toobig=$2
11048
11049         touch $file
11050         log "save $xbig on $file"
11051         if [ -z "$toobig" ]
11052         then
11053                 setfattr -n $xbig -v $value $file ||
11054                         error "saving $xbig on $file failed"
11055         else
11056                 setfattr -n $xbig -v $value $file &&
11057                         error "saving $xbig on $file succeeded"
11058                 return 0
11059         fi
11060
11061         local orig=$(get_xattr_value $xbig $file)
11062         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11063
11064         local xsml=trusted.sml
11065         log "save $xsml on $file"
11066         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11067
11068         local new=$(get_xattr_value $xbig $file)
11069         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11070
11071         log "grow $xsml on $file"
11072         setfattr -n $xsml -v "$value" $file ||
11073                 error "growing $xsml on $file failed"
11074
11075         new=$(get_xattr_value $xbig $file)
11076         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11077         log "$xbig still valid after growing $xsml"
11078
11079         rm -f $file
11080 }
11081
11082 test_102h() { # bug 15777
11083         grow_xattr 1024
11084 }
11085 run_test 102h "grow xattr from inside inode to external block"
11086
11087 test_102ha() {
11088         large_xattr_enabled || skip_env "ea_inode feature disabled"
11089
11090         echo "setting xattr of max xattr size: $(max_xattr_size)"
11091         grow_xattr $(max_xattr_size)
11092
11093         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11094         echo "This should fail:"
11095         grow_xattr $(($(max_xattr_size) + 10)) 1
11096 }
11097 run_test 102ha "grow xattr from inside inode to external inode"
11098
11099 test_102i() { # bug 17038
11100         [ -z "$(which getfattr 2>/dev/null)" ] &&
11101                 skip "could not find getfattr"
11102
11103         touch $DIR/$tfile
11104         ln -s $DIR/$tfile $DIR/${tfile}link
11105         getfattr -n trusted.lov $DIR/$tfile ||
11106                 error "lgetxattr on $DIR/$tfile failed"
11107         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11108                 grep -i "no such attr" ||
11109                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11110         rm -f $DIR/$tfile $DIR/${tfile}link
11111 }
11112 run_test 102i "lgetxattr test on symbolic link ============"
11113
11114 test_102j() {
11115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11116         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11117
11118         XINC=$(have_xattrs_include)
11119         setup_test102 "$RUNAS"
11120         chown $RUNAS_ID $DIR/$tdir
11121         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11122         cd $DIR/$tdir/$tdir
11123         compare_stripe_info1 "$RUNAS"
11124 }
11125 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11126
11127 test_102k() {
11128         [ -z "$(which setfattr 2>/dev/null)" ] &&
11129                 skip "could not find setfattr"
11130
11131         touch $DIR/$tfile
11132         # b22187 just check that does not crash for regular file.
11133         setfattr -n trusted.lov $DIR/$tfile
11134         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11135         local test_kdir=$DIR/$tdir
11136         test_mkdir $test_kdir
11137         local default_size=$($LFS getstripe -S $test_kdir)
11138         local default_count=$($LFS getstripe -c $test_kdir)
11139         local default_offset=$($LFS getstripe -i $test_kdir)
11140         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11141                 error 'dir setstripe failed'
11142         setfattr -n trusted.lov $test_kdir
11143         local stripe_size=$($LFS getstripe -S $test_kdir)
11144         local stripe_count=$($LFS getstripe -c $test_kdir)
11145         local stripe_offset=$($LFS getstripe -i $test_kdir)
11146         [ $stripe_size -eq $default_size ] ||
11147                 error "stripe size $stripe_size != $default_size"
11148         [ $stripe_count -eq $default_count ] ||
11149                 error "stripe count $stripe_count != $default_count"
11150         [ $stripe_offset -eq $default_offset ] ||
11151                 error "stripe offset $stripe_offset != $default_offset"
11152         rm -rf $DIR/$tfile $test_kdir
11153 }
11154 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11155
11156 test_102l() {
11157         [ -z "$(which getfattr 2>/dev/null)" ] &&
11158                 skip "could not find getfattr"
11159
11160         # LU-532 trusted. xattr is invisible to non-root
11161         local testfile=$DIR/$tfile
11162
11163         touch $testfile
11164
11165         echo "listxattr as user..."
11166         chown $RUNAS_ID $testfile
11167         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11168             grep -q "trusted" &&
11169                 error "$testfile trusted xattrs are user visible"
11170
11171         return 0;
11172 }
11173 run_test 102l "listxattr size test =================================="
11174
11175 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11176         local path=$DIR/$tfile
11177         touch $path
11178
11179         listxattr_size_check $path || error "listattr_size_check $path failed"
11180 }
11181 run_test 102m "Ensure listxattr fails on small bufffer ========"
11182
11183 cleanup_test102
11184
11185 getxattr() { # getxattr path name
11186         # Return the base64 encoding of the value of xattr name on path.
11187         local path=$1
11188         local name=$2
11189
11190         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11191         # file: $path
11192         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11193         #
11194         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11195
11196         getfattr --absolute-names --encoding=base64 --name=$name $path |
11197                 awk -F= -v name=$name '$1 == name {
11198                         print substr($0, index($0, "=") + 1);
11199         }'
11200 }
11201
11202 test_102n() { # LU-4101 mdt: protect internal xattrs
11203         [ -z "$(which setfattr 2>/dev/null)" ] &&
11204                 skip "could not find setfattr"
11205         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11206         then
11207                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11208         fi
11209
11210         local file0=$DIR/$tfile.0
11211         local file1=$DIR/$tfile.1
11212         local xattr0=$TMP/$tfile.0
11213         local xattr1=$TMP/$tfile.1
11214         local namelist="lov lma lmv link fid version som hsm"
11215         local name
11216         local value
11217
11218         rm -rf $file0 $file1 $xattr0 $xattr1
11219         touch $file0 $file1
11220
11221         # Get 'before' xattrs of $file1.
11222         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11223
11224         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11225                 namelist+=" lfsck_namespace"
11226         for name in $namelist; do
11227                 # Try to copy xattr from $file0 to $file1.
11228                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11229
11230                 setfattr --name=trusted.$name --value="$value" $file1 ||
11231                         error "setxattr 'trusted.$name' failed"
11232
11233                 # Try to set a garbage xattr.
11234                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11235
11236                 if [[ x$name == "xlov" ]]; then
11237                         setfattr --name=trusted.lov --value="$value" $file1 &&
11238                         error "setxattr invalid 'trusted.lov' success"
11239                 else
11240                         setfattr --name=trusted.$name --value="$value" $file1 ||
11241                                 error "setxattr invalid 'trusted.$name' failed"
11242                 fi
11243
11244                 # Try to remove the xattr from $file1. We don't care if this
11245                 # appears to succeed or fail, we just don't want there to be
11246                 # any changes or crashes.
11247                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11248         done
11249
11250         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11251         then
11252                 name="lfsck_ns"
11253                 # Try to copy xattr from $file0 to $file1.
11254                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11255
11256                 setfattr --name=trusted.$name --value="$value" $file1 ||
11257                         error "setxattr 'trusted.$name' failed"
11258
11259                 # Try to set a garbage xattr.
11260                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11261
11262                 setfattr --name=trusted.$name --value="$value" $file1 ||
11263                         error "setxattr 'trusted.$name' failed"
11264
11265                 # Try to remove the xattr from $file1. We don't care if this
11266                 # appears to succeed or fail, we just don't want there to be
11267                 # any changes or crashes.
11268                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11269         fi
11270
11271         # Get 'after' xattrs of file1.
11272         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11273
11274         if ! diff $xattr0 $xattr1; then
11275                 error "before and after xattrs of '$file1' differ"
11276         fi
11277
11278         rm -rf $file0 $file1 $xattr0 $xattr1
11279
11280         return 0
11281 }
11282 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11283
11284 test_102p() { # LU-4703 setxattr did not check ownership
11285         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11286                 skip "MDS needs to be at least 2.5.56"
11287
11288         local testfile=$DIR/$tfile
11289
11290         touch $testfile
11291
11292         echo "setfacl as user..."
11293         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11294         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11295
11296         echo "setfattr as user..."
11297         setfacl -m "u:$RUNAS_ID:---" $testfile
11298         $RUNAS setfattr -x system.posix_acl_access $testfile
11299         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11300 }
11301 run_test 102p "check setxattr(2) correctly fails without permission"
11302
11303 test_102q() {
11304         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11305                 skip "MDS needs to be at least 2.6.92"
11306
11307         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11308 }
11309 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11310
11311 test_102r() {
11312         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11313                 skip "MDS needs to be at least 2.6.93"
11314
11315         touch $DIR/$tfile || error "touch"
11316         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11317         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11318         rm $DIR/$tfile || error "rm"
11319
11320         #normal directory
11321         mkdir -p $DIR/$tdir || error "mkdir"
11322         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11323         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11324         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11325                 error "$testfile error deleting user.author1"
11326         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11327                 grep "user.$(basename $tdir)" &&
11328                 error "$tdir did not delete user.$(basename $tdir)"
11329         rmdir $DIR/$tdir || error "rmdir"
11330
11331         #striped directory
11332         test_mkdir $DIR/$tdir
11333         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11334         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11335         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11336                 error "$testfile error deleting user.author1"
11337         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11338                 grep "user.$(basename $tdir)" &&
11339                 error "$tdir did not delete user.$(basename $tdir)"
11340         rmdir $DIR/$tdir || error "rm striped dir"
11341 }
11342 run_test 102r "set EAs with empty values"
11343
11344 test_102s() {
11345         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11346                 skip "MDS needs to be at least 2.11.52"
11347
11348         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11349
11350         save_lustre_params client "llite.*.xattr_cache" > $save
11351
11352         for cache in 0 1; do
11353                 lctl set_param llite.*.xattr_cache=$cache
11354
11355                 rm -f $DIR/$tfile
11356                 touch $DIR/$tfile || error "touch"
11357                 for prefix in lustre security system trusted user; do
11358                         # Note getxattr() may fail with 'Operation not
11359                         # supported' or 'No such attribute' depending
11360                         # on prefix and cache.
11361                         getfattr -n $prefix.n102s $DIR/$tfile &&
11362                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11363                 done
11364         done
11365
11366         restore_lustre_params < $save
11367 }
11368 run_test 102s "getting nonexistent xattrs should fail"
11369
11370 test_102t() {
11371         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11372                 skip "MDS needs to be at least 2.11.52"
11373
11374         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11375
11376         save_lustre_params client "llite.*.xattr_cache" > $save
11377
11378         for cache in 0 1; do
11379                 lctl set_param llite.*.xattr_cache=$cache
11380
11381                 for buf_size in 0 256; do
11382                         rm -f $DIR/$tfile
11383                         touch $DIR/$tfile || error "touch"
11384                         setfattr -n user.multiop $DIR/$tfile
11385                         $MULTIOP $DIR/$tfile oa$buf_size ||
11386                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11387                 done
11388         done
11389
11390         restore_lustre_params < $save
11391 }
11392 run_test 102t "zero length xattr values handled correctly"
11393
11394 run_acl_subtest()
11395 {
11396     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11397     return $?
11398 }
11399
11400 test_103a() {
11401         [ "$UID" != 0 ] && skip "must run as root"
11402         $GSS && skip_env "could not run under gss"
11403         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11404                 skip_env "must have acl enabled"
11405         [ -z "$(which setfacl 2>/dev/null)" ] &&
11406                 skip_env "could not find setfacl"
11407         remote_mds_nodsh && skip "remote MDS with nodsh"
11408
11409         gpasswd -a daemon bin                           # LU-5641
11410         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11411
11412         declare -a identity_old
11413
11414         for num in $(seq $MDSCOUNT); do
11415                 switch_identity $num true || identity_old[$num]=$?
11416         done
11417
11418         SAVE_UMASK=$(umask)
11419         umask 0022
11420         mkdir -p $DIR/$tdir
11421         cd $DIR/$tdir
11422
11423         echo "performing cp ..."
11424         run_acl_subtest cp || error "run_acl_subtest cp failed"
11425         echo "performing getfacl-noacl..."
11426         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11427         echo "performing misc..."
11428         run_acl_subtest misc || error  "misc test failed"
11429         echo "performing permissions..."
11430         run_acl_subtest permissions || error "permissions failed"
11431         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11432         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11433                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11434                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11435         then
11436                 echo "performing permissions xattr..."
11437                 run_acl_subtest permissions_xattr ||
11438                         error "permissions_xattr failed"
11439         fi
11440         echo "performing setfacl..."
11441         run_acl_subtest setfacl || error  "setfacl test failed"
11442
11443         # inheritance test got from HP
11444         echo "performing inheritance..."
11445         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11446         chmod +x make-tree || error "chmod +x failed"
11447         run_acl_subtest inheritance || error "inheritance test failed"
11448         rm -f make-tree
11449
11450         echo "LU-974 ignore umask when acl is enabled..."
11451         run_acl_subtest 974 || error "LU-974 umask test failed"
11452         if [ $MDSCOUNT -ge 2 ]; then
11453                 run_acl_subtest 974_remote ||
11454                         error "LU-974 umask test failed under remote dir"
11455         fi
11456
11457         echo "LU-2561 newly created file is same size as directory..."
11458         if [ "$mds1_FSTYPE" != "zfs" ]; then
11459                 run_acl_subtest 2561 || error "LU-2561 test failed"
11460         else
11461                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11462         fi
11463
11464         run_acl_subtest 4924 || error "LU-4924 test failed"
11465
11466         cd $SAVE_PWD
11467         umask $SAVE_UMASK
11468
11469         for num in $(seq $MDSCOUNT); do
11470                 if [ "${identity_old[$num]}" = 1 ]; then
11471                         switch_identity $num false || identity_old[$num]=$?
11472                 fi
11473         done
11474 }
11475 run_test 103a "acl test"
11476
11477 test_103b() {
11478         declare -a pids
11479         local U
11480
11481         for U in {0..511}; do
11482                 {
11483                 local O=$(printf "%04o" $U)
11484
11485                 umask $(printf "%04o" $((511 ^ $O)))
11486                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11487                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11488
11489                 (( $S == ($O & 0666) )) ||
11490                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11491
11492                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11493                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11494                 (( $S == ($O & 0666) )) ||
11495                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11496
11497                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11498                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11499                 (( $S == ($O & 0666) )) ||
11500                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11501                 rm -f $DIR/$tfile.[smp]$0
11502                 } &
11503                 local pid=$!
11504
11505                 # limit the concurrently running threads to 64. LU-11878
11506                 local idx=$((U % 64))
11507                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11508                 pids[idx]=$pid
11509         done
11510         wait
11511 }
11512 run_test 103b "umask lfs setstripe"
11513
11514 test_103c() {
11515         mkdir -p $DIR/$tdir
11516         cp -rp $DIR/$tdir $DIR/$tdir.bak
11517
11518         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11519                 error "$DIR/$tdir shouldn't contain default ACL"
11520         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11521                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11522         true
11523 }
11524 run_test 103c "'cp -rp' won't set empty acl"
11525
11526 test_103e() {
11527         local numacl
11528         local fileacl
11529         local saved_debug=$($LCTL get_param -n debug)
11530
11531         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
11532                 skip "MDS needs to be at least 2.14.0"
11533
11534         large_xattr_enabled || skip_env "ea_inode feature disabled"
11535
11536         mkdir -p $DIR/$tdir
11537         # add big LOV EA to cause reply buffer overflow earlier
11538         $LFS setstripe -C 1000 $DIR/$tdir
11539         lctl set_param mdc.*-mdc*.stats=clear
11540
11541         $LCTL set_param debug=0
11542         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11543         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11544
11545         # add a large number of default ACLs (expect 8000+ for 2.13+)
11546         for U in {2..7000}; do
11547                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11548                         error "Able to add just $U default ACLs"
11549         done
11550         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11551         echo "$numacl default ACLs created"
11552
11553         stat $DIR/$tdir || error "Cannot stat directory"
11554         # check file creation
11555         touch $DIR/$tdir/$tfile ||
11556                 error "failed to create $tfile with $numacl default ACLs"
11557         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11558         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11559         echo "$fileacl ACLs were inherited"
11560         (( $fileacl == $numacl )) ||
11561                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11562         # check that new ACLs creation adds new ACLs to inherited ACLs
11563         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11564                 error "Cannot set new ACL"
11565         numacl=$((numacl + 1))
11566         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11567         (( $fileacl == $numacl )) ||
11568                 error "failed to add new ACL: $fileacl != $numacl as expected"
11569         # adds more ACLs to a file to reach their maximum at 8000+
11570         numacl=0
11571         for U in {20000..25000}; do
11572                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11573                 numacl=$((numacl + 1))
11574         done
11575         echo "Added $numacl more ACLs to the file"
11576         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11577         echo "Total $fileacl ACLs in file"
11578         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11579         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11580         rmdir $DIR/$tdir || error "Cannot remove directory"
11581 }
11582 run_test 103e "inheritance of big amount of default ACLs"
11583
11584 test_103f() {
11585         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11586                 skip "MDS needs to be at least 2.14.51"
11587
11588         large_xattr_enabled || skip_env "ea_inode feature disabled"
11589
11590         # enable changelog to consume more internal MDD buffers
11591         changelog_register
11592
11593         mkdir -p $DIR/$tdir
11594         # add big LOV EA
11595         $LFS setstripe -C 1000 $DIR/$tdir
11596         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11597         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11598         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11599         rmdir $DIR/$tdir || error "Cannot remove directory"
11600 }
11601 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11602
11603 test_104a() {
11604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11605
11606         touch $DIR/$tfile
11607         lfs df || error "lfs df failed"
11608         lfs df -ih || error "lfs df -ih failed"
11609         lfs df -h $DIR || error "lfs df -h $DIR failed"
11610         lfs df -i $DIR || error "lfs df -i $DIR failed"
11611         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11612         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11613
11614         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11615         lctl --device %$OSC deactivate
11616         lfs df || error "lfs df with deactivated OSC failed"
11617         lctl --device %$OSC activate
11618         # wait the osc back to normal
11619         wait_osc_import_ready client ost
11620
11621         lfs df || error "lfs df with reactivated OSC failed"
11622         rm -f $DIR/$tfile
11623 }
11624 run_test 104a "lfs df [-ih] [path] test ========================="
11625
11626 test_104b() {
11627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11628         [ $RUNAS_ID -eq $UID ] &&
11629                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11630
11631         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11632                         grep "Permission denied" | wc -l)))
11633         if [ $denied_cnt -ne 0 ]; then
11634                 error "lfs check servers test failed"
11635         fi
11636 }
11637 run_test 104b "$RUNAS lfs check servers test ===================="
11638
11639 #
11640 # Verify $1 is within range of $2.
11641 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11642 # $1 is <= 2% of $2. Else Fail.
11643 #
11644 value_in_range() {
11645         # Strip all units (M, G, T)
11646         actual=$(echo $1 | tr -d A-Z)
11647         expect=$(echo $2 | tr -d A-Z)
11648
11649         expect_lo=$(($expect * 98 / 100)) # 2% below
11650         expect_hi=$(($expect * 102 / 100)) # 2% above
11651
11652         # permit 2% drift above and below
11653         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11654 }
11655
11656 test_104c() {
11657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11658         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11659
11660         local ost_param="osd-zfs.$FSNAME-OST0000."
11661         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11662         local ofacets=$(get_facets OST)
11663         local mfacets=$(get_facets MDS)
11664         local saved_ost_blocks=
11665         local saved_mdt_blocks=
11666
11667         echo "Before recordsize change"
11668         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11669         df=($(df -h | grep "/mnt/lustre"$))
11670
11671         # For checking.
11672         echo "lfs output : ${lfs_df[*]}"
11673         echo "df  output : ${df[*]}"
11674
11675         for facet in ${ofacets//,/ }; do
11676                 if [ -z $saved_ost_blocks ]; then
11677                         saved_ost_blocks=$(do_facet $facet \
11678                                 lctl get_param -n $ost_param.blocksize)
11679                         echo "OST Blocksize: $saved_ost_blocks"
11680                 fi
11681                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11682                 do_facet $facet zfs set recordsize=32768 $ost
11683         done
11684
11685         # BS too small. Sufficient for functional testing.
11686         for facet in ${mfacets//,/ }; do
11687                 if [ -z $saved_mdt_blocks ]; then
11688                         saved_mdt_blocks=$(do_facet $facet \
11689                                 lctl get_param -n $mdt_param.blocksize)
11690                         echo "MDT Blocksize: $saved_mdt_blocks"
11691                 fi
11692                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11693                 do_facet $facet zfs set recordsize=32768 $mdt
11694         done
11695
11696         # Give new values chance to reflect change
11697         sleep 2
11698
11699         echo "After recordsize change"
11700         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11701         df_after=($(df -h | grep "/mnt/lustre"$))
11702
11703         # For checking.
11704         echo "lfs output : ${lfs_df_after[*]}"
11705         echo "df  output : ${df_after[*]}"
11706
11707         # Verify lfs df
11708         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11709                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11710         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11711                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11712         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11713                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11714
11715         # Verify df
11716         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11717                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11718         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11719                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11720         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11721                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11722
11723         # Restore MDT recordize back to original
11724         for facet in ${mfacets//,/ }; do
11725                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11726                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11727         done
11728
11729         # Restore OST recordize back to original
11730         for facet in ${ofacets//,/ }; do
11731                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11732                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11733         done
11734
11735         return 0
11736 }
11737 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11738
11739 test_105a() {
11740         # doesn't work on 2.4 kernels
11741         touch $DIR/$tfile
11742         if $(flock_is_enabled); then
11743                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11744         else
11745                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11746         fi
11747         rm -f $DIR/$tfile
11748 }
11749 run_test 105a "flock when mounted without -o flock test ========"
11750
11751 test_105b() {
11752         touch $DIR/$tfile
11753         if $(flock_is_enabled); then
11754                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11755         else
11756                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11757         fi
11758         rm -f $DIR/$tfile
11759 }
11760 run_test 105b "fcntl when mounted without -o flock test ========"
11761
11762 test_105c() {
11763         touch $DIR/$tfile
11764         if $(flock_is_enabled); then
11765                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11766         else
11767                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11768         fi
11769         rm -f $DIR/$tfile
11770 }
11771 run_test 105c "lockf when mounted without -o flock test"
11772
11773 test_105d() { # bug 15924
11774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11775
11776         test_mkdir $DIR/$tdir
11777         flock_is_enabled || skip_env "mount w/o flock enabled"
11778         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11779         $LCTL set_param fail_loc=0x80000315
11780         flocks_test 2 $DIR/$tdir
11781 }
11782 run_test 105d "flock race (should not freeze) ========"
11783
11784 test_105e() { # bug 22660 && 22040
11785         flock_is_enabled || skip_env "mount w/o flock enabled"
11786
11787         touch $DIR/$tfile
11788         flocks_test 3 $DIR/$tfile
11789 }
11790 run_test 105e "Two conflicting flocks from same process"
11791
11792 test_106() { #bug 10921
11793         test_mkdir $DIR/$tdir
11794         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11795         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11796 }
11797 run_test 106 "attempt exec of dir followed by chown of that dir"
11798
11799 test_107() {
11800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11801
11802         CDIR=`pwd`
11803         local file=core
11804
11805         cd $DIR
11806         rm -f $file
11807
11808         local save_pattern=$(sysctl -n kernel.core_pattern)
11809         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11810         sysctl -w kernel.core_pattern=$file
11811         sysctl -w kernel.core_uses_pid=0
11812
11813         ulimit -c unlimited
11814         sleep 60 &
11815         SLEEPPID=$!
11816
11817         sleep 1
11818
11819         kill -s 11 $SLEEPPID
11820         wait $SLEEPPID
11821         if [ -e $file ]; then
11822                 size=`stat -c%s $file`
11823                 [ $size -eq 0 ] && error "Fail to create core file $file"
11824         else
11825                 error "Fail to create core file $file"
11826         fi
11827         rm -f $file
11828         sysctl -w kernel.core_pattern=$save_pattern
11829         sysctl -w kernel.core_uses_pid=$save_uses_pid
11830         cd $CDIR
11831 }
11832 run_test 107 "Coredump on SIG"
11833
11834 test_110() {
11835         test_mkdir $DIR/$tdir
11836         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11837         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11838                 error "mkdir with 256 char should fail, but did not"
11839         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11840                 error "create with 255 char failed"
11841         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11842                 error "create with 256 char should fail, but did not"
11843
11844         ls -l $DIR/$tdir
11845         rm -rf $DIR/$tdir
11846 }
11847 run_test 110 "filename length checking"
11848
11849 #
11850 # Purpose: To verify dynamic thread (OSS) creation.
11851 #
11852 test_115() {
11853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11854         remote_ost_nodsh && skip "remote OST with nodsh"
11855
11856         # Lustre does not stop service threads once they are started.
11857         # Reset number of running threads to default.
11858         stopall
11859         setupall
11860
11861         local OSTIO_pre
11862         local save_params="$TMP/sanity-$TESTNAME.parameters"
11863
11864         # Get ll_ost_io count before I/O
11865         OSTIO_pre=$(do_facet ost1 \
11866                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11867         # Exit if lustre is not running (ll_ost_io not running).
11868         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11869
11870         echo "Starting with $OSTIO_pre threads"
11871         local thread_max=$((OSTIO_pre * 2))
11872         local rpc_in_flight=$((thread_max * 2))
11873         # this is limited to OSC_MAX_RIF_MAX (256)
11874         [ $rpc_in_flight -gt 256 ] && rpc_in_flight=256
11875         thread_max=$((rpc_in_flight / 2))
11876         [ $thread_max -le $OSTIO_pre ] && skip "Too many ost_io threads" &&
11877                 return
11878
11879         # Number of I/O Process proposed to be started.
11880         local nfiles
11881         local facets=$(get_facets OST)
11882
11883         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11884         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11885
11886         # Set in_flight to $rpc_in_flight
11887         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11888                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11889         nfiles=${rpc_in_flight}
11890         # Set ost thread_max to $thread_max
11891         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11892
11893         # 5 Minutes should be sufficient for max number of OSS
11894         # threads(thread_max) to be created.
11895         local timeout=300
11896
11897         # Start I/O.
11898         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11899         test_mkdir $DIR/$tdir
11900         for i in $(seq $nfiles); do
11901                 local file=$DIR/$tdir/${tfile}-$i
11902                 $LFS setstripe -c -1 -i 0 $file
11903                 ($WTL $file $timeout)&
11904         done
11905
11906         # I/O Started - Wait for thread_started to reach thread_max or report
11907         # error if thread_started is more than thread_max.
11908         echo "Waiting for thread_started to reach thread_max"
11909         local thread_started=0
11910         local end_time=$((SECONDS + timeout))
11911
11912         while [ $SECONDS -le $end_time ] ; do
11913                 echo -n "."
11914                 # Get ost i/o thread_started count.
11915                 thread_started=$(do_facet ost1 \
11916                         "$LCTL get_param \
11917                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11918                 # Break out if thread_started is equal/greater than thread_max
11919                 if [[ $thread_started -ge $thread_max ]]; then
11920                         echo ll_ost_io thread_started $thread_started, \
11921                                 equal/greater than thread_max $thread_max
11922                         break
11923                 fi
11924                 sleep 1
11925         done
11926
11927         # Cleanup - We have the numbers, Kill i/o jobs if running.
11928         jobcount=($(jobs -p))
11929         for i in $(seq 0 $((${#jobcount[@]}-1)))
11930         do
11931                 kill -9 ${jobcount[$i]}
11932                 if [ $? -ne 0 ] ; then
11933                         echo Warning: \
11934                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11935                 fi
11936         done
11937
11938         # Cleanup files left by WTL binary.
11939         for i in $(seq $nfiles); do
11940                 local file=$DIR/$tdir/${tfile}-$i
11941                 rm -rf $file
11942                 if [ $? -ne 0 ] ; then
11943                         echo "Warning: Failed to delete file $file"
11944                 fi
11945         done
11946
11947         restore_lustre_params <$save_params
11948         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11949
11950         # Error out if no new thread has started or Thread started is greater
11951         # than thread max.
11952         if [[ $thread_started -le $OSTIO_pre ||
11953                         $thread_started -gt $thread_max ]]; then
11954                 error "ll_ost_io: thread_started $thread_started" \
11955                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11956                       "No new thread started or thread started greater " \
11957                       "than thread_max."
11958         fi
11959 }
11960 run_test 115 "verify dynamic thread creation===================="
11961
11962 free_min_max () {
11963         wait_delete_completed
11964         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11965         echo "OST kbytes available: ${AVAIL[@]}"
11966         MAXV=${AVAIL[0]}
11967         MAXI=0
11968         MINV=${AVAIL[0]}
11969         MINI=0
11970         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11971                 #echo OST $i: ${AVAIL[i]}kb
11972                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11973                         MAXV=${AVAIL[i]}
11974                         MAXI=$i
11975                 fi
11976                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11977                         MINV=${AVAIL[i]}
11978                         MINI=$i
11979                 fi
11980         done
11981         echo "Min free space: OST $MINI: $MINV"
11982         echo "Max free space: OST $MAXI: $MAXV"
11983 }
11984
11985 test_116a() { # was previously test_116()
11986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11987         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11988         remote_mds_nodsh && skip "remote MDS with nodsh"
11989
11990         echo -n "Free space priority "
11991         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11992                 head -n1
11993         declare -a AVAIL
11994         free_min_max
11995
11996         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11997         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11998         stack_trap simple_cleanup_common
11999
12000         # Check if we need to generate uneven OSTs
12001         test_mkdir -p $DIR/$tdir/OST${MINI}
12002         local FILL=$((MINV / 4))
12003         local DIFF=$((MAXV - MINV))
12004         local DIFF2=$((DIFF * 100 / MINV))
12005
12006         local threshold=$(do_facet $SINGLEMDS \
12007                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12008         threshold=${threshold%%%}
12009         echo -n "Check for uneven OSTs: "
12010         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12011
12012         if [[ $DIFF2 -gt $threshold ]]; then
12013                 echo "ok"
12014                 echo "Don't need to fill OST$MINI"
12015         else
12016                 # generate uneven OSTs. Write 2% over the QOS threshold value
12017                 echo "no"
12018                 DIFF=$((threshold - DIFF2 + 2))
12019                 DIFF2=$((MINV * DIFF / 100))
12020                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12021                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12022                         error "setstripe failed"
12023                 DIFF=$((DIFF2 / 2048))
12024                 i=0
12025                 while [ $i -lt $DIFF ]; do
12026                         i=$((i + 1))
12027                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12028                                 bs=2M count=1 2>/dev/null
12029                         echo -n .
12030                 done
12031                 echo .
12032                 sync
12033                 sleep_maxage
12034                 free_min_max
12035         fi
12036
12037         DIFF=$((MAXV - MINV))
12038         DIFF2=$((DIFF * 100 / MINV))
12039         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12040         if [ $DIFF2 -gt $threshold ]; then
12041                 echo "ok"
12042         else
12043                 skip "QOS imbalance criteria not met"
12044         fi
12045
12046         MINI1=$MINI
12047         MINV1=$MINV
12048         MAXI1=$MAXI
12049         MAXV1=$MAXV
12050
12051         # now fill using QOS
12052         $LFS setstripe -c 1 $DIR/$tdir
12053         FILL=$((FILL / 200))
12054         if [ $FILL -gt 600 ]; then
12055                 FILL=600
12056         fi
12057         echo "writing $FILL files to QOS-assigned OSTs"
12058         i=0
12059         while [ $i -lt $FILL ]; do
12060                 i=$((i + 1))
12061                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12062                         count=1 2>/dev/null
12063                 echo -n .
12064         done
12065         echo "wrote $i 200k files"
12066         sync
12067         sleep_maxage
12068
12069         echo "Note: free space may not be updated, so measurements might be off"
12070         free_min_max
12071         DIFF2=$((MAXV - MINV))
12072         echo "free space delta: orig $DIFF final $DIFF2"
12073         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12074         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12075         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12076         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12077         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12078         if [[ $DIFF -gt 0 ]]; then
12079                 FILL=$((DIFF2 * 100 / DIFF - 100))
12080                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12081         fi
12082
12083         # Figure out which files were written where
12084         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12085                awk '/'$MINI1': / {print $2; exit}')
12086         echo $UUID
12087         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12088         echo "$MINC files created on smaller OST $MINI1"
12089         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12090                awk '/'$MAXI1': / {print $2; exit}')
12091         echo $UUID
12092         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12093         echo "$MAXC files created on larger OST $MAXI1"
12094         if [[ $MINC -gt 0 ]]; then
12095                 FILL=$((MAXC * 100 / MINC - 100))
12096                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12097         fi
12098         [[ $MAXC -gt $MINC ]] ||
12099                 error_ignore LU-9 "stripe QOS didn't balance free space"
12100 }
12101 run_test 116a "stripe QOS: free space balance ==================="
12102
12103 test_116b() { # LU-2093
12104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12105         remote_mds_nodsh && skip "remote MDS with nodsh"
12106
12107 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12108         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12109                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12110         [ -z "$old_rr" ] && skip "no QOS"
12111         do_facet $SINGLEMDS lctl set_param \
12112                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12113         mkdir -p $DIR/$tdir
12114         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12115         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12116         do_facet $SINGLEMDS lctl set_param fail_loc=0
12117         rm -rf $DIR/$tdir
12118         do_facet $SINGLEMDS lctl set_param \
12119                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12120 }
12121 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12122
12123 test_117() # bug 10891
12124 {
12125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12126
12127         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12128         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12129         lctl set_param fail_loc=0x21e
12130         > $DIR/$tfile || error "truncate failed"
12131         lctl set_param fail_loc=0
12132         echo "Truncate succeeded."
12133         rm -f $DIR/$tfile
12134 }
12135 run_test 117 "verify osd extend =========="
12136
12137 NO_SLOW_RESENDCOUNT=4
12138 export OLD_RESENDCOUNT=""
12139 set_resend_count () {
12140         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12141         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12142         lctl set_param -n $PROC_RESENDCOUNT $1
12143         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12144 }
12145
12146 # for reduce test_118* time (b=14842)
12147 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12148
12149 # Reset async IO behavior after error case
12150 reset_async() {
12151         FILE=$DIR/reset_async
12152
12153         # Ensure all OSCs are cleared
12154         $LFS setstripe -c -1 $FILE
12155         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12156         sync
12157         rm $FILE
12158 }
12159
12160 test_118a() #bug 11710
12161 {
12162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12163
12164         reset_async
12165
12166         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12167         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12168         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12169
12170         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12171                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12172                 return 1;
12173         fi
12174         rm -f $DIR/$tfile
12175 }
12176 run_test 118a "verify O_SYNC works =========="
12177
12178 test_118b()
12179 {
12180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12181         remote_ost_nodsh && skip "remote OST with nodsh"
12182
12183         reset_async
12184
12185         #define OBD_FAIL_SRV_ENOENT 0x217
12186         set_nodes_failloc "$(osts_nodes)" 0x217
12187         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12188         RC=$?
12189         set_nodes_failloc "$(osts_nodes)" 0
12190         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12191         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12192                     grep -c writeback)
12193
12194         if [[ $RC -eq 0 ]]; then
12195                 error "Must return error due to dropped pages, rc=$RC"
12196                 return 1;
12197         fi
12198
12199         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12200                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12201                 return 1;
12202         fi
12203
12204         echo "Dirty pages not leaked on ENOENT"
12205
12206         # Due to the above error the OSC will issue all RPCs syncronously
12207         # until a subsequent RPC completes successfully without error.
12208         $MULTIOP $DIR/$tfile Ow4096yc
12209         rm -f $DIR/$tfile
12210
12211         return 0
12212 }
12213 run_test 118b "Reclaim dirty pages on fatal error =========="
12214
12215 test_118c()
12216 {
12217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12218
12219         # for 118c, restore the original resend count, LU-1940
12220         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12221                                 set_resend_count $OLD_RESENDCOUNT
12222         remote_ost_nodsh && skip "remote OST with nodsh"
12223
12224         reset_async
12225
12226         #define OBD_FAIL_OST_EROFS               0x216
12227         set_nodes_failloc "$(osts_nodes)" 0x216
12228
12229         # multiop should block due to fsync until pages are written
12230         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12231         MULTIPID=$!
12232         sleep 1
12233
12234         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12235                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12236         fi
12237
12238         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12239                     grep -c writeback)
12240         if [[ $WRITEBACK -eq 0 ]]; then
12241                 error "No page in writeback, writeback=$WRITEBACK"
12242         fi
12243
12244         set_nodes_failloc "$(osts_nodes)" 0
12245         wait $MULTIPID
12246         RC=$?
12247         if [[ $RC -ne 0 ]]; then
12248                 error "Multiop fsync failed, rc=$RC"
12249         fi
12250
12251         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12252         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12253                     grep -c writeback)
12254         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12255                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12256         fi
12257
12258         rm -f $DIR/$tfile
12259         echo "Dirty pages flushed via fsync on EROFS"
12260         return 0
12261 }
12262 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12263
12264 # continue to use small resend count to reduce test_118* time (b=14842)
12265 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12266
12267 test_118d()
12268 {
12269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12270         remote_ost_nodsh && skip "remote OST with nodsh"
12271
12272         reset_async
12273
12274         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12275         set_nodes_failloc "$(osts_nodes)" 0x214
12276         # multiop should block due to fsync until pages are written
12277         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12278         MULTIPID=$!
12279         sleep 1
12280
12281         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12282                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12283         fi
12284
12285         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12286                     grep -c writeback)
12287         if [[ $WRITEBACK -eq 0 ]]; then
12288                 error "No page in writeback, writeback=$WRITEBACK"
12289         fi
12290
12291         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12292         set_nodes_failloc "$(osts_nodes)" 0
12293
12294         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12295         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12296                     grep -c writeback)
12297         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12298                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12299         fi
12300
12301         rm -f $DIR/$tfile
12302         echo "Dirty pages gaurenteed flushed via fsync"
12303         return 0
12304 }
12305 run_test 118d "Fsync validation inject a delay of the bulk =========="
12306
12307 test_118f() {
12308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12309
12310         reset_async
12311
12312         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12313         lctl set_param fail_loc=0x8000040a
12314
12315         # Should simulate EINVAL error which is fatal
12316         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12317         RC=$?
12318         if [[ $RC -eq 0 ]]; then
12319                 error "Must return error due to dropped pages, rc=$RC"
12320         fi
12321
12322         lctl set_param fail_loc=0x0
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 118f "Simulate unrecoverable OSC side error =========="
12343
12344 test_118g() {
12345         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12346
12347         reset_async
12348
12349         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12350         lctl set_param fail_loc=0x406
12351
12352         # simulate local -ENOMEM
12353         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12354         RC=$?
12355
12356         lctl set_param fail_loc=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         reset_async
12377         return 0
12378 }
12379 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12380
12381 test_118h() {
12382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12383         remote_ost_nodsh && skip "remote OST with nodsh"
12384
12385         reset_async
12386
12387         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12388         set_nodes_failloc "$(osts_nodes)" 0x20e
12389         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12390         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12391         RC=$?
12392
12393         set_nodes_failloc "$(osts_nodes)" 0
12394         if [[ $RC -eq 0 ]]; then
12395                 error "Must return error due to dropped pages, rc=$RC"
12396         fi
12397
12398         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12399         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12400         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12401                     grep -c writeback)
12402         if [[ $LOCKED -ne 0 ]]; then
12403                 error "Locked pages remain in cache, locked=$LOCKED"
12404         fi
12405
12406         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12407                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12408         fi
12409
12410         rm -f $DIR/$tfile
12411         echo "No pages locked after fsync"
12412
12413         return 0
12414 }
12415 run_test 118h "Verify timeout in handling recoverables errors  =========="
12416
12417 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12418
12419 test_118i() {
12420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12421         remote_ost_nodsh && skip "remote OST with nodsh"
12422
12423         reset_async
12424
12425         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12426         set_nodes_failloc "$(osts_nodes)" 0x20e
12427
12428         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12429         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12430         PID=$!
12431         sleep 5
12432         set_nodes_failloc "$(osts_nodes)" 0
12433
12434         wait $PID
12435         RC=$?
12436         if [[ $RC -ne 0 ]]; then
12437                 error "got error, but should be not, 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         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12448                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12449         fi
12450
12451         rm -f $DIR/$tfile
12452         echo "No pages locked after fsync"
12453
12454         return 0
12455 }
12456 run_test 118i "Fix error before timeout in recoverable error  =========="
12457
12458 [ "$SLOW" = "no" ] && set_resend_count 4
12459
12460 test_118j() {
12461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12462         remote_ost_nodsh && skip "remote OST with nodsh"
12463
12464         reset_async
12465
12466         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12467         set_nodes_failloc "$(osts_nodes)" 0x220
12468
12469         # return -EIO from OST
12470         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12471         RC=$?
12472         set_nodes_failloc "$(osts_nodes)" 0x0
12473         if [[ $RC -eq 0 ]]; then
12474                 error "Must return error due to dropped pages, rc=$RC"
12475         fi
12476
12477         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12478         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12479         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12480         if [[ $LOCKED -ne 0 ]]; then
12481                 error "Locked pages remain in cache, locked=$LOCKED"
12482         fi
12483
12484         # in recoverable error on OST we want resend and stay until it finished
12485         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12486                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12487         fi
12488
12489         rm -f $DIR/$tfile
12490         echo "No pages locked after fsync"
12491
12492         return 0
12493 }
12494 run_test 118j "Simulate unrecoverable OST side error =========="
12495
12496 test_118k()
12497 {
12498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12499         remote_ost_nodsh && skip "remote OSTs with nodsh"
12500
12501         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12502         set_nodes_failloc "$(osts_nodes)" 0x20e
12503         test_mkdir $DIR/$tdir
12504
12505         for ((i=0;i<10;i++)); do
12506                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12507                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12508                 SLEEPPID=$!
12509                 sleep 0.500s
12510                 kill $SLEEPPID
12511                 wait $SLEEPPID
12512         done
12513
12514         set_nodes_failloc "$(osts_nodes)" 0
12515         rm -rf $DIR/$tdir
12516 }
12517 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12518
12519 test_118l() # LU-646
12520 {
12521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12522
12523         test_mkdir $DIR/$tdir
12524         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12525         rm -rf $DIR/$tdir
12526 }
12527 run_test 118l "fsync dir"
12528
12529 test_118m() # LU-3066
12530 {
12531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12532
12533         test_mkdir $DIR/$tdir
12534         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12535         rm -rf $DIR/$tdir
12536 }
12537 run_test 118m "fdatasync dir ========="
12538
12539 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12540
12541 test_118n()
12542 {
12543         local begin
12544         local end
12545
12546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12547         remote_ost_nodsh && skip "remote OSTs with nodsh"
12548
12549         # Sleep to avoid a cached response.
12550         #define OBD_STATFS_CACHE_SECONDS 1
12551         sleep 2
12552
12553         # Inject a 10 second delay in the OST_STATFS handler.
12554         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12555         set_nodes_failloc "$(osts_nodes)" 0x242
12556
12557         begin=$SECONDS
12558         stat --file-system $MOUNT > /dev/null
12559         end=$SECONDS
12560
12561         set_nodes_failloc "$(osts_nodes)" 0
12562
12563         if ((end - begin > 20)); then
12564             error "statfs took $((end - begin)) seconds, expected 10"
12565         fi
12566 }
12567 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12568
12569 test_119a() # bug 11737
12570 {
12571         BSIZE=$((512 * 1024))
12572         directio write $DIR/$tfile 0 1 $BSIZE
12573         # We ask to read two blocks, which is more than a file size.
12574         # directio will indicate an error when requested and actual
12575         # sizes aren't equeal (a normal situation in this case) and
12576         # print actual read amount.
12577         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12578         if [ "$NOB" != "$BSIZE" ]; then
12579                 error "read $NOB bytes instead of $BSIZE"
12580         fi
12581         rm -f $DIR/$tfile
12582 }
12583 run_test 119a "Short directIO read must return actual read amount"
12584
12585 test_119b() # bug 11737
12586 {
12587         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12588
12589         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12590         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12591         sync
12592         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12593                 error "direct read failed"
12594         rm -f $DIR/$tfile
12595 }
12596 run_test 119b "Sparse directIO read must return actual read amount"
12597
12598 test_119c() # bug 13099
12599 {
12600         BSIZE=1048576
12601         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12602         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12603         rm -f $DIR/$tfile
12604 }
12605 run_test 119c "Testing for direct read hitting hole"
12606
12607 test_119d() # bug 15950
12608 {
12609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12610
12611         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12612         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12613         BSIZE=1048576
12614         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12615         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12616         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12617         lctl set_param fail_loc=0x40d
12618         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12619         pid_dio=$!
12620         sleep 1
12621         cat $DIR/$tfile > /dev/null &
12622         lctl set_param fail_loc=0
12623         pid_reads=$!
12624         wait $pid_dio
12625         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12626         sleep 2
12627         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12628         error "the read rpcs have not completed in 2s"
12629         rm -f $DIR/$tfile
12630         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12631 }
12632 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12633
12634 test_120a() {
12635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12636         remote_mds_nodsh && skip "remote MDS with nodsh"
12637         test_mkdir -i0 -c1 $DIR/$tdir
12638         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12639                 skip_env "no early lock cancel on server"
12640
12641         lru_resize_disable mdc
12642         lru_resize_disable osc
12643         cancel_lru_locks mdc
12644         # asynchronous object destroy at MDT could cause bl ast to client
12645         cancel_lru_locks osc
12646
12647         stat $DIR/$tdir > /dev/null
12648         can1=$(do_facet mds1 \
12649                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12650                awk '/ldlm_cancel/ {print $2}')
12651         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12652                awk '/ldlm_bl_callback/ {print $2}')
12653         test_mkdir -i0 -c1 $DIR/$tdir/d1
12654         can2=$(do_facet mds1 \
12655                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12656                awk '/ldlm_cancel/ {print $2}')
12657         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12658                awk '/ldlm_bl_callback/ {print $2}')
12659         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12660         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12661         lru_resize_enable mdc
12662         lru_resize_enable osc
12663 }
12664 run_test 120a "Early Lock Cancel: mkdir test"
12665
12666 test_120b() {
12667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12668         remote_mds_nodsh && skip "remote MDS with nodsh"
12669         test_mkdir $DIR/$tdir
12670         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12671                 skip_env "no early lock cancel on server"
12672
12673         lru_resize_disable mdc
12674         lru_resize_disable osc
12675         cancel_lru_locks mdc
12676         stat $DIR/$tdir > /dev/null
12677         can1=$(do_facet $SINGLEMDS \
12678                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12679                awk '/ldlm_cancel/ {print $2}')
12680         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12681                awk '/ldlm_bl_callback/ {print $2}')
12682         touch $DIR/$tdir/f1
12683         can2=$(do_facet $SINGLEMDS \
12684                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12685                awk '/ldlm_cancel/ {print $2}')
12686         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12687                awk '/ldlm_bl_callback/ {print $2}')
12688         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12689         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12690         lru_resize_enable mdc
12691         lru_resize_enable osc
12692 }
12693 run_test 120b "Early Lock Cancel: create test"
12694
12695 test_120c() {
12696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12697         remote_mds_nodsh && skip "remote MDS with nodsh"
12698         test_mkdir -i0 -c1 $DIR/$tdir
12699         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12700                 skip "no early lock cancel on server"
12701
12702         lru_resize_disable mdc
12703         lru_resize_disable osc
12704         test_mkdir -i0 -c1 $DIR/$tdir/d1
12705         test_mkdir -i0 -c1 $DIR/$tdir/d2
12706         touch $DIR/$tdir/d1/f1
12707         cancel_lru_locks mdc
12708         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12709         can1=$(do_facet mds1 \
12710                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12711                awk '/ldlm_cancel/ {print $2}')
12712         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12713                awk '/ldlm_bl_callback/ {print $2}')
12714         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12715         can2=$(do_facet mds1 \
12716                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12717                awk '/ldlm_cancel/ {print $2}')
12718         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12719                awk '/ldlm_bl_callback/ {print $2}')
12720         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12721         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12722         lru_resize_enable mdc
12723         lru_resize_enable osc
12724 }
12725 run_test 120c "Early Lock Cancel: link test"
12726
12727 test_120d() {
12728         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12729         remote_mds_nodsh && skip "remote MDS with nodsh"
12730         test_mkdir -i0 -c1 $DIR/$tdir
12731         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12732                 skip_env "no early lock cancel on server"
12733
12734         lru_resize_disable mdc
12735         lru_resize_disable osc
12736         touch $DIR/$tdir
12737         cancel_lru_locks mdc
12738         stat $DIR/$tdir > /dev/null
12739         can1=$(do_facet mds1 \
12740                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12741                awk '/ldlm_cancel/ {print $2}')
12742         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12743                awk '/ldlm_bl_callback/ {print $2}')
12744         chmod a+x $DIR/$tdir
12745         can2=$(do_facet mds1 \
12746                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12747                awk '/ldlm_cancel/ {print $2}')
12748         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12749                awk '/ldlm_bl_callback/ {print $2}')
12750         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12751         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12752         lru_resize_enable mdc
12753         lru_resize_enable osc
12754 }
12755 run_test 120d "Early Lock Cancel: setattr test"
12756
12757 test_120e() {
12758         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12759         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12760                 skip_env "no early lock cancel on server"
12761         remote_mds_nodsh && skip "remote MDS with nodsh"
12762
12763         local dlmtrace_set=false
12764
12765         test_mkdir -i0 -c1 $DIR/$tdir
12766         lru_resize_disable mdc
12767         lru_resize_disable osc
12768         ! $LCTL get_param debug | grep -q dlmtrace &&
12769                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12770         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12771         cancel_lru_locks mdc
12772         cancel_lru_locks osc
12773         dd if=$DIR/$tdir/f1 of=/dev/null
12774         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12775         # XXX client can not do early lock cancel of OST lock
12776         # during unlink (LU-4206), so cancel osc lock now.
12777         sleep 2
12778         cancel_lru_locks osc
12779         can1=$(do_facet mds1 \
12780                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12781                awk '/ldlm_cancel/ {print $2}')
12782         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12783                awk '/ldlm_bl_callback/ {print $2}')
12784         unlink $DIR/$tdir/f1
12785         sleep 5
12786         can2=$(do_facet mds1 \
12787                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12788                awk '/ldlm_cancel/ {print $2}')
12789         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12790                awk '/ldlm_bl_callback/ {print $2}')
12791         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12792                 $LCTL dk $TMP/cancel.debug.txt
12793         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12794                 $LCTL dk $TMP/blocking.debug.txt
12795         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12796         lru_resize_enable mdc
12797         lru_resize_enable osc
12798 }
12799 run_test 120e "Early Lock Cancel: unlink test"
12800
12801 test_120f() {
12802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12803         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12804                 skip_env "no early lock cancel on server"
12805         remote_mds_nodsh && skip "remote MDS with nodsh"
12806
12807         test_mkdir -i0 -c1 $DIR/$tdir
12808         lru_resize_disable mdc
12809         lru_resize_disable osc
12810         test_mkdir -i0 -c1 $DIR/$tdir/d1
12811         test_mkdir -i0 -c1 $DIR/$tdir/d2
12812         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12813         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12814         cancel_lru_locks mdc
12815         cancel_lru_locks osc
12816         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12817         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12818         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12819         # XXX client can not do early lock cancel of OST lock
12820         # during rename (LU-4206), so cancel osc lock now.
12821         sleep 2
12822         cancel_lru_locks osc
12823         can1=$(do_facet mds1 \
12824                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12825                awk '/ldlm_cancel/ {print $2}')
12826         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12827                awk '/ldlm_bl_callback/ {print $2}')
12828         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12829         sleep 5
12830         can2=$(do_facet mds1 \
12831                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12832                awk '/ldlm_cancel/ {print $2}')
12833         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12834                awk '/ldlm_bl_callback/ {print $2}')
12835         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12836         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12837         lru_resize_enable mdc
12838         lru_resize_enable osc
12839 }
12840 run_test 120f "Early Lock Cancel: rename test"
12841
12842 test_120g() {
12843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12844         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12845                 skip_env "no early lock cancel on server"
12846         remote_mds_nodsh && skip "remote MDS with nodsh"
12847
12848         lru_resize_disable mdc
12849         lru_resize_disable osc
12850         count=10000
12851         echo create $count files
12852         test_mkdir $DIR/$tdir
12853         cancel_lru_locks mdc
12854         cancel_lru_locks osc
12855         t0=$(date +%s)
12856
12857         can0=$(do_facet $SINGLEMDS \
12858                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12859                awk '/ldlm_cancel/ {print $2}')
12860         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12861                awk '/ldlm_bl_callback/ {print $2}')
12862         createmany -o $DIR/$tdir/f $count
12863         sync
12864         can1=$(do_facet $SINGLEMDS \
12865                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12866                awk '/ldlm_cancel/ {print $2}')
12867         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12868                awk '/ldlm_bl_callback/ {print $2}')
12869         t1=$(date +%s)
12870         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12871         echo rm $count files
12872         rm -r $DIR/$tdir
12873         sync
12874         can2=$(do_facet $SINGLEMDS \
12875                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12876                awk '/ldlm_cancel/ {print $2}')
12877         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12878                awk '/ldlm_bl_callback/ {print $2}')
12879         t2=$(date +%s)
12880         echo total: $count removes in $((t2-t1))
12881         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12882         sleep 2
12883         # wait for commitment of removal
12884         lru_resize_enable mdc
12885         lru_resize_enable osc
12886 }
12887 run_test 120g "Early Lock Cancel: performance test"
12888
12889 test_121() { #bug #10589
12890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12891
12892         rm -rf $DIR/$tfile
12893         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12894 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12895         lctl set_param fail_loc=0x310
12896         cancel_lru_locks osc > /dev/null
12897         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12898         lctl set_param fail_loc=0
12899         [[ $reads -eq $writes ]] ||
12900                 error "read $reads blocks, must be $writes blocks"
12901 }
12902 run_test 121 "read cancel race ========="
12903
12904 test_123a_base() { # was test 123, statahead(bug 11401)
12905         local lsx="$1"
12906
12907         SLOWOK=0
12908         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12909                 log "testing UP system. Performance may be lower than expected."
12910                 SLOWOK=1
12911         fi
12912
12913         rm -rf $DIR/$tdir
12914         test_mkdir $DIR/$tdir
12915         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12916         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12917         MULT=10
12918         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12919                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12920
12921                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12922                 lctl set_param -n llite.*.statahead_max 0
12923                 lctl get_param llite.*.statahead_max
12924                 cancel_lru_locks mdc
12925                 cancel_lru_locks osc
12926                 stime=$(date +%s)
12927                 time $lsx $DIR/$tdir | wc -l
12928                 etime=$(date +%s)
12929                 delta=$((etime - stime))
12930                 log "$lsx $i files without statahead: $delta sec"
12931                 lctl set_param llite.*.statahead_max=$max
12932
12933                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12934                         grep "statahead wrong:" | awk '{print $3}')
12935                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12936                 cancel_lru_locks mdc
12937                 cancel_lru_locks osc
12938                 stime=$(date +%s)
12939                 time $lsx $DIR/$tdir | wc -l
12940                 etime=$(date +%s)
12941                 delta_sa=$((etime - stime))
12942                 log "$lsx $i files with statahead: $delta_sa sec"
12943                 lctl get_param -n llite.*.statahead_stats
12944                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12945                         grep "statahead wrong:" | awk '{print $3}')
12946
12947                 [[ $swrong -lt $ewrong ]] &&
12948                         log "statahead was stopped, maybe too many locks held!"
12949                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12950
12951                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12952                         max=$(lctl get_param -n llite.*.statahead_max |
12953                                 head -n 1)
12954                         lctl set_param -n llite.*.statahead_max 0
12955                         lctl get_param llite.*.statahead_max
12956                         cancel_lru_locks mdc
12957                         cancel_lru_locks osc
12958                         stime=$(date +%s)
12959                         time $lsx $DIR/$tdir | wc -l
12960                         etime=$(date +%s)
12961                         delta=$((etime - stime))
12962                         log "$lsx $i files again without statahead: $delta sec"
12963                         lctl set_param llite.*.statahead_max=$max
12964                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12965                                 if [  $SLOWOK -eq 0 ]; then
12966                                         error "$lsx $i files is slower with statahead!"
12967                                 else
12968                                         log "$lsx $i files is slower with statahead!"
12969                                 fi
12970                                 break
12971                         fi
12972                 fi
12973
12974                 [ $delta -gt 20 ] && break
12975                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12976                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12977         done
12978         log "$lsx done"
12979
12980         stime=$(date +%s)
12981         rm -r $DIR/$tdir
12982         sync
12983         etime=$(date +%s)
12984         delta=$((etime - stime))
12985         log "rm -r $DIR/$tdir/: $delta seconds"
12986         log "rm done"
12987         lctl get_param -n llite.*.statahead_stats
12988 }
12989
12990 test_123aa() {
12991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12992
12993         test_123a_base "ls -l"
12994 }
12995 run_test 123aa "verify statahead work"
12996
12997 test_123ab() {
12998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12999
13000         statx_supported || skip_env "Test must be statx() syscall supported"
13001
13002         test_123a_base "$STATX -l"
13003 }
13004 run_test 123ab "verify statahead work by using statx"
13005
13006 test_123ac() {
13007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13008
13009         statx_supported || skip_env "Test must be statx() syscall supported"
13010
13011         local rpcs_before
13012         local rpcs_after
13013         local agl_before
13014         local agl_after
13015
13016         cancel_lru_locks $OSC
13017         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13018         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13019                 awk '/agl.total:/ {print $3}')
13020         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13021         test_123a_base "$STATX --cached=always -D"
13022         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13023                 awk '/agl.total:/ {print $3}')
13024         [ $agl_before -eq $agl_after ] ||
13025                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13026         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13027         [ $rpcs_after -eq $rpcs_before ] ||
13028                 error "$STATX should not send glimpse RPCs to $OSC"
13029 }
13030 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13031
13032 test_123b () { # statahead(bug 15027)
13033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13034
13035         test_mkdir $DIR/$tdir
13036         createmany -o $DIR/$tdir/$tfile-%d 1000
13037
13038         cancel_lru_locks mdc
13039         cancel_lru_locks osc
13040
13041 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13042         lctl set_param fail_loc=0x80000803
13043         ls -lR $DIR/$tdir > /dev/null
13044         log "ls done"
13045         lctl set_param fail_loc=0x0
13046         lctl get_param -n llite.*.statahead_stats
13047         rm -r $DIR/$tdir
13048         sync
13049
13050 }
13051 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13052
13053 test_123c() {
13054         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13055
13056         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13057         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13058         touch $DIR/$tdir.1/{1..3}
13059         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13060
13061         remount_client $MOUNT
13062
13063         $MULTIOP $DIR/$tdir.0 Q
13064
13065         # let statahead to complete
13066         ls -l $DIR/$tdir.0 > /dev/null
13067
13068         testid=$(echo $TESTNAME | tr '_' ' ')
13069         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13070                 error "statahead warning" || true
13071 }
13072 run_test 123c "Can not initialize inode warning on DNE statahead"
13073
13074 test_124a() {
13075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13076         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13077                 skip_env "no lru resize on server"
13078
13079         local NR=2000
13080
13081         test_mkdir $DIR/$tdir
13082
13083         log "create $NR files at $DIR/$tdir"
13084         createmany -o $DIR/$tdir/f $NR ||
13085                 error "failed to create $NR files in $DIR/$tdir"
13086
13087         cancel_lru_locks mdc
13088         ls -l $DIR/$tdir > /dev/null
13089
13090         local NSDIR=""
13091         local LRU_SIZE=0
13092         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13093                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13094                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13095                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13096                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13097                         log "NSDIR=$NSDIR"
13098                         log "NS=$(basename $NSDIR)"
13099                         break
13100                 fi
13101         done
13102
13103         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13104                 skip "Not enough cached locks created!"
13105         fi
13106         log "LRU=$LRU_SIZE"
13107
13108         local SLEEP=30
13109
13110         # We know that lru resize allows one client to hold $LIMIT locks
13111         # for 10h. After that locks begin to be killed by client.
13112         local MAX_HRS=10
13113         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13114         log "LIMIT=$LIMIT"
13115         if [ $LIMIT -lt $LRU_SIZE ]; then
13116                 skip "Limit is too small $LIMIT"
13117         fi
13118
13119         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13120         # killing locks. Some time was spent for creating locks. This means
13121         # that up to the moment of sleep finish we must have killed some of
13122         # them (10-100 locks). This depends on how fast ther were created.
13123         # Many of them were touched in almost the same moment and thus will
13124         # be killed in groups.
13125         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13126
13127         # Use $LRU_SIZE_B here to take into account real number of locks
13128         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13129         local LRU_SIZE_B=$LRU_SIZE
13130         log "LVF=$LVF"
13131         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13132         log "OLD_LVF=$OLD_LVF"
13133         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13134
13135         # Let's make sure that we really have some margin. Client checks
13136         # cached locks every 10 sec.
13137         SLEEP=$((SLEEP+20))
13138         log "Sleep ${SLEEP} sec"
13139         local SEC=0
13140         while ((SEC<$SLEEP)); do
13141                 echo -n "..."
13142                 sleep 5
13143                 SEC=$((SEC+5))
13144                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13145                 echo -n "$LRU_SIZE"
13146         done
13147         echo ""
13148         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13149         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13150
13151         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13152                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13153                 unlinkmany $DIR/$tdir/f $NR
13154                 return
13155         }
13156
13157         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13158         log "unlink $NR files at $DIR/$tdir"
13159         unlinkmany $DIR/$tdir/f $NR
13160 }
13161 run_test 124a "lru resize ======================================="
13162
13163 get_max_pool_limit()
13164 {
13165         local limit=$($LCTL get_param \
13166                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13167         local max=0
13168         for l in $limit; do
13169                 if [[ $l -gt $max ]]; then
13170                         max=$l
13171                 fi
13172         done
13173         echo $max
13174 }
13175
13176 test_124b() {
13177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13178         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13179                 skip_env "no lru resize on server"
13180
13181         LIMIT=$(get_max_pool_limit)
13182
13183         NR=$(($(default_lru_size)*20))
13184         if [[ $NR -gt $LIMIT ]]; then
13185                 log "Limit lock number by $LIMIT locks"
13186                 NR=$LIMIT
13187         fi
13188
13189         IFree=$(mdsrate_inodes_available)
13190         if [ $IFree -lt $NR ]; then
13191                 log "Limit lock number by $IFree inodes"
13192                 NR=$IFree
13193         fi
13194
13195         lru_resize_disable mdc
13196         test_mkdir -p $DIR/$tdir/disable_lru_resize
13197
13198         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13199         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13200         cancel_lru_locks mdc
13201         stime=`date +%s`
13202         PID=""
13203         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13204         PID="$PID $!"
13205         sleep 2
13206         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13207         PID="$PID $!"
13208         sleep 2
13209         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13210         PID="$PID $!"
13211         wait $PID
13212         etime=`date +%s`
13213         nolruresize_delta=$((etime-stime))
13214         log "ls -la time: $nolruresize_delta seconds"
13215         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13216         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13217
13218         lru_resize_enable mdc
13219         test_mkdir -p $DIR/$tdir/enable_lru_resize
13220
13221         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13222         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13223         cancel_lru_locks mdc
13224         stime=`date +%s`
13225         PID=""
13226         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13227         PID="$PID $!"
13228         sleep 2
13229         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13230         PID="$PID $!"
13231         sleep 2
13232         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13233         PID="$PID $!"
13234         wait $PID
13235         etime=`date +%s`
13236         lruresize_delta=$((etime-stime))
13237         log "ls -la time: $lruresize_delta seconds"
13238         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13239
13240         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13241                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13242         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13243                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13244         else
13245                 log "lru resize performs the same with no lru resize"
13246         fi
13247         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13248 }
13249 run_test 124b "lru resize (performance test) ======================="
13250
13251 test_124c() {
13252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13253         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13254                 skip_env "no lru resize on server"
13255
13256         # cache ununsed locks on client
13257         local nr=100
13258         cancel_lru_locks mdc
13259         test_mkdir $DIR/$tdir
13260         createmany -o $DIR/$tdir/f $nr ||
13261                 error "failed to create $nr files in $DIR/$tdir"
13262         ls -l $DIR/$tdir > /dev/null
13263
13264         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13265         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13266         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13267         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13268         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13269
13270         # set lru_max_age to 1 sec
13271         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13272         echo "sleep $((recalc_p * 2)) seconds..."
13273         sleep $((recalc_p * 2))
13274
13275         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13276         # restore lru_max_age
13277         $LCTL set_param -n $nsdir.lru_max_age $max_age
13278         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13279         unlinkmany $DIR/$tdir/f $nr
13280 }
13281 run_test 124c "LRUR cancel very aged locks"
13282
13283 test_124d() {
13284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13285         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13286                 skip_env "no lru resize on server"
13287
13288         # cache ununsed locks on client
13289         local nr=100
13290
13291         lru_resize_disable mdc
13292         stack_trap "lru_resize_enable mdc" EXIT
13293
13294         cancel_lru_locks mdc
13295
13296         # asynchronous object destroy at MDT could cause bl ast to client
13297         test_mkdir $DIR/$tdir
13298         createmany -o $DIR/$tdir/f $nr ||
13299                 error "failed to create $nr files in $DIR/$tdir"
13300         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13301
13302         ls -l $DIR/$tdir > /dev/null
13303
13304         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13305         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13306         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13307         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13308
13309         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13310
13311         # set lru_max_age to 1 sec
13312         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13313         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13314
13315         echo "sleep $((recalc_p * 2)) seconds..."
13316         sleep $((recalc_p * 2))
13317
13318         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13319
13320         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13321 }
13322 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13323
13324 test_125() { # 13358
13325         $LCTL get_param -n llite.*.client_type | grep -q local ||
13326                 skip "must run as local client"
13327         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13328                 skip_env "must have acl enabled"
13329         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13330
13331         test_mkdir $DIR/$tdir
13332         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13333         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13334         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13335 }
13336 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13337
13338 test_126() { # bug 12829/13455
13339         $GSS && skip_env "must run as gss disabled"
13340         $LCTL get_param -n llite.*.client_type | grep -q local ||
13341                 skip "must run as local client"
13342         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13343
13344         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13345         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13346         rm -f $DIR/$tfile
13347         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13348 }
13349 run_test 126 "check that the fsgid provided by the client is taken into account"
13350
13351 test_127a() { # bug 15521
13352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13353         local name count samp unit min max sum sumsq
13354
13355         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13356         echo "stats before reset"
13357         $LCTL get_param osc.*.stats
13358         $LCTL set_param osc.*.stats=0
13359         local fsize=$((2048 * 1024))
13360
13361         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13362         cancel_lru_locks osc
13363         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13364
13365         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13366         stack_trap "rm -f $TMP/$tfile.tmp"
13367         while read name count samp unit min max sum sumsq; do
13368                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13369                 [ ! $min ] && error "Missing min value for $name proc entry"
13370                 eval $name=$count || error "Wrong proc format"
13371
13372                 case $name in
13373                 read_bytes|write_bytes)
13374                         [[ "$unit" =~ "bytes" ]] ||
13375                                 error "unit is not 'bytes': $unit"
13376                         (( $min >= 4096 )) || error "min is too small: $min"
13377                         (( $min <= $fsize )) || error "min is too big: $min"
13378                         (( $max >= 4096 )) || error "max is too small: $max"
13379                         (( $max <= $fsize )) || error "max is too big: $max"
13380                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13381                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13382                                 error "sumsquare is too small: $sumsq"
13383                         (( $sumsq <= $fsize * $fsize )) ||
13384                                 error "sumsquare is too big: $sumsq"
13385                         ;;
13386                 ost_read|ost_write)
13387                         [[ "$unit" =~ "usec" ]] ||
13388                                 error "unit is not 'usec': $unit"
13389                         ;;
13390                 *)      ;;
13391                 esac
13392         done < $DIR/$tfile.tmp
13393
13394         #check that we actually got some stats
13395         [ "$read_bytes" ] || error "Missing read_bytes stats"
13396         [ "$write_bytes" ] || error "Missing write_bytes stats"
13397         [ "$read_bytes" != 0 ] || error "no read done"
13398         [ "$write_bytes" != 0 ] || error "no write done"
13399 }
13400 run_test 127a "verify the client stats are sane"
13401
13402 test_127b() { # bug LU-333
13403         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13404         local name count samp unit min max sum sumsq
13405
13406         echo "stats before reset"
13407         $LCTL get_param llite.*.stats
13408         $LCTL set_param llite.*.stats=0
13409
13410         # perform 2 reads and writes so MAX is different from SUM.
13411         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13412         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13413         cancel_lru_locks osc
13414         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13415         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13416
13417         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13418         stack_trap "rm -f $TMP/$tfile.tmp"
13419         while read name count samp unit min max sum sumsq; do
13420                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13421                 eval $name=$count || error "Wrong proc format"
13422
13423                 case $name in
13424                 read_bytes|write_bytes)
13425                         [[ "$unit" =~ "bytes" ]] ||
13426                                 error "unit is not 'bytes': $unit"
13427                         (( $count == 2 )) || error "count is not 2: $count"
13428                         (( $min == $PAGE_SIZE )) ||
13429                                 error "min is not $PAGE_SIZE: $min"
13430                         (( $max == $PAGE_SIZE )) ||
13431                                 error "max is not $PAGE_SIZE: $max"
13432                         (( $sum == $PAGE_SIZE * 2 )) ||
13433                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13434                         ;;
13435                 read|write)
13436                         [[ "$unit" =~ "usec" ]] ||
13437                                 error "unit is not 'usec': $unit"
13438                         ;;
13439                 *)      ;;
13440                 esac
13441         done < $TMP/$tfile.tmp
13442
13443         #check that we actually got some stats
13444         [ "$read_bytes" ] || error "Missing read_bytes stats"
13445         [ "$write_bytes" ] || error "Missing write_bytes stats"
13446         [ "$read_bytes" != 0 ] || error "no read done"
13447         [ "$write_bytes" != 0 ] || error "no write done"
13448 }
13449 run_test 127b "verify the llite client stats are sane"
13450
13451 test_127c() { # LU-12394
13452         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13453         local size
13454         local bsize
13455         local reads
13456         local writes
13457         local count
13458
13459         $LCTL set_param llite.*.extents_stats=1
13460         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13461
13462         # Use two stripes so there is enough space in default config
13463         $LFS setstripe -c 2 $DIR/$tfile
13464
13465         # Extent stats start at 0-4K and go in power of two buckets
13466         # LL_HIST_START = 12 --> 2^12 = 4K
13467         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13468         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13469         # small configs
13470         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13471                 do
13472                 # Write and read, 2x each, second time at a non-zero offset
13473                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13474                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13475                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13476                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13477                 rm -f $DIR/$tfile
13478         done
13479
13480         $LCTL get_param llite.*.extents_stats
13481
13482         count=2
13483         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13484                 do
13485                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13486                                 grep -m 1 $bsize)
13487                 reads=$(echo $bucket | awk '{print $5}')
13488                 writes=$(echo $bucket | awk '{print $9}')
13489                 [ "$reads" -eq $count ] ||
13490                         error "$reads reads in < $bsize bucket, expect $count"
13491                 [ "$writes" -eq $count ] ||
13492                         error "$writes writes in < $bsize bucket, expect $count"
13493         done
13494
13495         # Test mmap write and read
13496         $LCTL set_param llite.*.extents_stats=c
13497         size=512
13498         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13499         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13500         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13501
13502         $LCTL get_param llite.*.extents_stats
13503
13504         count=$(((size*1024) / PAGE_SIZE))
13505
13506         bsize=$((2 * PAGE_SIZE / 1024))K
13507
13508         bucket=$($LCTL get_param -n llite.*.extents_stats |
13509                         grep -m 1 $bsize)
13510         reads=$(echo $bucket | awk '{print $5}')
13511         writes=$(echo $bucket | awk '{print $9}')
13512         # mmap writes fault in the page first, creating an additonal read
13513         [ "$reads" -eq $((2 * count)) ] ||
13514                 error "$reads reads in < $bsize bucket, expect $count"
13515         [ "$writes" -eq $count ] ||
13516                 error "$writes writes in < $bsize bucket, expect $count"
13517 }
13518 run_test 127c "test llite extent stats with regular & mmap i/o"
13519
13520 test_128() { # bug 15212
13521         touch $DIR/$tfile
13522         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13523                 find $DIR/$tfile
13524                 find $DIR/$tfile
13525         EOF
13526
13527         result=$(grep error $TMP/$tfile.log)
13528         rm -f $DIR/$tfile $TMP/$tfile.log
13529         [ -z "$result" ] ||
13530                 error "consecutive find's under interactive lfs failed"
13531 }
13532 run_test 128 "interactive lfs for 2 consecutive find's"
13533
13534 set_dir_limits () {
13535         local mntdev
13536         local canondev
13537         local node
13538
13539         local ldproc=/proc/fs/ldiskfs
13540         local facets=$(get_facets MDS)
13541
13542         for facet in ${facets//,/ }; do
13543                 canondev=$(ldiskfs_canon \
13544                            *.$(convert_facet2label $facet).mntdev $facet)
13545                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13546                         ldproc=/sys/fs/ldiskfs
13547                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13548                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13549         done
13550 }
13551
13552 check_mds_dmesg() {
13553         local facets=$(get_facets MDS)
13554         for facet in ${facets//,/ }; do
13555                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13556         done
13557         return 1
13558 }
13559
13560 test_129() {
13561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13562         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13563                 skip "Need MDS version with at least 2.5.56"
13564         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13565                 skip_env "ldiskfs only test"
13566         fi
13567         remote_mds_nodsh && skip "remote MDS with nodsh"
13568
13569         local ENOSPC=28
13570         local has_warning=false
13571
13572         rm -rf $DIR/$tdir
13573         mkdir -p $DIR/$tdir
13574
13575         # block size of mds1
13576         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13577         set_dir_limits $maxsize $((maxsize * 6 / 8))
13578         stack_trap "set_dir_limits 0 0"
13579         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13580         local dirsize=$(stat -c%s "$DIR/$tdir")
13581         local nfiles=0
13582         while (( $dirsize <= $maxsize )); do
13583                 $MCREATE $DIR/$tdir/file_base_$nfiles
13584                 rc=$?
13585                 # check two errors:
13586                 # ENOSPC for ext4 max_dir_size, which has been used since
13587                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13588                 if (( rc == ENOSPC )); then
13589                         set_dir_limits 0 0
13590                         echo "rc=$rc returned as expected after $nfiles files"
13591
13592                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13593                                 error "create failed w/o dir size limit"
13594
13595                         # messages may be rate limited if test is run repeatedly
13596                         check_mds_dmesg '"is approaching max"' ||
13597                                 echo "warning message should be output"
13598                         check_mds_dmesg '"has reached max"' ||
13599                                 echo "reached message should be output"
13600
13601                         dirsize=$(stat -c%s "$DIR/$tdir")
13602
13603                         [[ $dirsize -ge $maxsize ]] && return 0
13604                         error "dirsize $dirsize < $maxsize after $nfiles files"
13605                 elif (( rc != 0 )); then
13606                         break
13607                 fi
13608                 nfiles=$((nfiles + 1))
13609                 dirsize=$(stat -c%s "$DIR/$tdir")
13610         done
13611
13612         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13613 }
13614 run_test 129 "test directory size limit ========================"
13615
13616 OLDIFS="$IFS"
13617 cleanup_130() {
13618         trap 0
13619         IFS="$OLDIFS"
13620 }
13621
13622 test_130a() {
13623         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13624         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13625
13626         trap cleanup_130 EXIT RETURN
13627
13628         local fm_file=$DIR/$tfile
13629         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13630         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13631                 error "dd failed for $fm_file"
13632
13633         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13634         filefrag -ves $fm_file
13635         RC=$?
13636         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13637                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13638         [ $RC != 0 ] && error "filefrag $fm_file failed"
13639
13640         filefrag_op=$(filefrag -ve -k $fm_file |
13641                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13642         lun=$($LFS getstripe -i $fm_file)
13643
13644         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13645         IFS=$'\n'
13646         tot_len=0
13647         for line in $filefrag_op
13648         do
13649                 frag_lun=`echo $line | cut -d: -f5`
13650                 ext_len=`echo $line | cut -d: -f4`
13651                 if (( $frag_lun != $lun )); then
13652                         cleanup_130
13653                         error "FIEMAP on 1-stripe file($fm_file) failed"
13654                         return
13655                 fi
13656                 (( tot_len += ext_len ))
13657         done
13658
13659         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13660                 cleanup_130
13661                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13662                 return
13663         fi
13664
13665         cleanup_130
13666
13667         echo "FIEMAP on single striped file succeeded"
13668 }
13669 run_test 130a "FIEMAP (1-stripe file)"
13670
13671 test_130b() {
13672         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13673
13674         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13675         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13676
13677         trap cleanup_130 EXIT RETURN
13678
13679         local fm_file=$DIR/$tfile
13680         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13681                         error "setstripe on $fm_file"
13682         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13683                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13684
13685         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13686                 error "dd failed on $fm_file"
13687
13688         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13689         filefrag_op=$(filefrag -ve -k $fm_file |
13690                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13691
13692         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13693                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13694
13695         IFS=$'\n'
13696         tot_len=0
13697         num_luns=1
13698         for line in $filefrag_op
13699         do
13700                 frag_lun=$(echo $line | cut -d: -f5 |
13701                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13702                 ext_len=$(echo $line | cut -d: -f4)
13703                 if (( $frag_lun != $last_lun )); then
13704                         if (( tot_len != 1024 )); then
13705                                 cleanup_130
13706                                 error "FIEMAP on $fm_file failed; returned " \
13707                                 "len $tot_len for OST $last_lun instead of 1024"
13708                                 return
13709                         else
13710                                 (( num_luns += 1 ))
13711                                 tot_len=0
13712                         fi
13713                 fi
13714                 (( tot_len += ext_len ))
13715                 last_lun=$frag_lun
13716         done
13717         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13718                 cleanup_130
13719                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13720                         "luns or wrong len for OST $last_lun"
13721                 return
13722         fi
13723
13724         cleanup_130
13725
13726         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13727 }
13728 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13729
13730 test_130c() {
13731         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13732
13733         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13734         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13735
13736         trap cleanup_130 EXIT RETURN
13737
13738         local fm_file=$DIR/$tfile
13739         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13740         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13741                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13742
13743         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13744                         error "dd failed on $fm_file"
13745
13746         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13747         filefrag_op=$(filefrag -ve -k $fm_file |
13748                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13749
13750         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13751                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13752
13753         IFS=$'\n'
13754         tot_len=0
13755         num_luns=1
13756         for line in $filefrag_op
13757         do
13758                 frag_lun=$(echo $line | cut -d: -f5 |
13759                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13760                 ext_len=$(echo $line | cut -d: -f4)
13761                 if (( $frag_lun != $last_lun )); then
13762                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13763                         if (( logical != 512 )); then
13764                                 cleanup_130
13765                                 error "FIEMAP on $fm_file failed; returned " \
13766                                 "logical start for lun $logical instead of 512"
13767                                 return
13768                         fi
13769                         if (( tot_len != 512 )); then
13770                                 cleanup_130
13771                                 error "FIEMAP on $fm_file failed; returned " \
13772                                 "len $tot_len for OST $last_lun instead of 1024"
13773                                 return
13774                         else
13775                                 (( num_luns += 1 ))
13776                                 tot_len=0
13777                         fi
13778                 fi
13779                 (( tot_len += ext_len ))
13780                 last_lun=$frag_lun
13781         done
13782         if (( num_luns != 2 || tot_len != 512 )); then
13783                 cleanup_130
13784                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13785                         "luns or wrong len for OST $last_lun"
13786                 return
13787         fi
13788
13789         cleanup_130
13790
13791         echo "FIEMAP on 2-stripe file with hole succeeded"
13792 }
13793 run_test 130c "FIEMAP (2-stripe file with hole)"
13794
13795 test_130d() {
13796         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13797
13798         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13799         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13800
13801         trap cleanup_130 EXIT RETURN
13802
13803         local fm_file=$DIR/$tfile
13804         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13805                         error "setstripe on $fm_file"
13806         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13807                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13808
13809         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13810         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13811                 error "dd failed on $fm_file"
13812
13813         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13814         filefrag_op=$(filefrag -ve -k $fm_file |
13815                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13816
13817         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13818                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13819
13820         IFS=$'\n'
13821         tot_len=0
13822         num_luns=1
13823         for line in $filefrag_op
13824         do
13825                 frag_lun=$(echo $line | cut -d: -f5 |
13826                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13827                 ext_len=$(echo $line | cut -d: -f4)
13828                 if (( $frag_lun != $last_lun )); then
13829                         if (( tot_len != 1024 )); then
13830                                 cleanup_130
13831                                 error "FIEMAP on $fm_file failed; returned " \
13832                                 "len $tot_len for OST $last_lun instead of 1024"
13833                                 return
13834                         else
13835                                 (( num_luns += 1 ))
13836                                 tot_len=0
13837                         fi
13838                 fi
13839                 (( tot_len += ext_len ))
13840                 last_lun=$frag_lun
13841         done
13842         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13843                 cleanup_130
13844                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13845                         "luns or wrong len for OST $last_lun"
13846                 return
13847         fi
13848
13849         cleanup_130
13850
13851         echo "FIEMAP on N-stripe file succeeded"
13852 }
13853 run_test 130d "FIEMAP (N-stripe file)"
13854
13855 test_130e() {
13856         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13857
13858         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13859         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13860
13861         trap cleanup_130 EXIT RETURN
13862
13863         local fm_file=$DIR/$tfile
13864         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13865
13866         NUM_BLKS=512
13867         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13868         for ((i = 0; i < $NUM_BLKS; i++)); do
13869                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13870                         conv=notrunc > /dev/null 2>&1
13871         done
13872
13873         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13874         filefrag_op=$(filefrag -ve -k $fm_file |
13875                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13876
13877         last_lun=$(echo $filefrag_op | cut -d: -f5)
13878
13879         IFS=$'\n'
13880         tot_len=0
13881         num_luns=1
13882         for line in $filefrag_op; do
13883                 frag_lun=$(echo $line | cut -d: -f5)
13884                 ext_len=$(echo $line | cut -d: -f4)
13885                 if [[ "$frag_lun" != "$last_lun" ]]; then
13886                         if (( tot_len != $EXPECTED_LEN )); then
13887                                 cleanup_130
13888                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13889                         else
13890                                 (( num_luns += 1 ))
13891                                 tot_len=0
13892                         fi
13893                 fi
13894                 (( tot_len += ext_len ))
13895                 last_lun=$frag_lun
13896         done
13897         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13898                 cleanup_130
13899                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13900         fi
13901
13902         echo "FIEMAP with continuation calls succeeded"
13903 }
13904 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13905
13906 test_130f() {
13907         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13908         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13909
13910         local fm_file=$DIR/$tfile
13911         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13912                 error "multiop create with lov_delay_create on $fm_file"
13913
13914         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13915         filefrag_extents=$(filefrag -vek $fm_file |
13916                            awk '/extents? found/ { print $2 }')
13917         if [[ "$filefrag_extents" != "0" ]]; then
13918                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13919         fi
13920
13921         rm -f $fm_file
13922 }
13923 run_test 130f "FIEMAP (unstriped file)"
13924
13925 test_130g() {
13926         local file=$DIR/$tfile
13927         local nr=$((OSTCOUNT * 100))
13928
13929         $LFS setstripe -C $nr $file ||
13930                 error "failed to setstripe -C $nr $file"
13931
13932         dd if=/dev/zero of=$file count=$nr bs=1M
13933         sync
13934         nr=$($LFS getstripe -c $file)
13935
13936         local extents=$(filefrag -v $file |
13937                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13938
13939         echo "filefrag list $extents extents in file with stripecount $nr"
13940         if (( extents < nr )); then
13941                 $LFS getstripe $file
13942                 filefrag -v $file
13943                 error "filefrag printed $extents < $nr extents"
13944         fi
13945
13946         rm -f $file
13947 }
13948 run_test 130g "FIEMAP (overstripe file)"
13949
13950 # Test for writev/readv
13951 test_131a() {
13952         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13953                 error "writev test failed"
13954         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13955                 error "readv failed"
13956         rm -f $DIR/$tfile
13957 }
13958 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13959
13960 test_131b() {
13961         local fsize=$((524288 + 1048576 + 1572864))
13962         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13963                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13964                         error "append writev test failed"
13965
13966         ((fsize += 1572864 + 1048576))
13967         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13968                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13969                         error "append writev test failed"
13970         rm -f $DIR/$tfile
13971 }
13972 run_test 131b "test append writev"
13973
13974 test_131c() {
13975         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13976         error "NOT PASS"
13977 }
13978 run_test 131c "test read/write on file w/o objects"
13979
13980 test_131d() {
13981         rwv -f $DIR/$tfile -w -n 1 1572864
13982         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13983         if [ "$NOB" != 1572864 ]; then
13984                 error "Short read filed: read $NOB bytes instead of 1572864"
13985         fi
13986         rm -f $DIR/$tfile
13987 }
13988 run_test 131d "test short read"
13989
13990 test_131e() {
13991         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13992         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13993         error "read hitting hole failed"
13994         rm -f $DIR/$tfile
13995 }
13996 run_test 131e "test read hitting hole"
13997
13998 check_stats() {
13999         local facet=$1
14000         local op=$2
14001         local want=${3:-0}
14002         local res
14003
14004         case $facet in
14005         mds*) res=$(do_facet $facet \
14006                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
14007                  ;;
14008         ost*) res=$(do_facet $facet \
14009                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
14010                  ;;
14011         *) error "Wrong facet '$facet'" ;;
14012         esac
14013         [ "$res" ] || error "The counter for $op on $facet was not incremented"
14014         # if the argument $3 is zero, it means any stat increment is ok.
14015         if [[ $want -gt 0 ]]; then
14016                 local count=$(echo $res | awk '{ print $2 }')
14017                 [[ $count -ne $want ]] &&
14018                         error "The $op counter on $facet is $count, not $want"
14019         fi
14020 }
14021
14022 test_133a() {
14023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14024         remote_ost_nodsh && skip "remote OST with nodsh"
14025         remote_mds_nodsh && skip "remote MDS with nodsh"
14026         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14027                 skip_env "MDS doesn't support rename stats"
14028
14029         local testdir=$DIR/${tdir}/stats_testdir
14030
14031         mkdir -p $DIR/${tdir}
14032
14033         # clear stats.
14034         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14035         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14036
14037         # verify mdt stats first.
14038         mkdir ${testdir} || error "mkdir failed"
14039         check_stats $SINGLEMDS "mkdir" 1
14040         touch ${testdir}/${tfile} || error "touch failed"
14041         check_stats $SINGLEMDS "open" 1
14042         check_stats $SINGLEMDS "close" 1
14043         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14044                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14045                 check_stats $SINGLEMDS "mknod" 2
14046         }
14047         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14048         check_stats $SINGLEMDS "unlink" 1
14049         rm -f ${testdir}/${tfile} || error "file remove failed"
14050         check_stats $SINGLEMDS "unlink" 2
14051
14052         # remove working dir and check mdt stats again.
14053         rmdir ${testdir} || error "rmdir failed"
14054         check_stats $SINGLEMDS "rmdir" 1
14055
14056         local testdir1=$DIR/${tdir}/stats_testdir1
14057         mkdir -p ${testdir}
14058         mkdir -p ${testdir1}
14059         touch ${testdir1}/test1
14060         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14061         check_stats $SINGLEMDS "crossdir_rename" 1
14062
14063         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14064         check_stats $SINGLEMDS "samedir_rename" 1
14065
14066         rm -rf $DIR/${tdir}
14067 }
14068 run_test 133a "Verifying MDT stats ========================================"
14069
14070 test_133b() {
14071         local res
14072
14073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14074         remote_ost_nodsh && skip "remote OST with nodsh"
14075         remote_mds_nodsh && skip "remote MDS with nodsh"
14076
14077         local testdir=$DIR/${tdir}/stats_testdir
14078
14079         mkdir -p ${testdir} || error "mkdir failed"
14080         touch ${testdir}/${tfile} || error "touch failed"
14081         cancel_lru_locks mdc
14082
14083         # clear stats.
14084         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14085         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14086
14087         # extra mdt stats verification.
14088         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14089         check_stats $SINGLEMDS "setattr" 1
14090         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14091         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14092         then            # LU-1740
14093                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14094                 check_stats $SINGLEMDS "getattr" 1
14095         fi
14096         rm -rf $DIR/${tdir}
14097
14098         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14099         # so the check below is not reliable
14100         [ $MDSCOUNT -eq 1 ] || return 0
14101
14102         # Sleep to avoid a cached response.
14103         #define OBD_STATFS_CACHE_SECONDS 1
14104         sleep 2
14105         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14106         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14107         $LFS df || error "lfs failed"
14108         check_stats $SINGLEMDS "statfs" 1
14109
14110         # check aggregated statfs (LU-10018)
14111         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14112                 return 0
14113         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14114                 return 0
14115         sleep 2
14116         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14117         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14118         df $DIR
14119         check_stats $SINGLEMDS "statfs" 1
14120
14121         # We want to check that the client didn't send OST_STATFS to
14122         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14123         # extra care is needed here.
14124         if remote_mds; then
14125                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14126                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14127
14128                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14129                 [ "$res" ] && error "OST got STATFS"
14130         fi
14131
14132         return 0
14133 }
14134 run_test 133b "Verifying extra MDT stats =================================="
14135
14136 test_133c() {
14137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14138         remote_ost_nodsh && skip "remote OST with nodsh"
14139         remote_mds_nodsh && skip "remote MDS with nodsh"
14140
14141         local testdir=$DIR/$tdir/stats_testdir
14142
14143         test_mkdir -p $testdir
14144
14145         # verify obdfilter stats.
14146         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14147         sync
14148         cancel_lru_locks osc
14149         wait_delete_completed
14150
14151         # clear stats.
14152         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14153         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14154
14155         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14156                 error "dd failed"
14157         sync
14158         cancel_lru_locks osc
14159         check_stats ost1 "write" 1
14160
14161         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14162         check_stats ost1 "read" 1
14163
14164         > $testdir/$tfile || error "truncate failed"
14165         check_stats ost1 "punch" 1
14166
14167         rm -f $testdir/$tfile || error "file remove failed"
14168         wait_delete_completed
14169         check_stats ost1 "destroy" 1
14170
14171         rm -rf $DIR/$tdir
14172 }
14173 run_test 133c "Verifying OST stats ========================================"
14174
14175 order_2() {
14176         local value=$1
14177         local orig=$value
14178         local order=1
14179
14180         while [ $value -ge 2 ]; do
14181                 order=$((order*2))
14182                 value=$((value/2))
14183         done
14184
14185         if [ $orig -gt $order ]; then
14186                 order=$((order*2))
14187         fi
14188         echo $order
14189 }
14190
14191 size_in_KMGT() {
14192     local value=$1
14193     local size=('K' 'M' 'G' 'T');
14194     local i=0
14195     local size_string=$value
14196
14197     while [ $value -ge 1024 ]; do
14198         if [ $i -gt 3 ]; then
14199             #T is the biggest unit we get here, if that is bigger,
14200             #just return XXXT
14201             size_string=${value}T
14202             break
14203         fi
14204         value=$((value >> 10))
14205         if [ $value -lt 1024 ]; then
14206             size_string=${value}${size[$i]}
14207             break
14208         fi
14209         i=$((i + 1))
14210     done
14211
14212     echo $size_string
14213 }
14214
14215 get_rename_size() {
14216         local size=$1
14217         local context=${2:-.}
14218         local sample=$(do_facet $SINGLEMDS $LCTL \
14219                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14220                 grep -A1 $context |
14221                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14222         echo $sample
14223 }
14224
14225 test_133d() {
14226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14227         remote_ost_nodsh && skip "remote OST with nodsh"
14228         remote_mds_nodsh && skip "remote MDS with nodsh"
14229         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14230                 skip_env "MDS doesn't support rename stats"
14231
14232         local testdir1=$DIR/${tdir}/stats_testdir1
14233         local testdir2=$DIR/${tdir}/stats_testdir2
14234         mkdir -p $DIR/${tdir}
14235
14236         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14237
14238         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14239         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14240
14241         createmany -o $testdir1/test 512 || error "createmany failed"
14242
14243         # check samedir rename size
14244         mv ${testdir1}/test0 ${testdir1}/test_0
14245
14246         local testdir1_size=$(ls -l $DIR/${tdir} |
14247                 awk '/stats_testdir1/ {print $5}')
14248         local testdir2_size=$(ls -l $DIR/${tdir} |
14249                 awk '/stats_testdir2/ {print $5}')
14250
14251         testdir1_size=$(order_2 $testdir1_size)
14252         testdir2_size=$(order_2 $testdir2_size)
14253
14254         testdir1_size=$(size_in_KMGT $testdir1_size)
14255         testdir2_size=$(size_in_KMGT $testdir2_size)
14256
14257         echo "source rename dir size: ${testdir1_size}"
14258         echo "target rename dir size: ${testdir2_size}"
14259
14260         local cmd="do_facet $SINGLEMDS $LCTL "
14261         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14262
14263         eval $cmd || error "$cmd failed"
14264         local samedir=$($cmd | grep 'same_dir')
14265         local same_sample=$(get_rename_size $testdir1_size)
14266         [ -z "$samedir" ] && error "samedir_rename_size count error"
14267         [[ $same_sample -eq 1 ]] ||
14268                 error "samedir_rename_size error $same_sample"
14269         echo "Check same dir rename stats success"
14270
14271         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14272
14273         # check crossdir rename size
14274         mv ${testdir1}/test_0 ${testdir2}/test_0
14275
14276         testdir1_size=$(ls -l $DIR/${tdir} |
14277                 awk '/stats_testdir1/ {print $5}')
14278         testdir2_size=$(ls -l $DIR/${tdir} |
14279                 awk '/stats_testdir2/ {print $5}')
14280
14281         testdir1_size=$(order_2 $testdir1_size)
14282         testdir2_size=$(order_2 $testdir2_size)
14283
14284         testdir1_size=$(size_in_KMGT $testdir1_size)
14285         testdir2_size=$(size_in_KMGT $testdir2_size)
14286
14287         echo "source rename dir size: ${testdir1_size}"
14288         echo "target rename dir size: ${testdir2_size}"
14289
14290         eval $cmd || error "$cmd failed"
14291         local crossdir=$($cmd | grep 'crossdir')
14292         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14293         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14294         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14295         [[ $src_sample -eq 1 ]] ||
14296                 error "crossdir_rename_size error $src_sample"
14297         [[ $tgt_sample -eq 1 ]] ||
14298                 error "crossdir_rename_size error $tgt_sample"
14299         echo "Check cross dir rename stats success"
14300         rm -rf $DIR/${tdir}
14301 }
14302 run_test 133d "Verifying rename_stats ========================================"
14303
14304 test_133e() {
14305         remote_mds_nodsh && skip "remote MDS with nodsh"
14306         remote_ost_nodsh && skip "remote OST with nodsh"
14307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14308
14309         local testdir=$DIR/${tdir}/stats_testdir
14310         local ctr f0 f1 bs=32768 count=42 sum
14311
14312         mkdir -p ${testdir} || error "mkdir failed"
14313
14314         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14315
14316         for ctr in {write,read}_bytes; do
14317                 sync
14318                 cancel_lru_locks osc
14319
14320                 do_facet ost1 $LCTL set_param -n \
14321                         "obdfilter.*.exports.clear=clear"
14322
14323                 if [ $ctr = write_bytes ]; then
14324                         f0=/dev/zero
14325                         f1=${testdir}/${tfile}
14326                 else
14327                         f0=${testdir}/${tfile}
14328                         f1=/dev/null
14329                 fi
14330
14331                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14332                         error "dd failed"
14333                 sync
14334                 cancel_lru_locks osc
14335
14336                 sum=$(do_facet ost1 $LCTL get_param \
14337                         "obdfilter.*.exports.*.stats" |
14338                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14339                                 $1 == ctr { sum += $7 }
14340                                 END { printf("%0.0f", sum) }')
14341
14342                 if ((sum != bs * count)); then
14343                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14344                 fi
14345         done
14346
14347         rm -rf $DIR/${tdir}
14348 }
14349 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14350
14351 test_133f() {
14352         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14353                 skip "too old lustre for get_param -R ($facet_ver)"
14354
14355         # verifying readability.
14356         $LCTL get_param -R '*' &> /dev/null
14357
14358         # Verifing writability with badarea_io.
14359         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14360         local skipped_params='force_lbug|changelog_mask|daemon_file'
14361         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14362                 egrep -v "$skipped_params" |
14363                 xargs -n 1 find $proc_dirs -name |
14364                 xargs -n 1 badarea_io ||
14365                 error "client badarea_io failed"
14366
14367         # remount the FS in case writes/reads /proc break the FS
14368         cleanup || error "failed to unmount"
14369         setup || error "failed to setup"
14370 }
14371 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14372
14373 test_133g() {
14374         remote_mds_nodsh && skip "remote MDS with nodsh"
14375         remote_ost_nodsh && skip "remote OST with nodsh"
14376
14377         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14378         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14379         local facet
14380         for facet in mds1 ost1; do
14381                 local facet_ver=$(lustre_version_code $facet)
14382                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14383                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14384                 else
14385                         log "$facet: too old lustre for get_param -R"
14386                 fi
14387                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14388                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14389                                 tr -d = | egrep -v $skipped_params |
14390                                 xargs -n 1 find $proc_dirs -name |
14391                                 xargs -n 1 badarea_io" ||
14392                                         error "$facet badarea_io failed"
14393                 else
14394                         skip_noexit "$facet: too old lustre for get_param -R"
14395                 fi
14396         done
14397
14398         # remount the FS in case writes/reads /proc break the FS
14399         cleanup || error "failed to unmount"
14400         setup || error "failed to setup"
14401 }
14402 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14403
14404 test_133h() {
14405         remote_mds_nodsh && skip "remote MDS with nodsh"
14406         remote_ost_nodsh && skip "remote OST with nodsh"
14407         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14408                 skip "Need MDS version at least 2.9.54"
14409
14410         local facet
14411         for facet in client mds1 ost1; do
14412                 # Get the list of files that are missing the terminating newline
14413                 local plist=$(do_facet $facet
14414                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14415                 local ent
14416                 for ent in $plist; do
14417                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14418                                 awk -v FS='\v' -v RS='\v\v' \
14419                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14420                                         print FILENAME}'" 2>/dev/null)
14421                         [ -z $missing ] || {
14422                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14423                                 error "file does not end with newline: $facet-$ent"
14424                         }
14425                 done
14426         done
14427 }
14428 run_test 133h "Proc files should end with newlines"
14429
14430 test_134a() {
14431         remote_mds_nodsh && skip "remote MDS with nodsh"
14432         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14433                 skip "Need MDS version at least 2.7.54"
14434
14435         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14436         cancel_lru_locks mdc
14437
14438         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14439         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14440         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14441
14442         local nr=1000
14443         createmany -o $DIR/$tdir/f $nr ||
14444                 error "failed to create $nr files in $DIR/$tdir"
14445         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14446
14447         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14448         do_facet mds1 $LCTL set_param fail_loc=0x327
14449         do_facet mds1 $LCTL set_param fail_val=500
14450         touch $DIR/$tdir/m
14451
14452         echo "sleep 10 seconds ..."
14453         sleep 10
14454         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14455
14456         do_facet mds1 $LCTL set_param fail_loc=0
14457         do_facet mds1 $LCTL set_param fail_val=0
14458         [ $lck_cnt -lt $unused ] ||
14459                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14460
14461         rm $DIR/$tdir/m
14462         unlinkmany $DIR/$tdir/f $nr
14463 }
14464 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14465
14466 test_134b() {
14467         remote_mds_nodsh && skip "remote MDS with nodsh"
14468         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14469                 skip "Need MDS version at least 2.7.54"
14470
14471         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14472         cancel_lru_locks mdc
14473
14474         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14475                         ldlm.lock_reclaim_threshold_mb)
14476         # disable reclaim temporarily
14477         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14478
14479         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14480         do_facet mds1 $LCTL set_param fail_loc=0x328
14481         do_facet mds1 $LCTL set_param fail_val=500
14482
14483         $LCTL set_param debug=+trace
14484
14485         local nr=600
14486         createmany -o $DIR/$tdir/f $nr &
14487         local create_pid=$!
14488
14489         echo "Sleep $TIMEOUT seconds ..."
14490         sleep $TIMEOUT
14491         if ! ps -p $create_pid  > /dev/null 2>&1; then
14492                 do_facet mds1 $LCTL set_param fail_loc=0
14493                 do_facet mds1 $LCTL set_param fail_val=0
14494                 do_facet mds1 $LCTL set_param \
14495                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14496                 error "createmany finished incorrectly!"
14497         fi
14498         do_facet mds1 $LCTL set_param fail_loc=0
14499         do_facet mds1 $LCTL set_param fail_val=0
14500         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14501         wait $create_pid || return 1
14502
14503         unlinkmany $DIR/$tdir/f $nr
14504 }
14505 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14506
14507 test_135() {
14508         remote_mds_nodsh && skip "remote MDS with nodsh"
14509         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14510                 skip "Need MDS version at least 2.13.50"
14511         local fname
14512
14513         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14514
14515 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14516         #set only one record at plain llog
14517         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14518
14519         #fill already existed plain llog each 64767
14520         #wrapping whole catalog
14521         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14522
14523         createmany -o $DIR/$tdir/$tfile_ 64700
14524         for (( i = 0; i < 64700; i = i + 2 ))
14525         do
14526                 rm $DIR/$tdir/$tfile_$i &
14527                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14528                 local pid=$!
14529                 wait $pid
14530         done
14531
14532         #waiting osp synchronization
14533         wait_delete_completed
14534 }
14535 run_test 135 "Race catalog processing"
14536
14537 test_136() {
14538         remote_mds_nodsh && skip "remote MDS with nodsh"
14539         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14540                 skip "Need MDS version at least 2.13.50"
14541         local fname
14542
14543         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14544         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14545         #set only one record at plain llog
14546 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14547         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14548
14549         #fill already existed 2 plain llogs each 64767
14550         #wrapping whole catalog
14551         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14552         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14553         wait_delete_completed
14554
14555         createmany -o $DIR/$tdir/$tfile_ 10
14556         sleep 25
14557
14558         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14559         for (( i = 0; i < 10; i = i + 3 ))
14560         do
14561                 rm $DIR/$tdir/$tfile_$i &
14562                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14563                 local pid=$!
14564                 wait $pid
14565                 sleep 7
14566                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14567         done
14568
14569         #waiting osp synchronization
14570         wait_delete_completed
14571 }
14572 run_test 136 "Race catalog processing 2"
14573
14574 test_140() { #bug-17379
14575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14576
14577         test_mkdir $DIR/$tdir
14578         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14579         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14580
14581         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14582         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14583         local i=0
14584         while i=$((i + 1)); do
14585                 test_mkdir $i
14586                 cd $i || error "Changing to $i"
14587                 ln -s ../stat stat || error "Creating stat symlink"
14588                 # Read the symlink until ELOOP present,
14589                 # not LBUGing the system is considered success,
14590                 # we didn't overrun the stack.
14591                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14592                 if [ $ret -ne 0 ]; then
14593                         if [ $ret -eq 40 ]; then
14594                                 break  # -ELOOP
14595                         else
14596                                 error "Open stat symlink"
14597                                         return
14598                         fi
14599                 fi
14600         done
14601         i=$((i - 1))
14602         echo "The symlink depth = $i"
14603         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14604                 error "Invalid symlink depth"
14605
14606         # Test recursive symlink
14607         ln -s symlink_self symlink_self
14608         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14609         echo "open symlink_self returns $ret"
14610         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14611 }
14612 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14613
14614 test_150a() {
14615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14616
14617         local TF="$TMP/$tfile"
14618
14619         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14620         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14621         cp $TF $DIR/$tfile
14622         cancel_lru_locks $OSC
14623         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14624         remount_client $MOUNT
14625         df -P $MOUNT
14626         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14627
14628         $TRUNCATE $TF 6000
14629         $TRUNCATE $DIR/$tfile 6000
14630         cancel_lru_locks $OSC
14631         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14632
14633         echo "12345" >>$TF
14634         echo "12345" >>$DIR/$tfile
14635         cancel_lru_locks $OSC
14636         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14637
14638         echo "12345" >>$TF
14639         echo "12345" >>$DIR/$tfile
14640         cancel_lru_locks $OSC
14641         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14642 }
14643 run_test 150a "truncate/append tests"
14644
14645 test_150b() {
14646         check_set_fallocate_or_skip
14647
14648         touch $DIR/$tfile
14649         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14650         check_fallocate $DIR/$tfile || error "fallocate failed"
14651 }
14652 run_test 150b "Verify fallocate (prealloc) functionality"
14653
14654 test_150bb() {
14655         check_set_fallocate_or_skip
14656
14657         touch $DIR/$tfile
14658         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14659         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14660         > $DIR/$tfile
14661         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14662         # precomputed md5sum for 20MB of zeroes
14663         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14664         local sum=($(md5sum $DIR/$tfile))
14665
14666         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14667
14668         check_set_fallocate 1
14669
14670         > $DIR/$tfile
14671         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14672         sum=($(md5sum $DIR/$tfile))
14673
14674         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14675 }
14676 run_test 150bb "Verify fallocate modes both zero space"
14677
14678 test_150c() {
14679         check_set_fallocate_or_skip
14680         local striping="-c2"
14681
14682         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14683         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14684         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14685         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14686         local want=$((OSTCOUNT * 1048576))
14687
14688         # Must allocate all requested space, not more than 5% extra
14689         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14690                 error "bytes $bytes is not $want"
14691
14692         rm -f $DIR/$tfile
14693
14694         echo "verify fallocate on PFL file"
14695
14696         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14697
14698         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14699                 error "Create $DIR/$tfile failed"
14700         fallocate -l $((1048576 * 512)) $DIR/$tfile ||
14701                         error "fallocate failed"
14702         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14703         want=$((512 * 1048576))
14704
14705         # Must allocate all requested space, not more than 5% extra
14706         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14707                 error "bytes $bytes is not $want"
14708 }
14709 run_test 150c "Verify fallocate Size and Blocks"
14710
14711 test_150d() {
14712         check_set_fallocate_or_skip
14713         local striping="-c2"
14714
14715         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14716
14717         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14718         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14719                 error "setstripe failed"
14720         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14721         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14722         local want=$((OSTCOUNT * 1048576))
14723
14724         # Must allocate all requested space, not more than 5% extra
14725         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14726                 error "bytes $bytes is not $want"
14727 }
14728 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14729
14730 test_150e() {
14731         check_set_fallocate_or_skip
14732
14733         echo "df before:"
14734         $LFS df
14735         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14736         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14737                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14738
14739         # Find OST with Minimum Size
14740         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14741                        sort -un | head -1)
14742
14743         # Get 100MB per OST of the available space to reduce run time
14744         # else 60% of the available space if we are running SLOW tests
14745         if [ $SLOW == "no" ]; then
14746                 local space=$((1024 * 100 * OSTCOUNT))
14747         else
14748                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14749         fi
14750
14751         fallocate -l${space}k $DIR/$tfile ||
14752                 error "fallocate ${space}k $DIR/$tfile failed"
14753         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14754
14755         # get size immediately after fallocate. This should be correctly
14756         # updated
14757         local size=$(stat -c '%s' $DIR/$tfile)
14758         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14759
14760         # Sleep for a while for statfs to get updated. And not pull from cache.
14761         sleep 2
14762
14763         echo "df after fallocate:"
14764         $LFS df
14765
14766         (( size / 1024 == space )) || error "size $size != requested $space"
14767         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14768                 error "used $used < space $space"
14769
14770         rm $DIR/$tfile || error "rm failed"
14771         sync
14772         wait_delete_completed
14773
14774         echo "df after unlink:"
14775         $LFS df
14776 }
14777 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14778
14779 test_150f() {
14780         local size
14781         local blocks
14782         local want_size_before=20480 # in bytes
14783         local want_blocks_before=40 # 512 sized blocks
14784         local want_blocks_after=24  # 512 sized blocks
14785         local length=$(((want_blocks_before - want_blocks_after) * 512))
14786
14787         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14788                 skip "need at least 2.14.0 for fallocate punch"
14789
14790         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14791                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14792         fi
14793
14794         check_set_fallocate_or_skip
14795         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14796
14797         [[ "x$DOM" == "xyes" ]] &&
14798                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14799
14800         echo "Verify fallocate punch: Range within the file range"
14801         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14802                 error "dd failed for bs 4096 and count 5"
14803
14804         # Call fallocate with punch range which is within the file range
14805         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
14806                 error "fallocate failed: offset 4096 and length $length"
14807         # client must see changes immediately after fallocate
14808         size=$(stat -c '%s' $DIR/$tfile)
14809         blocks=$(stat -c '%b' $DIR/$tfile)
14810
14811         # Verify punch worked.
14812         (( blocks == want_blocks_after )) ||
14813                 error "punch failed: blocks $blocks != $want_blocks_after"
14814
14815         (( size == want_size_before )) ||
14816                 error "punch failed: size $size != $want_size_before"
14817
14818         # Verify there is hole in file
14819         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14820         # precomputed md5sum
14821         local expect="4a9a834a2db02452929c0a348273b4aa"
14822
14823         cksum=($(md5sum $DIR/$tfile))
14824         [[ "${cksum[0]}" == "$expect" ]] ||
14825                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14826
14827         # Start second sub-case for fallocate punch.
14828         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14829         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14830                 error "dd failed for bs 4096 and count 5"
14831
14832         # Punch range less than block size will have no change in block count
14833         want_blocks_after=40  # 512 sized blocks
14834
14835         # Punch overlaps two blocks and less than blocksize
14836         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
14837                 error "fallocate failed: offset 4000 length 3000"
14838         size=$(stat -c '%s' $DIR/$tfile)
14839         blocks=$(stat -c '%b' $DIR/$tfile)
14840
14841         # Verify punch worked.
14842         (( blocks == want_blocks_after )) ||
14843                 error "punch failed: blocks $blocks != $want_blocks_after"
14844
14845         (( size == want_size_before )) ||
14846                 error "punch failed: size $size != $want_size_before"
14847
14848         # Verify if range is really zero'ed out. We expect Zeros.
14849         # precomputed md5sum
14850         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14851         cksum=($(md5sum $DIR/$tfile))
14852         [[ "${cksum[0]}" == "$expect" ]] ||
14853                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14854 }
14855 run_test 150f "Verify fallocate punch functionality"
14856
14857 test_150g() {
14858         local space
14859         local size
14860         local blocks
14861         local blocks_after
14862         local size_after
14863         local BS=4096 # Block size in bytes
14864
14865         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14866                 skip "need at least 2.14.0 for fallocate punch"
14867
14868         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14869                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14870         fi
14871
14872         check_set_fallocate_or_skip
14873         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14874
14875         if [[ "x$DOM" == "xyes" ]]; then
14876                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
14877                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
14878         else
14879                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14880                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14881         fi
14882
14883         # Get 100MB per OST of the available space to reduce run time
14884         # else 60% of the available space if we are running SLOW tests
14885         if [ $SLOW == "no" ]; then
14886                 space=$((1024 * 100 * OSTCOUNT))
14887         else
14888                 # Find OST with Minimum Size
14889                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14890                         sort -un | head -1)
14891                 echo "min size OST: $space"
14892                 space=$(((space * 60)/100 * OSTCOUNT))
14893         fi
14894         # space in 1k units, round to 4k blocks
14895         local blkcount=$((space * 1024 / $BS))
14896
14897         echo "Verify fallocate punch: Very large Range"
14898         fallocate -l${space}k $DIR/$tfile ||
14899                 error "fallocate ${space}k $DIR/$tfile failed"
14900         # write 1M at the end, start and in the middle
14901         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14902                 error "dd failed: bs $BS count 256"
14903         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14904                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14905         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14906                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14907
14908         # Gather stats.
14909         size=$(stat -c '%s' $DIR/$tfile)
14910
14911         # gather punch length.
14912         local punch_size=$((size - (BS * 2)))
14913
14914         echo "punch_size = $punch_size"
14915         echo "size - punch_size: $((size - punch_size))"
14916         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14917
14918         # Call fallocate to punch all except 2 blocks. We leave the
14919         # first and the last block
14920         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14921         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14922                 error "fallocate failed: offset $BS length $punch_size"
14923
14924         size_after=$(stat -c '%s' $DIR/$tfile)
14925         blocks_after=$(stat -c '%b' $DIR/$tfile)
14926
14927         # Verify punch worked.
14928         # Size should be kept
14929         (( size == size_after )) ||
14930                 error "punch failed: size $size != $size_after"
14931
14932         # two 4k data blocks to remain plus possible 1 extra extent block
14933         (( blocks_after <= ((BS / 512) * 3) )) ||
14934                 error "too many blocks remains: $blocks_after"
14935
14936         # Verify that file has hole between the first and the last blocks
14937         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14938         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14939
14940         echo "Hole at [$hole_start, $hole_end)"
14941         (( hole_start == BS )) ||
14942                 error "no hole at offset $BS after punch"
14943
14944         (( hole_end == BS + punch_size )) ||
14945                 error "data at offset $hole_end < $((BS + punch_size))"
14946 }
14947 run_test 150g "Verify fallocate punch on large range"
14948
14949 #LU-2902 roc_hit was not able to read all values from lproc
14950 function roc_hit_init() {
14951         local list=$(comma_list $(osts_nodes))
14952         local dir=$DIR/$tdir-check
14953         local file=$dir/$tfile
14954         local BEFORE
14955         local AFTER
14956         local idx
14957
14958         test_mkdir $dir
14959         #use setstripe to do a write to every ost
14960         for i in $(seq 0 $((OSTCOUNT-1))); do
14961                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14962                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14963                 idx=$(printf %04x $i)
14964                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14965                         awk '$1 == "cache_access" {sum += $7}
14966                                 END { printf("%0.0f", sum) }')
14967
14968                 cancel_lru_locks osc
14969                 cat $file >/dev/null
14970
14971                 AFTER=$(get_osd_param $list *OST*$idx stats |
14972                         awk '$1 == "cache_access" {sum += $7}
14973                                 END { printf("%0.0f", sum) }')
14974
14975                 echo BEFORE:$BEFORE AFTER:$AFTER
14976                 if ! let "AFTER - BEFORE == 4"; then
14977                         rm -rf $dir
14978                         error "roc_hit is not safe to use"
14979                 fi
14980                 rm $file
14981         done
14982
14983         rm -rf $dir
14984 }
14985
14986 function roc_hit() {
14987         local list=$(comma_list $(osts_nodes))
14988         echo $(get_osd_param $list '' stats |
14989                 awk '$1 == "cache_hit" {sum += $7}
14990                         END { printf("%0.0f", sum) }')
14991 }
14992
14993 function set_cache() {
14994         local on=1
14995
14996         if [ "$2" == "off" ]; then
14997                 on=0;
14998         fi
14999         local list=$(comma_list $(osts_nodes))
15000         set_osd_param $list '' $1_cache_enable $on
15001
15002         cancel_lru_locks osc
15003 }
15004
15005 test_151() {
15006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15007         remote_ost_nodsh && skip "remote OST with nodsh"
15008
15009         local CPAGES=3
15010         local list=$(comma_list $(osts_nodes))
15011
15012         # check whether obdfilter is cache capable at all
15013         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15014                 skip "not cache-capable obdfilter"
15015         fi
15016
15017         # check cache is enabled on all obdfilters
15018         if get_osd_param $list '' read_cache_enable | grep 0; then
15019                 skip "oss cache is disabled"
15020         fi
15021
15022         set_osd_param $list '' writethrough_cache_enable 1
15023
15024         # check write cache is enabled on all obdfilters
15025         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15026                 skip "oss write cache is NOT enabled"
15027         fi
15028
15029         roc_hit_init
15030
15031         #define OBD_FAIL_OBD_NO_LRU  0x609
15032         do_nodes $list $LCTL set_param fail_loc=0x609
15033
15034         # pages should be in the case right after write
15035         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15036                 error "dd failed"
15037
15038         local BEFORE=$(roc_hit)
15039         cancel_lru_locks osc
15040         cat $DIR/$tfile >/dev/null
15041         local AFTER=$(roc_hit)
15042
15043         do_nodes $list $LCTL set_param fail_loc=0
15044
15045         if ! let "AFTER - BEFORE == CPAGES"; then
15046                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15047         fi
15048
15049         cancel_lru_locks osc
15050         # invalidates OST cache
15051         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15052         set_osd_param $list '' read_cache_enable 0
15053         cat $DIR/$tfile >/dev/null
15054
15055         # now data shouldn't be found in the cache
15056         BEFORE=$(roc_hit)
15057         cancel_lru_locks osc
15058         cat $DIR/$tfile >/dev/null
15059         AFTER=$(roc_hit)
15060         if let "AFTER - BEFORE != 0"; then
15061                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15062         fi
15063
15064         set_osd_param $list '' read_cache_enable 1
15065         rm -f $DIR/$tfile
15066 }
15067 run_test 151 "test cache on oss and controls ==============================="
15068
15069 test_152() {
15070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15071
15072         local TF="$TMP/$tfile"
15073
15074         # simulate ENOMEM during write
15075 #define OBD_FAIL_OST_NOMEM      0x226
15076         lctl set_param fail_loc=0x80000226
15077         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15078         cp $TF $DIR/$tfile
15079         sync || error "sync failed"
15080         lctl set_param fail_loc=0
15081
15082         # discard client's cache
15083         cancel_lru_locks osc
15084
15085         # simulate ENOMEM during read
15086         lctl set_param fail_loc=0x80000226
15087         cmp $TF $DIR/$tfile || error "cmp failed"
15088         lctl set_param fail_loc=0
15089
15090         rm -f $TF
15091 }
15092 run_test 152 "test read/write with enomem ============================"
15093
15094 test_153() {
15095         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15096 }
15097 run_test 153 "test if fdatasync does not crash ======================="
15098
15099 dot_lustre_fid_permission_check() {
15100         local fid=$1
15101         local ffid=$MOUNT/.lustre/fid/$fid
15102         local test_dir=$2
15103
15104         echo "stat fid $fid"
15105         stat $ffid > /dev/null || error "stat $ffid failed."
15106         echo "touch fid $fid"
15107         touch $ffid || error "touch $ffid failed."
15108         echo "write to fid $fid"
15109         cat /etc/hosts > $ffid || error "write $ffid failed."
15110         echo "read fid $fid"
15111         diff /etc/hosts $ffid || error "read $ffid failed."
15112         echo "append write to fid $fid"
15113         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15114         echo "rename fid $fid"
15115         mv $ffid $test_dir/$tfile.1 &&
15116                 error "rename $ffid to $tfile.1 should fail."
15117         touch $test_dir/$tfile.1
15118         mv $test_dir/$tfile.1 $ffid &&
15119                 error "rename $tfile.1 to $ffid should fail."
15120         rm -f $test_dir/$tfile.1
15121         echo "truncate fid $fid"
15122         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15123         echo "link fid $fid"
15124         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15125         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15126                 echo "setfacl fid $fid"
15127                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
15128                 echo "getfacl fid $fid"
15129                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
15130         fi
15131         echo "unlink fid $fid"
15132         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15133         echo "mknod fid $fid"
15134         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15135
15136         fid=[0xf00000400:0x1:0x0]
15137         ffid=$MOUNT/.lustre/fid/$fid
15138
15139         echo "stat non-exist fid $fid"
15140         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15141         echo "write to non-exist fid $fid"
15142         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15143         echo "link new fid $fid"
15144         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15145
15146         mkdir -p $test_dir/$tdir
15147         touch $test_dir/$tdir/$tfile
15148         fid=$($LFS path2fid $test_dir/$tdir)
15149         rc=$?
15150         [ $rc -ne 0 ] &&
15151                 error "error: could not get fid for $test_dir/$dir/$tfile."
15152
15153         ffid=$MOUNT/.lustre/fid/$fid
15154
15155         echo "ls $fid"
15156         ls $ffid > /dev/null || error "ls $ffid failed."
15157         echo "touch $fid/$tfile.1"
15158         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15159
15160         echo "touch $MOUNT/.lustre/fid/$tfile"
15161         touch $MOUNT/.lustre/fid/$tfile && \
15162                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15163
15164         echo "setxattr to $MOUNT/.lustre/fid"
15165         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15166
15167         echo "listxattr for $MOUNT/.lustre/fid"
15168         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15169
15170         echo "delxattr from $MOUNT/.lustre/fid"
15171         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15172
15173         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15174         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15175                 error "touch invalid fid should fail."
15176
15177         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15178         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15179                 error "touch non-normal fid should fail."
15180
15181         echo "rename $tdir to $MOUNT/.lustre/fid"
15182         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15183                 error "rename to $MOUNT/.lustre/fid should fail."
15184
15185         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15186         then            # LU-3547
15187                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15188                 local new_obf_mode=777
15189
15190                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15191                 chmod $new_obf_mode $DIR/.lustre/fid ||
15192                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15193
15194                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15195                 [ $obf_mode -eq $new_obf_mode ] ||
15196                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15197
15198                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15199                 chmod $old_obf_mode $DIR/.lustre/fid ||
15200                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15201         fi
15202
15203         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15204         fid=$($LFS path2fid $test_dir/$tfile-2)
15205
15206         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15207         then # LU-5424
15208                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15209                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15210                         error "create lov data thru .lustre failed"
15211         fi
15212         echo "cp /etc/passwd $test_dir/$tfile-2"
15213         cp /etc/passwd $test_dir/$tfile-2 ||
15214                 error "copy to $test_dir/$tfile-2 failed."
15215         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15216         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15217                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15218
15219         rm -rf $test_dir/tfile.lnk
15220         rm -rf $test_dir/$tfile-2
15221 }
15222
15223 test_154A() {
15224         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15225                 skip "Need MDS version at least 2.4.1"
15226
15227         local tf=$DIR/$tfile
15228         touch $tf
15229
15230         local fid=$($LFS path2fid $tf)
15231         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15232
15233         # check that we get the same pathname back
15234         local rootpath
15235         local found
15236         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15237                 echo "$rootpath $fid"
15238                 found=$($LFS fid2path $rootpath "$fid")
15239                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15240                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15241         done
15242
15243         # check wrong root path format
15244         rootpath=$MOUNT"_wrong"
15245         found=$($LFS fid2path $rootpath "$fid")
15246         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15247 }
15248 run_test 154A "lfs path2fid and fid2path basic checks"
15249
15250 test_154B() {
15251         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15252                 skip "Need MDS version at least 2.4.1"
15253
15254         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15255         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15256         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15257         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15258
15259         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15260         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15261
15262         # check that we get the same pathname
15263         echo "PFID: $PFID, name: $name"
15264         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15265         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15266         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15267                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15268
15269         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15270 }
15271 run_test 154B "verify the ll_decode_linkea tool"
15272
15273 test_154a() {
15274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15275         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15276         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15277                 skip "Need MDS version at least 2.2.51"
15278         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15279
15280         cp /etc/hosts $DIR/$tfile
15281
15282         fid=$($LFS path2fid $DIR/$tfile)
15283         rc=$?
15284         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15285
15286         dot_lustre_fid_permission_check "$fid" $DIR ||
15287                 error "dot lustre permission check $fid failed"
15288
15289         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15290
15291         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15292
15293         touch $MOUNT/.lustre/file &&
15294                 error "creation is not allowed under .lustre"
15295
15296         mkdir $MOUNT/.lustre/dir &&
15297                 error "mkdir is not allowed under .lustre"
15298
15299         rm -rf $DIR/$tfile
15300 }
15301 run_test 154a "Open-by-FID"
15302
15303 test_154b() {
15304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15305         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15306         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15307         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15308                 skip "Need MDS version at least 2.2.51"
15309
15310         local remote_dir=$DIR/$tdir/remote_dir
15311         local MDTIDX=1
15312         local rc=0
15313
15314         mkdir -p $DIR/$tdir
15315         $LFS mkdir -i $MDTIDX $remote_dir ||
15316                 error "create remote directory failed"
15317
15318         cp /etc/hosts $remote_dir/$tfile
15319
15320         fid=$($LFS path2fid $remote_dir/$tfile)
15321         rc=$?
15322         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15323
15324         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15325                 error "dot lustre permission check $fid failed"
15326         rm -rf $DIR/$tdir
15327 }
15328 run_test 154b "Open-by-FID for remote directory"
15329
15330 test_154c() {
15331         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15332                 skip "Need MDS version at least 2.4.1"
15333
15334         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15335         local FID1=$($LFS path2fid $DIR/$tfile.1)
15336         local FID2=$($LFS path2fid $DIR/$tfile.2)
15337         local FID3=$($LFS path2fid $DIR/$tfile.3)
15338
15339         local N=1
15340         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15341                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15342                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15343                 local want=FID$N
15344                 [ "$FID" = "${!want}" ] ||
15345                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15346                 N=$((N + 1))
15347         done
15348
15349         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15350         do
15351                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15352                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15353                 N=$((N + 1))
15354         done
15355 }
15356 run_test 154c "lfs path2fid and fid2path multiple arguments"
15357
15358 test_154d() {
15359         remote_mds_nodsh && skip "remote MDS with nodsh"
15360         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15361                 skip "Need MDS version at least 2.5.53"
15362
15363         if remote_mds; then
15364                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15365         else
15366                 nid="0@lo"
15367         fi
15368         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15369         local fd
15370         local cmd
15371
15372         rm -f $DIR/$tfile
15373         touch $DIR/$tfile
15374
15375         local fid=$($LFS path2fid $DIR/$tfile)
15376         # Open the file
15377         fd=$(free_fd)
15378         cmd="exec $fd<$DIR/$tfile"
15379         eval $cmd
15380         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15381         echo "$fid_list" | grep "$fid"
15382         rc=$?
15383
15384         cmd="exec $fd>/dev/null"
15385         eval $cmd
15386         if [ $rc -ne 0 ]; then
15387                 error "FID $fid not found in open files list $fid_list"
15388         fi
15389 }
15390 run_test 154d "Verify open file fid"
15391
15392 test_154e()
15393 {
15394         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15395                 skip "Need MDS version at least 2.6.50"
15396
15397         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15398                 error ".lustre returned by readdir"
15399         fi
15400 }
15401 run_test 154e ".lustre is not returned by readdir"
15402
15403 test_154f() {
15404         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15405
15406         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15407         mkdir_on_mdt0 $DIR/$tdir
15408         # test dirs inherit from its stripe
15409         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15410         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15411         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15412         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15413         touch $DIR/f
15414
15415         # get fid of parents
15416         local FID0=$($LFS path2fid $DIR/$tdir)
15417         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15418         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15419         local FID3=$($LFS path2fid $DIR)
15420
15421         # check that path2fid --parents returns expected <parent_fid>/name
15422         # 1) test for a directory (single parent)
15423         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15424         [ "$parent" == "$FID0/foo1" ] ||
15425                 error "expected parent: $FID0/foo1, got: $parent"
15426
15427         # 2) test for a file with nlink > 1 (multiple parents)
15428         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15429         echo "$parent" | grep -F "$FID1/$tfile" ||
15430                 error "$FID1/$tfile not returned in parent list"
15431         echo "$parent" | grep -F "$FID2/link" ||
15432                 error "$FID2/link not returned in parent list"
15433
15434         # 3) get parent by fid
15435         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15436         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15437         echo "$parent" | grep -F "$FID1/$tfile" ||
15438                 error "$FID1/$tfile not returned in parent list (by fid)"
15439         echo "$parent" | grep -F "$FID2/link" ||
15440                 error "$FID2/link not returned in parent list (by fid)"
15441
15442         # 4) test for entry in root directory
15443         parent=$($LFS path2fid --parents $DIR/f)
15444         echo "$parent" | grep -F "$FID3/f" ||
15445                 error "$FID3/f not returned in parent list"
15446
15447         # 5) test it on root directory
15448         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15449                 error "$MOUNT should not have parents"
15450
15451         # enable xattr caching and check that linkea is correctly updated
15452         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15453         save_lustre_params client "llite.*.xattr_cache" > $save
15454         lctl set_param llite.*.xattr_cache 1
15455
15456         # 6.1) linkea update on rename
15457         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15458
15459         # get parents by fid
15460         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15461         # foo1 should no longer be returned in parent list
15462         echo "$parent" | grep -F "$FID1" &&
15463                 error "$FID1 should no longer be in parent list"
15464         # the new path should appear
15465         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15466                 error "$FID2/$tfile.moved is not in parent list"
15467
15468         # 6.2) linkea update on unlink
15469         rm -f $DIR/$tdir/foo2/link
15470         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15471         # foo2/link should no longer be returned in parent list
15472         echo "$parent" | grep -F "$FID2/link" &&
15473                 error "$FID2/link should no longer be in parent list"
15474         true
15475
15476         rm -f $DIR/f
15477         restore_lustre_params < $save
15478         rm -f $save
15479 }
15480 run_test 154f "get parent fids by reading link ea"
15481
15482 test_154g()
15483 {
15484         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15485         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15486            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15487                 skip "Need MDS version at least 2.6.92"
15488
15489         mkdir_on_mdt0 $DIR/$tdir
15490         llapi_fid_test -d $DIR/$tdir
15491 }
15492 run_test 154g "various llapi FID tests"
15493
15494 test_155_small_load() {
15495     local temp=$TMP/$tfile
15496     local file=$DIR/$tfile
15497
15498     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15499         error "dd of=$temp bs=6096 count=1 failed"
15500     cp $temp $file
15501     cancel_lru_locks $OSC
15502     cmp $temp $file || error "$temp $file differ"
15503
15504     $TRUNCATE $temp 6000
15505     $TRUNCATE $file 6000
15506     cmp $temp $file || error "$temp $file differ (truncate1)"
15507
15508     echo "12345" >>$temp
15509     echo "12345" >>$file
15510     cmp $temp $file || error "$temp $file differ (append1)"
15511
15512     echo "12345" >>$temp
15513     echo "12345" >>$file
15514     cmp $temp $file || error "$temp $file differ (append2)"
15515
15516     rm -f $temp $file
15517     true
15518 }
15519
15520 test_155_big_load() {
15521         remote_ost_nodsh && skip "remote OST with nodsh"
15522
15523         local temp=$TMP/$tfile
15524         local file=$DIR/$tfile
15525
15526         free_min_max
15527         local cache_size=$(do_facet ost$((MAXI+1)) \
15528                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15529         local large_file_size=$((cache_size * 2))
15530
15531         echo "OSS cache size: $cache_size KB"
15532         echo "Large file size: $large_file_size KB"
15533
15534         [ $MAXV -le $large_file_size ] &&
15535                 skip_env "max available OST size needs > $large_file_size KB"
15536
15537         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15538
15539         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15540                 error "dd of=$temp bs=$large_file_size count=1k failed"
15541         cp $temp $file
15542         ls -lh $temp $file
15543         cancel_lru_locks osc
15544         cmp $temp $file || error "$temp $file differ"
15545
15546         rm -f $temp $file
15547         true
15548 }
15549
15550 save_writethrough() {
15551         local facets=$(get_facets OST)
15552
15553         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15554 }
15555
15556 test_155a() {
15557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15558
15559         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15560
15561         save_writethrough $p
15562
15563         set_cache read on
15564         set_cache writethrough on
15565         test_155_small_load
15566         restore_lustre_params < $p
15567         rm -f $p
15568 }
15569 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15570
15571 test_155b() {
15572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15573
15574         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15575
15576         save_writethrough $p
15577
15578         set_cache read on
15579         set_cache writethrough off
15580         test_155_small_load
15581         restore_lustre_params < $p
15582         rm -f $p
15583 }
15584 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15585
15586 test_155c() {
15587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15588
15589         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15590
15591         save_writethrough $p
15592
15593         set_cache read off
15594         set_cache writethrough on
15595         test_155_small_load
15596         restore_lustre_params < $p
15597         rm -f $p
15598 }
15599 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15600
15601 test_155d() {
15602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15603
15604         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15605
15606         save_writethrough $p
15607
15608         set_cache read off
15609         set_cache writethrough off
15610         test_155_small_load
15611         restore_lustre_params < $p
15612         rm -f $p
15613 }
15614 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15615
15616 test_155e() {
15617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15618
15619         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15620
15621         save_writethrough $p
15622
15623         set_cache read on
15624         set_cache writethrough on
15625         test_155_big_load
15626         restore_lustre_params < $p
15627         rm -f $p
15628 }
15629 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15630
15631 test_155f() {
15632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15633
15634         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15635
15636         save_writethrough $p
15637
15638         set_cache read on
15639         set_cache writethrough off
15640         test_155_big_load
15641         restore_lustre_params < $p
15642         rm -f $p
15643 }
15644 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15645
15646 test_155g() {
15647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15648
15649         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15650
15651         save_writethrough $p
15652
15653         set_cache read off
15654         set_cache writethrough on
15655         test_155_big_load
15656         restore_lustre_params < $p
15657         rm -f $p
15658 }
15659 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15660
15661 test_155h() {
15662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15663
15664         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15665
15666         save_writethrough $p
15667
15668         set_cache read off
15669         set_cache writethrough off
15670         test_155_big_load
15671         restore_lustre_params < $p
15672         rm -f $p
15673 }
15674 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15675
15676 test_156() {
15677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15678         remote_ost_nodsh && skip "remote OST with nodsh"
15679         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15680                 skip "stats not implemented on old servers"
15681         [ "$ost1_FSTYPE" = "zfs" ] &&
15682                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15683
15684         local CPAGES=3
15685         local BEFORE
15686         local AFTER
15687         local file="$DIR/$tfile"
15688         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15689
15690         save_writethrough $p
15691         roc_hit_init
15692
15693         log "Turn on read and write cache"
15694         set_cache read on
15695         set_cache writethrough on
15696
15697         log "Write data and read it back."
15698         log "Read should be satisfied from the cache."
15699         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15700         BEFORE=$(roc_hit)
15701         cancel_lru_locks osc
15702         cat $file >/dev/null
15703         AFTER=$(roc_hit)
15704         if ! let "AFTER - BEFORE == CPAGES"; then
15705                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15706         else
15707                 log "cache hits: before: $BEFORE, after: $AFTER"
15708         fi
15709
15710         log "Read again; it should be satisfied from the cache."
15711         BEFORE=$AFTER
15712         cancel_lru_locks osc
15713         cat $file >/dev/null
15714         AFTER=$(roc_hit)
15715         if ! let "AFTER - BEFORE == CPAGES"; then
15716                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15717         else
15718                 log "cache hits:: before: $BEFORE, after: $AFTER"
15719         fi
15720
15721         log "Turn off the read cache and turn on the write cache"
15722         set_cache read off
15723         set_cache writethrough on
15724
15725         log "Read again; it should be satisfied from the cache."
15726         BEFORE=$(roc_hit)
15727         cancel_lru_locks osc
15728         cat $file >/dev/null
15729         AFTER=$(roc_hit)
15730         if ! let "AFTER - BEFORE == CPAGES"; then
15731                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15732         else
15733                 log "cache hits:: before: $BEFORE, after: $AFTER"
15734         fi
15735
15736         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15737                 # > 2.12.56 uses pagecache if cached
15738                 log "Read again; it should not be satisfied from the cache."
15739                 BEFORE=$AFTER
15740                 cancel_lru_locks osc
15741                 cat $file >/dev/null
15742                 AFTER=$(roc_hit)
15743                 if ! let "AFTER - BEFORE == 0"; then
15744                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15745                 else
15746                         log "cache hits:: before: $BEFORE, after: $AFTER"
15747                 fi
15748         fi
15749
15750         log "Write data and read it back."
15751         log "Read should be satisfied from the cache."
15752         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15753         BEFORE=$(roc_hit)
15754         cancel_lru_locks osc
15755         cat $file >/dev/null
15756         AFTER=$(roc_hit)
15757         if ! let "AFTER - BEFORE == CPAGES"; then
15758                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15759         else
15760                 log "cache hits:: before: $BEFORE, after: $AFTER"
15761         fi
15762
15763         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15764                 # > 2.12.56 uses pagecache if cached
15765                 log "Read again; it should not be satisfied from the cache."
15766                 BEFORE=$AFTER
15767                 cancel_lru_locks osc
15768                 cat $file >/dev/null
15769                 AFTER=$(roc_hit)
15770                 if ! let "AFTER - BEFORE == 0"; then
15771                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15772                 else
15773                         log "cache hits:: before: $BEFORE, after: $AFTER"
15774                 fi
15775         fi
15776
15777         log "Turn off read and write cache"
15778         set_cache read off
15779         set_cache writethrough off
15780
15781         log "Write data and read it back"
15782         log "It should not be satisfied from the cache."
15783         rm -f $file
15784         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15785         cancel_lru_locks osc
15786         BEFORE=$(roc_hit)
15787         cat $file >/dev/null
15788         AFTER=$(roc_hit)
15789         if ! let "AFTER - BEFORE == 0"; then
15790                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15791         else
15792                 log "cache hits:: before: $BEFORE, after: $AFTER"
15793         fi
15794
15795         log "Turn on the read cache and turn off the write cache"
15796         set_cache read on
15797         set_cache writethrough off
15798
15799         log "Write data and read it back"
15800         log "It should not be satisfied from the cache."
15801         rm -f $file
15802         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15803         BEFORE=$(roc_hit)
15804         cancel_lru_locks osc
15805         cat $file >/dev/null
15806         AFTER=$(roc_hit)
15807         if ! let "AFTER - BEFORE == 0"; then
15808                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15809         else
15810                 log "cache hits:: before: $BEFORE, after: $AFTER"
15811         fi
15812
15813         log "Read again; it should be satisfied from the cache."
15814         BEFORE=$(roc_hit)
15815         cancel_lru_locks osc
15816         cat $file >/dev/null
15817         AFTER=$(roc_hit)
15818         if ! let "AFTER - BEFORE == CPAGES"; then
15819                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15820         else
15821                 log "cache hits:: before: $BEFORE, after: $AFTER"
15822         fi
15823
15824         restore_lustre_params < $p
15825         rm -f $p $file
15826 }
15827 run_test 156 "Verification of tunables"
15828
15829 test_160a() {
15830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15831         remote_mds_nodsh && skip "remote MDS with nodsh"
15832         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15833                 skip "Need MDS version at least 2.2.0"
15834
15835         changelog_register || error "changelog_register failed"
15836         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15837         changelog_users $SINGLEMDS | grep -q $cl_user ||
15838                 error "User $cl_user not found in changelog_users"
15839
15840         mkdir_on_mdt0 $DIR/$tdir
15841
15842         # change something
15843         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15844         changelog_clear 0 || error "changelog_clear failed"
15845         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15846         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15847         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15848         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15849         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15850         rm $DIR/$tdir/pics/desktop.jpg
15851
15852         echo "verifying changelog mask"
15853         changelog_chmask "-MKDIR"
15854         changelog_chmask "-CLOSE"
15855
15856         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15857         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15858
15859         changelog_chmask "+MKDIR"
15860         changelog_chmask "+CLOSE"
15861
15862         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15863         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15864
15865         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15866         CLOSES=$(changelog_dump | grep -c "CLOSE")
15867         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15868         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15869
15870         # verify contents
15871         echo "verifying target fid"
15872         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15873         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15874         [ "$fidc" == "$fidf" ] ||
15875                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15876         echo "verifying parent fid"
15877         # The FID returned from the Changelog may be the directory shard on
15878         # a different MDT, and not the FID returned by path2fid on the parent.
15879         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15880         # since this is what will matter when recreating this file in the tree.
15881         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15882         local pathp=$($LFS fid2path $MOUNT "$fidp")
15883         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15884                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15885
15886         echo "getting records for $cl_user"
15887         changelog_users $SINGLEMDS
15888         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15889         local nclr=3
15890         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15891                 error "changelog_clear failed"
15892         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15893         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15894         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15895                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15896
15897         local min0_rec=$(changelog_users $SINGLEMDS |
15898                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15899         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15900                           awk '{ print $1; exit; }')
15901
15902         changelog_dump | tail -n 5
15903         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15904         [ $first_rec == $((min0_rec + 1)) ] ||
15905                 error "first index should be $min0_rec + 1 not $first_rec"
15906
15907         # LU-3446 changelog index reset on MDT restart
15908         local cur_rec1=$(changelog_users $SINGLEMDS |
15909                          awk '/^current.index:/ { print $NF }')
15910         changelog_clear 0 ||
15911                 error "clear all changelog records for $cl_user failed"
15912         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15913         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15914                 error "Fail to start $SINGLEMDS"
15915         local cur_rec2=$(changelog_users $SINGLEMDS |
15916                          awk '/^current.index:/ { print $NF }')
15917         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15918         [ $cur_rec1 == $cur_rec2 ] ||
15919                 error "current index should be $cur_rec1 not $cur_rec2"
15920
15921         echo "verifying users from this test are deregistered"
15922         changelog_deregister || error "changelog_deregister failed"
15923         changelog_users $SINGLEMDS | grep -q $cl_user &&
15924                 error "User '$cl_user' still in changelog_users"
15925
15926         # lctl get_param -n mdd.*.changelog_users
15927         # current_index: 144
15928         # ID    index (idle seconds)
15929         # cl3   144   (2) mask=<list>
15930         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15931                 # this is the normal case where all users were deregistered
15932                 # make sure no new records are added when no users are present
15933                 local last_rec1=$(changelog_users $SINGLEMDS |
15934                                   awk '/^current.index:/ { print $NF }')
15935                 touch $DIR/$tdir/chloe
15936                 local last_rec2=$(changelog_users $SINGLEMDS |
15937                                   awk '/^current.index:/ { print $NF }')
15938                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15939                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15940         else
15941                 # any changelog users must be leftovers from a previous test
15942                 changelog_users $SINGLEMDS
15943                 echo "other changelog users; can't verify off"
15944         fi
15945 }
15946 run_test 160a "changelog sanity"
15947
15948 test_160b() { # LU-3587
15949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15950         remote_mds_nodsh && skip "remote MDS with nodsh"
15951         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15952                 skip "Need MDS version at least 2.2.0"
15953
15954         changelog_register || error "changelog_register failed"
15955         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15956         changelog_users $SINGLEMDS | grep -q $cl_user ||
15957                 error "User '$cl_user' not found in changelog_users"
15958
15959         local longname1=$(str_repeat a 255)
15960         local longname2=$(str_repeat b 255)
15961
15962         cd $DIR
15963         echo "creating very long named file"
15964         touch $longname1 || error "create of '$longname1' failed"
15965         echo "renaming very long named file"
15966         mv $longname1 $longname2
15967
15968         changelog_dump | grep RENME | tail -n 5
15969         rm -f $longname2
15970 }
15971 run_test 160b "Verify that very long rename doesn't crash in changelog"
15972
15973 test_160c() {
15974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15975         remote_mds_nodsh && skip "remote MDS with nodsh"
15976
15977         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15978                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15979                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15980                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15981
15982         local rc=0
15983
15984         # Registration step
15985         changelog_register || error "changelog_register failed"
15986
15987         rm -rf $DIR/$tdir
15988         mkdir -p $DIR/$tdir
15989         $MCREATE $DIR/$tdir/foo_160c
15990         changelog_chmask "-TRUNC"
15991         $TRUNCATE $DIR/$tdir/foo_160c 200
15992         changelog_chmask "+TRUNC"
15993         $TRUNCATE $DIR/$tdir/foo_160c 199
15994         changelog_dump | tail -n 5
15995         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15996         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15997 }
15998 run_test 160c "verify that changelog log catch the truncate event"
15999
16000 test_160d() {
16001         remote_mds_nodsh && skip "remote MDS with nodsh"
16002         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16003         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16004         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16005                 skip "Need MDS version at least 2.7.60"
16006
16007         # Registration step
16008         changelog_register || error "changelog_register failed"
16009
16010         mkdir -p $DIR/$tdir/migrate_dir
16011         changelog_clear 0 || error "changelog_clear failed"
16012
16013         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16014         changelog_dump | tail -n 5
16015         local migrates=$(changelog_dump | grep -c "MIGRT")
16016         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16017 }
16018 run_test 160d "verify that changelog log catch the migrate event"
16019
16020 test_160e() {
16021         remote_mds_nodsh && skip "remote MDS with nodsh"
16022
16023         # Create a user
16024         changelog_register || error "changelog_register failed"
16025
16026         local MDT0=$(facet_svc $SINGLEMDS)
16027         local rc
16028
16029         # No user (expect fail)
16030         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16031         rc=$?
16032         if [ $rc -eq 0 ]; then
16033                 error "Should fail without user"
16034         elif [ $rc -ne 4 ]; then
16035                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16036         fi
16037
16038         # Delete a future user (expect fail)
16039         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16040         rc=$?
16041         if [ $rc -eq 0 ]; then
16042                 error "Deleted non-existant user cl77"
16043         elif [ $rc -ne 2 ]; then
16044                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16045         fi
16046
16047         # Clear to a bad index (1 billion should be safe)
16048         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16049         rc=$?
16050
16051         if [ $rc -eq 0 ]; then
16052                 error "Successfully cleared to invalid CL index"
16053         elif [ $rc -ne 22 ]; then
16054                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16055         fi
16056 }
16057 run_test 160e "changelog negative testing (should return errors)"
16058
16059 test_160f() {
16060         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16061         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16062                 skip "Need MDS version at least 2.10.56"
16063
16064         local mdts=$(comma_list $(mdts_nodes))
16065
16066         # Create a user
16067         changelog_register || error "first changelog_register failed"
16068         changelog_register || error "second changelog_register failed"
16069         local cl_users
16070         declare -A cl_user1
16071         declare -A cl_user2
16072         local user_rec1
16073         local user_rec2
16074         local i
16075
16076         # generate some changelog records to accumulate on each MDT
16077         # use all_char because created files should be evenly distributed
16078         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16079                 error "test_mkdir $tdir failed"
16080         log "$(date +%s): creating first files"
16081         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16082                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16083                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16084         done
16085
16086         # check changelogs have been generated
16087         local start=$SECONDS
16088         local idle_time=$((MDSCOUNT * 5 + 5))
16089         local nbcl=$(changelog_dump | wc -l)
16090         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16091
16092         for param in "changelog_max_idle_time=$idle_time" \
16093                      "changelog_gc=1" \
16094                      "changelog_min_gc_interval=2" \
16095                      "changelog_min_free_cat_entries=3"; do
16096                 local MDT0=$(facet_svc $SINGLEMDS)
16097                 local var="${param%=*}"
16098                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16099
16100                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16101                 do_nodes $mdts $LCTL set_param mdd.*.$param
16102         done
16103
16104         # force cl_user2 to be idle (1st part), but also cancel the
16105         # cl_user1 records so that it is not evicted later in the test.
16106         local sleep1=$((idle_time / 2))
16107         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16108         sleep $sleep1
16109
16110         # simulate changelog catalog almost full
16111         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16112         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16113
16114         for i in $(seq $MDSCOUNT); do
16115                 cl_users=(${CL_USERS[mds$i]})
16116                 cl_user1[mds$i]="${cl_users[0]}"
16117                 cl_user2[mds$i]="${cl_users[1]}"
16118
16119                 [ -n "${cl_user1[mds$i]}" ] ||
16120                         error "mds$i: no user registered"
16121                 [ -n "${cl_user2[mds$i]}" ] ||
16122                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16123
16124                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16125                 [ -n "$user_rec1" ] ||
16126                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16127                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16128                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16129                 [ -n "$user_rec2" ] ||
16130                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16131                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16132                      "$user_rec1 + 2 == $user_rec2"
16133                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16134                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16135                               "$user_rec1 + 2, but is $user_rec2"
16136                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16137                 [ -n "$user_rec2" ] ||
16138                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16139                 [ $user_rec1 == $user_rec2 ] ||
16140                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16141                               "$user_rec1, but is $user_rec2"
16142         done
16143
16144         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16145         local sleep2=$((idle_time - (SECONDS - start) + 1))
16146         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16147         sleep $sleep2
16148
16149         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16150         # cl_user1 should be OK because it recently processed records.
16151         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16152         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16153                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16154                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16155         done
16156
16157         # ensure gc thread is done
16158         for i in $(mdts_nodes); do
16159                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16160                         error "$i: GC-thread not done"
16161         done
16162
16163         local first_rec
16164         for (( i = 1; i <= MDSCOUNT; i++ )); do
16165                 # check cl_user1 still registered
16166                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16167                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16168                 # check cl_user2 unregistered
16169                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16170                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16171
16172                 # check changelogs are present and starting at $user_rec1 + 1
16173                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16174                 [ -n "$user_rec1" ] ||
16175                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16176                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16177                             awk '{ print $1; exit; }')
16178
16179                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16180                 [ $((user_rec1 + 1)) == $first_rec ] ||
16181                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16182         done
16183 }
16184 run_test 160f "changelog garbage collect (timestamped users)"
16185
16186 test_160g() {
16187         remote_mds_nodsh && skip "remote MDS with nodsh"
16188         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16189                 skip "Need MDS version at least 2.14.55"
16190
16191         local mdts=$(comma_list $(mdts_nodes))
16192
16193         # Create a user
16194         changelog_register || error "first changelog_register failed"
16195         changelog_register || error "second changelog_register failed"
16196         local cl_users
16197         declare -A cl_user1
16198         declare -A cl_user2
16199         local user_rec1
16200         local user_rec2
16201         local i
16202
16203         # generate some changelog records to accumulate on each MDT
16204         # use all_char because created files should be evenly distributed
16205         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16206                 error "test_mkdir $tdir failed"
16207         for ((i = 0; i < MDSCOUNT; i++)); do
16208                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16209                         error "create $DIR/$tdir/d$i.1 failed"
16210         done
16211
16212         # check changelogs have been generated
16213         local nbcl=$(changelog_dump | wc -l)
16214         (( $nbcl > 0 )) || error "no changelogs found"
16215
16216         # reduce the max_idle_indexes value to make sure we exceed it
16217         for param in "changelog_max_idle_indexes=2" \
16218                      "changelog_gc=1" \
16219                      "changelog_min_gc_interval=2"; do
16220                 local MDT0=$(facet_svc $SINGLEMDS)
16221                 local var="${param%=*}"
16222                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16223
16224                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16225                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16226                         error "unable to set mdd.*.$param"
16227         done
16228
16229         local start=$SECONDS
16230         for i in $(seq $MDSCOUNT); do
16231                 cl_users=(${CL_USERS[mds$i]})
16232                 cl_user1[mds$i]="${cl_users[0]}"
16233                 cl_user2[mds$i]="${cl_users[1]}"
16234
16235                 [ -n "${cl_user1[mds$i]}" ] ||
16236                         error "mds$i: user1 is not registered"
16237                 [ -n "${cl_user2[mds$i]}" ] ||
16238                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16239
16240                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16241                 [ -n "$user_rec1" ] ||
16242                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16243                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16244                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16245                 [ -n "$user_rec2" ] ||
16246                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16247                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16248                      "$user_rec1 + 2 == $user_rec2"
16249                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16250                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16251                               "expected $user_rec1 + 2, but is $user_rec2"
16252                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16253                 [ -n "$user_rec2" ] ||
16254                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16255                 [ $user_rec1 == $user_rec2 ] ||
16256                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16257                               "expected $user_rec1, but is $user_rec2"
16258         done
16259
16260         # ensure we are past the previous changelog_min_gc_interval set above
16261         local sleep2=$((start + 2 - SECONDS))
16262         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16263         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16264         # cl_user1 should be OK because it recently processed records.
16265         for ((i = 0; i < MDSCOUNT; i++)); do
16266                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16267                         error "create $DIR/$tdir/d$i.3 failed"
16268         done
16269
16270         # ensure gc thread is done
16271         for i in $(mdts_nodes); do
16272                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16273                         error "$i: GC-thread not done"
16274         done
16275
16276         local first_rec
16277         for (( i = 1; i <= MDSCOUNT; i++ )); do
16278                 # check cl_user1 still registered
16279                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16280                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16281                 # check cl_user2 unregistered
16282                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16283                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16284
16285                 # check changelogs are present and starting at $user_rec1 + 1
16286                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16287                 [ -n "$user_rec1" ] ||
16288                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16289                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16290                             awk '{ print $1; exit; }')
16291
16292                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16293                 [ $((user_rec1 + 1)) == $first_rec ] ||
16294                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16295         done
16296 }
16297 run_test 160g "changelog garbage collect on idle records"
16298
16299 test_160h() {
16300         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16301         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16302                 skip "Need MDS version at least 2.10.56"
16303
16304         local mdts=$(comma_list $(mdts_nodes))
16305
16306         # Create a user
16307         changelog_register || error "first changelog_register failed"
16308         changelog_register || error "second changelog_register failed"
16309         local cl_users
16310         declare -A cl_user1
16311         declare -A cl_user2
16312         local user_rec1
16313         local user_rec2
16314         local i
16315
16316         # generate some changelog records to accumulate on each MDT
16317         # use all_char because created files should be evenly distributed
16318         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16319                 error "test_mkdir $tdir failed"
16320         for ((i = 0; i < MDSCOUNT; i++)); do
16321                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16322                         error "create $DIR/$tdir/d$i.1 failed"
16323         done
16324
16325         # check changelogs have been generated
16326         local nbcl=$(changelog_dump | wc -l)
16327         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16328
16329         for param in "changelog_max_idle_time=10" \
16330                      "changelog_gc=1" \
16331                      "changelog_min_gc_interval=2"; do
16332                 local MDT0=$(facet_svc $SINGLEMDS)
16333                 local var="${param%=*}"
16334                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16335
16336                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16337                 do_nodes $mdts $LCTL set_param mdd.*.$param
16338         done
16339
16340         # force cl_user2 to be idle (1st part)
16341         sleep 9
16342
16343         for i in $(seq $MDSCOUNT); do
16344                 cl_users=(${CL_USERS[mds$i]})
16345                 cl_user1[mds$i]="${cl_users[0]}"
16346                 cl_user2[mds$i]="${cl_users[1]}"
16347
16348                 [ -n "${cl_user1[mds$i]}" ] ||
16349                         error "mds$i: no user registered"
16350                 [ -n "${cl_user2[mds$i]}" ] ||
16351                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16352
16353                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16354                 [ -n "$user_rec1" ] ||
16355                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16356                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16357                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16358                 [ -n "$user_rec2" ] ||
16359                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16360                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16361                      "$user_rec1 + 2 == $user_rec2"
16362                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16363                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16364                               "$user_rec1 + 2, but is $user_rec2"
16365                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16366                 [ -n "$user_rec2" ] ||
16367                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16368                 [ $user_rec1 == $user_rec2 ] ||
16369                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16370                               "$user_rec1, but is $user_rec2"
16371         done
16372
16373         # force cl_user2 to be idle (2nd part) and to reach
16374         # changelog_max_idle_time
16375         sleep 2
16376
16377         # force each GC-thread start and block then
16378         # one per MDT/MDD, set fail_val accordingly
16379         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16380         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16381
16382         # generate more changelogs to trigger fail_loc
16383         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16384                 error "create $DIR/$tdir/${tfile}bis failed"
16385
16386         # stop MDT to stop GC-thread, should be done in back-ground as it will
16387         # block waiting for the thread to be released and exit
16388         declare -A stop_pids
16389         for i in $(seq $MDSCOUNT); do
16390                 stop mds$i &
16391                 stop_pids[mds$i]=$!
16392         done
16393
16394         for i in $(mdts_nodes); do
16395                 local facet
16396                 local nb=0
16397                 local facets=$(facets_up_on_host $i)
16398
16399                 for facet in ${facets//,/ }; do
16400                         if [[ $facet == mds* ]]; then
16401                                 nb=$((nb + 1))
16402                         fi
16403                 done
16404                 # ensure each MDS's gc threads are still present and all in "R"
16405                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16406                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16407                         error "$i: expected $nb GC-thread"
16408                 wait_update $i \
16409                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16410                         "R" 20 ||
16411                         error "$i: GC-thread not found in R-state"
16412                 # check umounts of each MDT on MDS have reached kthread_stop()
16413                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16414                         error "$i: expected $nb umount"
16415                 wait_update $i \
16416                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16417                         error "$i: umount not found in D-state"
16418         done
16419
16420         # release all GC-threads
16421         do_nodes $mdts $LCTL set_param fail_loc=0
16422
16423         # wait for MDT stop to complete
16424         for i in $(seq $MDSCOUNT); do
16425                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16426         done
16427
16428         # XXX
16429         # may try to check if any orphan changelog records are present
16430         # via ldiskfs/zfs and llog_reader...
16431
16432         # re-start/mount MDTs
16433         for i in $(seq $MDSCOUNT); do
16434                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16435                         error "Fail to start mds$i"
16436         done
16437
16438         local first_rec
16439         for i in $(seq $MDSCOUNT); do
16440                 # check cl_user1 still registered
16441                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16442                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16443                 # check cl_user2 unregistered
16444                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16445                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16446
16447                 # check changelogs are present and starting at $user_rec1 + 1
16448                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16449                 [ -n "$user_rec1" ] ||
16450                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16451                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16452                             awk '{ print $1; exit; }')
16453
16454                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16455                 [ $((user_rec1 + 1)) == $first_rec ] ||
16456                         error "mds$i: first index should be $user_rec1 + 1, " \
16457                               "but is $first_rec"
16458         done
16459 }
16460 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16461               "during mount"
16462
16463 test_160i() {
16464
16465         local mdts=$(comma_list $(mdts_nodes))
16466
16467         changelog_register || error "first changelog_register failed"
16468
16469         # generate some changelog records to accumulate on each MDT
16470         # use all_char because created files should be evenly distributed
16471         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16472                 error "test_mkdir $tdir failed"
16473         for ((i = 0; i < MDSCOUNT; i++)); do
16474                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16475                         error "create $DIR/$tdir/d$i.1 failed"
16476         done
16477
16478         # check changelogs have been generated
16479         local nbcl=$(changelog_dump | wc -l)
16480         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16481
16482         # simulate race between register and unregister
16483         # XXX as fail_loc is set per-MDS, with DNE configs the race
16484         # simulation will only occur for one MDT per MDS and for the
16485         # others the normal race scenario will take place
16486         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16487         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16488         do_nodes $mdts $LCTL set_param fail_val=1
16489
16490         # unregister 1st user
16491         changelog_deregister &
16492         local pid1=$!
16493         # wait some time for deregister work to reach race rdv
16494         sleep 2
16495         # register 2nd user
16496         changelog_register || error "2nd user register failed"
16497
16498         wait $pid1 || error "1st user deregister failed"
16499
16500         local i
16501         local last_rec
16502         declare -A LAST_REC
16503         for i in $(seq $MDSCOUNT); do
16504                 if changelog_users mds$i | grep "^cl"; then
16505                         # make sure new records are added with one user present
16506                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16507                                           awk '/^current.index:/ { print $NF }')
16508                 else
16509                         error "mds$i has no user registered"
16510                 fi
16511         done
16512
16513         # generate more changelog records to accumulate on each MDT
16514         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16515                 error "create $DIR/$tdir/${tfile}bis failed"
16516
16517         for i in $(seq $MDSCOUNT); do
16518                 last_rec=$(changelog_users $SINGLEMDS |
16519                            awk '/^current.index:/ { print $NF }')
16520                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16521                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16522                         error "changelogs are off on mds$i"
16523         done
16524 }
16525 run_test 160i "changelog user register/unregister race"
16526
16527 test_160j() {
16528         remote_mds_nodsh && skip "remote MDS with nodsh"
16529         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16530                 skip "Need MDS version at least 2.12.56"
16531
16532         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16533         stack_trap "umount $MOUNT2" EXIT
16534
16535         changelog_register || error "first changelog_register failed"
16536         stack_trap "changelog_deregister" EXIT
16537
16538         # generate some changelog
16539         # use all_char because created files should be evenly distributed
16540         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16541                 error "mkdir $tdir failed"
16542         for ((i = 0; i < MDSCOUNT; i++)); do
16543                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16544                         error "create $DIR/$tdir/d$i.1 failed"
16545         done
16546
16547         # open the changelog device
16548         exec 3>/dev/changelog-$FSNAME-MDT0000
16549         stack_trap "exec 3>&-" EXIT
16550         exec 4</dev/changelog-$FSNAME-MDT0000
16551         stack_trap "exec 4<&-" EXIT
16552
16553         # umount the first lustre mount
16554         umount $MOUNT
16555         stack_trap "mount_client $MOUNT" EXIT
16556
16557         # read changelog, which may or may not fail, but should not crash
16558         cat <&4 >/dev/null
16559
16560         # clear changelog
16561         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16562         changelog_users $SINGLEMDS | grep -q $cl_user ||
16563                 error "User $cl_user not found in changelog_users"
16564
16565         printf 'clear:'$cl_user':0' >&3
16566 }
16567 run_test 160j "client can be umounted while its chanangelog is being used"
16568
16569 test_160k() {
16570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16571         remote_mds_nodsh && skip "remote MDS with nodsh"
16572
16573         mkdir -p $DIR/$tdir/1/1
16574
16575         changelog_register || error "changelog_register failed"
16576         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16577
16578         changelog_users $SINGLEMDS | grep -q $cl_user ||
16579                 error "User '$cl_user' not found in changelog_users"
16580 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16581         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16582         rmdir $DIR/$tdir/1/1 & sleep 1
16583         mkdir $DIR/$tdir/2
16584         touch $DIR/$tdir/2/2
16585         rm -rf $DIR/$tdir/2
16586
16587         wait
16588         sleep 4
16589
16590         changelog_dump | grep rmdir || error "rmdir not recorded"
16591 }
16592 run_test 160k "Verify that changelog records are not lost"
16593
16594 # Verifies that a file passed as a parameter has recently had an operation
16595 # performed on it that has generated an MTIME changelog which contains the
16596 # correct parent FID. As files might reside on a different MDT from the
16597 # parent directory in DNE configurations, the FIDs are translated to paths
16598 # before being compared, which should be identical
16599 compare_mtime_changelog() {
16600         local file="${1}"
16601         local mdtidx
16602         local mtime
16603         local cl_fid
16604         local pdir
16605         local dir
16606
16607         mdtidx=$($LFS getstripe --mdt-index $file)
16608         mdtidx=$(printf "%04x" $mdtidx)
16609
16610         # Obtain the parent FID from the MTIME changelog
16611         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16612         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16613
16614         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16615         [ -z "$cl_fid" ] && error "parent FID not present"
16616
16617         # Verify that the path for the parent FID is the same as the path for
16618         # the test directory
16619         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16620
16621         dir=$(dirname $1)
16622
16623         [[ "${pdir%/}" == "$dir" ]] ||
16624                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16625 }
16626
16627 test_160l() {
16628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16629
16630         remote_mds_nodsh && skip "remote MDS with nodsh"
16631         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16632                 skip "Need MDS version at least 2.13.55"
16633
16634         local cl_user
16635
16636         changelog_register || error "changelog_register failed"
16637         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16638
16639         changelog_users $SINGLEMDS | grep -q $cl_user ||
16640                 error "User '$cl_user' not found in changelog_users"
16641
16642         # Clear some types so that MTIME changelogs are generated
16643         changelog_chmask "-CREAT"
16644         changelog_chmask "-CLOSE"
16645
16646         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16647
16648         # Test CL_MTIME during setattr
16649         touch $DIR/$tdir/$tfile
16650         compare_mtime_changelog $DIR/$tdir/$tfile
16651
16652         # Test CL_MTIME during close
16653         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16654         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16655 }
16656 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16657
16658 test_160m() {
16659         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16660         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16661                 skip "Need MDS version at least 2.14.51"
16662         local cl_users
16663         local cl_user1
16664         local cl_user2
16665         local pid1
16666
16667         # Create a user
16668         changelog_register || error "first changelog_register failed"
16669         changelog_register || error "second changelog_register failed"
16670
16671         cl_users=(${CL_USERS[mds1]})
16672         cl_user1="${cl_users[0]}"
16673         cl_user2="${cl_users[1]}"
16674         # generate some changelog records to accumulate on MDT0
16675         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16676         createmany -m $DIR/$tdir/$tfile 50 ||
16677                 error "create $DIR/$tdir/$tfile failed"
16678         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16679         rm -f $DIR/$tdir
16680
16681         # check changelogs have been generated
16682         local nbcl=$(changelog_dump | wc -l)
16683         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16684
16685 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16686         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16687
16688         __changelog_clear mds1 $cl_user1 +10
16689         __changelog_clear mds1 $cl_user2 0 &
16690         pid1=$!
16691         sleep 2
16692         __changelog_clear mds1 $cl_user1 0 ||
16693                 error "fail to cancel record for $cl_user1"
16694         wait $pid1
16695         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16696 }
16697 run_test 160m "Changelog clear race"
16698
16699 test_160n() {
16700         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16701         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16702                 skip "Need MDS version at least 2.14.51"
16703         local cl_users
16704         local cl_user1
16705         local cl_user2
16706         local pid1
16707         local first_rec
16708         local last_rec=0
16709
16710         # Create a user
16711         changelog_register || error "first changelog_register failed"
16712
16713         cl_users=(${CL_USERS[mds1]})
16714         cl_user1="${cl_users[0]}"
16715
16716         # generate some changelog records to accumulate on MDT0
16717         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16718         first_rec=$(changelog_users $SINGLEMDS |
16719                         awk '/^current.index:/ { print $NF }')
16720         while (( last_rec < (( first_rec + 65000)) )); do
16721                 createmany -m $DIR/$tdir/$tfile 10000 ||
16722                         error "create $DIR/$tdir/$tfile failed"
16723
16724                 for i in $(seq 0 10000); do
16725                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16726                                 > /dev/null
16727                 done
16728
16729                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16730                         error "unlinkmany failed unlink"
16731                 last_rec=$(changelog_users $SINGLEMDS |
16732                         awk '/^current.index:/ { print $NF }')
16733                 echo last record $last_rec
16734                 (( last_rec == 0 )) && error "no changelog found"
16735         done
16736
16737 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16738         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16739
16740         __changelog_clear mds1 $cl_user1 0 &
16741         pid1=$!
16742         sleep 2
16743         __changelog_clear mds1 $cl_user1 0 ||
16744                 error "fail to cancel record for $cl_user1"
16745         wait $pid1
16746         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16747 }
16748 run_test 160n "Changelog destroy race"
16749
16750 test_160o() {
16751         local mdt="$(facet_svc $SINGLEMDS)"
16752
16753         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16754         remote_mds_nodsh && skip "remote MDS with nodsh"
16755         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16756                 skip "Need MDS version at least 2.14.52"
16757
16758         changelog_register --user test_160o -m unlnk+close+open ||
16759                 error "changelog_register failed"
16760
16761         do_facet $SINGLEMDS $LCTL --device $mdt \
16762                                 changelog_register -u "Tt3_-#" &&
16763                 error "bad symbols in name should fail"
16764
16765         do_facet $SINGLEMDS $LCTL --device $mdt \
16766                                 changelog_register -u test_160o &&
16767                 error "the same name registration should fail"
16768
16769         do_facet $SINGLEMDS $LCTL --device $mdt \
16770                         changelog_register -u test_160toolongname &&
16771                 error "too long name registration should fail"
16772
16773         changelog_chmask "MARK+HSM"
16774         lctl get_param mdd.*.changelog*mask
16775         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16776         changelog_users $SINGLEMDS | grep -q $cl_user ||
16777                 error "User $cl_user not found in changelog_users"
16778         #verify username
16779         echo $cl_user | grep -q test_160o ||
16780                 error "User $cl_user has no specific name 'test160o'"
16781
16782         # change something
16783         changelog_clear 0 || error "changelog_clear failed"
16784         # generate some changelog records to accumulate on MDT0
16785         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16786         touch $DIR/$tdir/$tfile                 # open 1
16787
16788         OPENS=$(changelog_dump | grep -c "OPEN")
16789         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16790
16791         # must be no MKDIR it wasn't set as user mask
16792         MKDIR=$(changelog_dump | grep -c "MKDIR")
16793         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16794
16795         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16796                                 mdd.$mdt.changelog_current_mask -n)
16797         # register maskless user
16798         changelog_register || error "changelog_register failed"
16799         # effective mask should be not changed because it is not minimal
16800         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16801                                 mdd.$mdt.changelog_current_mask -n)
16802         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16803         # set server mask to minimal value
16804         changelog_chmask "MARK"
16805         # check effective mask again, should be treated as DEFMASK now
16806         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16807                                 mdd.$mdt.changelog_current_mask -n)
16808         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16809
16810         do_facet $SINGLEMDS $LCTL --device $mdt \
16811                                 changelog_deregister -u test_160o ||
16812                 error "cannot deregister by name"
16813 }
16814 run_test 160o "changelog user name and mask"
16815
16816 test_160p() {
16817         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16818         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16819                 skip "Need MDS version at least 2.14.51"
16820         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16821         local cl_users
16822         local cl_user1
16823         local entry_count
16824
16825         # Create a user
16826         changelog_register || error "first changelog_register failed"
16827
16828         cl_users=(${CL_USERS[mds1]})
16829         cl_user1="${cl_users[0]}"
16830
16831         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16832         createmany -m $DIR/$tdir/$tfile 50 ||
16833                 error "create $DIR/$tdir/$tfile failed"
16834         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16835         rm -rf $DIR/$tdir
16836
16837         # check changelogs have been generated
16838         entry_count=$(changelog_dump | wc -l)
16839         ((entry_count != 0)) || error "no changelog entries found"
16840
16841         # remove changelog_users and check that orphan entries are removed
16842         stop mds1
16843         local dev=$(mdsdevname 1)
16844         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
16845         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
16846         entry_count=$(changelog_dump | wc -l)
16847         ((entry_count == 0)) ||
16848                 error "found $entry_count changelog entries, expected none"
16849 }
16850 run_test 160p "Changelog orphan cleanup with no users"
16851
16852 test_160q() {
16853         local mdt="$(facet_svc $SINGLEMDS)"
16854         local clu
16855
16856         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16857         remote_mds_nodsh && skip "remote MDS with nodsh"
16858         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16859                 skip "Need MDS version at least 2.14.54"
16860
16861         # set server mask to minimal value like server init does
16862         changelog_chmask "MARK"
16863         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16864                 error "changelog_register failed"
16865         # check effective mask again, should be treated as DEFMASK now
16866         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16867                                 mdd.$mdt.changelog_current_mask -n)
16868         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
16869                 error "changelog_deregister failed"
16870         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16871 }
16872 run_test 160q "changelog effective mask is DEFMASK if not set"
16873
16874 test_160s() {
16875         remote_mds_nodsh && skip "remote MDS with nodsh"
16876         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
16877                 skip "Need MDS version at least 2.14.55"
16878
16879         local mdts=$(comma_list $(mdts_nodes))
16880
16881         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
16882         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
16883                                        fail_val=$((24 * 3600 * 10))
16884
16885         # Create a user which is 10 days old
16886         changelog_register || error "first changelog_register failed"
16887         local cl_users
16888         declare -A cl_user1
16889         local i
16890
16891         # generate some changelog records to accumulate on each MDT
16892         # use all_char because created files should be evenly distributed
16893         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16894                 error "test_mkdir $tdir failed"
16895         for ((i = 0; i < MDSCOUNT; i++)); do
16896                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16897                         error "create $DIR/$tdir/d$i.1 failed"
16898         done
16899
16900         # check changelogs have been generated
16901         local nbcl=$(changelog_dump | wc -l)
16902         (( nbcl > 0 )) || error "no changelogs found"
16903
16904         # reduce the max_idle_indexes value to make sure we exceed it
16905         for param in "changelog_max_idle_indexes=2097446912" \
16906                      "changelog_max_idle_time=2592000" \
16907                      "changelog_gc=1" \
16908                      "changelog_min_gc_interval=2"; do
16909                 local MDT0=$(facet_svc $SINGLEMDS)
16910                 local var="${param%=*}"
16911                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16912
16913                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16914                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16915                         error "unable to set mdd.*.$param"
16916         done
16917
16918         local start=$SECONDS
16919         for i in $(seq $MDSCOUNT); do
16920                 cl_users=(${CL_USERS[mds$i]})
16921                 cl_user1[mds$i]="${cl_users[0]}"
16922
16923                 [[ -n "${cl_user1[mds$i]}" ]] ||
16924                         error "mds$i: no user registered"
16925         done
16926
16927         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
16928         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
16929
16930         # ensure we are past the previous changelog_min_gc_interval set above
16931         local sleep2=$((start + 2 - SECONDS))
16932         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16933
16934         # Generate one more changelog to trigger GC
16935         for ((i = 0; i < MDSCOUNT; i++)); do
16936                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
16937                         error "create $DIR/$tdir/d$i.3 failed"
16938         done
16939
16940         # ensure gc thread is done
16941         for node in $(mdts_nodes); do
16942                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
16943                         error "$node: GC-thread not done"
16944         done
16945
16946         do_nodes $mdts $LCTL set_param fail_loc=0
16947
16948         for (( i = 1; i <= MDSCOUNT; i++ )); do
16949                 # check cl_user1 is purged
16950                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
16951                         error "mds$i: User ${cl_user1[mds$i]} is registered"
16952         done
16953         return 0
16954 }
16955 run_test 160s "changelog garbage collect on idle records * time"
16956
16957 test_161a() {
16958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16959
16960         test_mkdir -c1 $DIR/$tdir
16961         cp /etc/hosts $DIR/$tdir/$tfile
16962         test_mkdir -c1 $DIR/$tdir/foo1
16963         test_mkdir -c1 $DIR/$tdir/foo2
16964         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16965         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16966         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16967         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16968         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16969         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16970                 $LFS fid2path $DIR $FID
16971                 error "bad link ea"
16972         fi
16973         # middle
16974         rm $DIR/$tdir/foo2/zachary
16975         # last
16976         rm $DIR/$tdir/foo2/thor
16977         # first
16978         rm $DIR/$tdir/$tfile
16979         # rename
16980         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16981         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16982                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16983         rm $DIR/$tdir/foo2/maggie
16984
16985         # overflow the EA
16986         local longname=$tfile.avg_len_is_thirty_two_
16987         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16988                 error_noexit 'failed to unlink many hardlinks'" EXIT
16989         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16990                 error "failed to hardlink many files"
16991         links=$($LFS fid2path $DIR $FID | wc -l)
16992         echo -n "${links}/1000 links in link EA"
16993         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16994 }
16995 run_test 161a "link ea sanity"
16996
16997 test_161b() {
16998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16999         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17000
17001         local MDTIDX=1
17002         local remote_dir=$DIR/$tdir/remote_dir
17003
17004         mkdir -p $DIR/$tdir
17005         $LFS mkdir -i $MDTIDX $remote_dir ||
17006                 error "create remote directory failed"
17007
17008         cp /etc/hosts $remote_dir/$tfile
17009         mkdir -p $remote_dir/foo1
17010         mkdir -p $remote_dir/foo2
17011         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17012         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17013         ln $remote_dir/$tfile $remote_dir/foo1/luna
17014         ln $remote_dir/$tfile $remote_dir/foo2/thor
17015
17016         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17017                      tr -d ']')
17018         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17019                 $LFS fid2path $DIR $FID
17020                 error "bad link ea"
17021         fi
17022         # middle
17023         rm $remote_dir/foo2/zachary
17024         # last
17025         rm $remote_dir/foo2/thor
17026         # first
17027         rm $remote_dir/$tfile
17028         # rename
17029         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17030         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17031         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17032                 $LFS fid2path $DIR $FID
17033                 error "bad link rename"
17034         fi
17035         rm $remote_dir/foo2/maggie
17036
17037         # overflow the EA
17038         local longname=filename_avg_len_is_thirty_two_
17039         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17040                 error "failed to hardlink many files"
17041         links=$($LFS fid2path $DIR $FID | wc -l)
17042         echo -n "${links}/1000 links in link EA"
17043         [[ ${links} -gt 60 ]] ||
17044                 error "expected at least 60 links in link EA"
17045         unlinkmany $remote_dir/foo2/$longname 1000 ||
17046         error "failed to unlink many hardlinks"
17047 }
17048 run_test 161b "link ea sanity under remote directory"
17049
17050 test_161c() {
17051         remote_mds_nodsh && skip "remote MDS with nodsh"
17052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17053         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17054                 skip "Need MDS version at least 2.1.5"
17055
17056         # define CLF_RENAME_LAST 0x0001
17057         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17058         changelog_register || error "changelog_register failed"
17059
17060         rm -rf $DIR/$tdir
17061         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17062         touch $DIR/$tdir/foo_161c
17063         touch $DIR/$tdir/bar_161c
17064         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17065         changelog_dump | grep RENME | tail -n 5
17066         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17067         changelog_clear 0 || error "changelog_clear failed"
17068         if [ x$flags != "x0x1" ]; then
17069                 error "flag $flags is not 0x1"
17070         fi
17071
17072         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17073         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17074         touch $DIR/$tdir/foo_161c
17075         touch $DIR/$tdir/bar_161c
17076         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17077         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17078         changelog_dump | grep RENME | tail -n 5
17079         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17080         changelog_clear 0 || error "changelog_clear failed"
17081         if [ x$flags != "x0x0" ]; then
17082                 error "flag $flags is not 0x0"
17083         fi
17084         echo "rename overwrite a target having nlink > 1," \
17085                 "changelog record has flags of $flags"
17086
17087         # rename doesn't overwrite a target (changelog flag 0x0)
17088         touch $DIR/$tdir/foo_161c
17089         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17090         changelog_dump | grep RENME | tail -n 5
17091         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17092         changelog_clear 0 || error "changelog_clear failed"
17093         if [ x$flags != "x0x0" ]; then
17094                 error "flag $flags is not 0x0"
17095         fi
17096         echo "rename doesn't overwrite a target," \
17097                 "changelog record has flags of $flags"
17098
17099         # define CLF_UNLINK_LAST 0x0001
17100         # unlink a file having nlink = 1 (changelog flag 0x1)
17101         rm -f $DIR/$tdir/foo2_161c
17102         changelog_dump | grep UNLNK | tail -n 5
17103         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17104         changelog_clear 0 || error "changelog_clear failed"
17105         if [ x$flags != "x0x1" ]; then
17106                 error "flag $flags is not 0x1"
17107         fi
17108         echo "unlink a file having nlink = 1," \
17109                 "changelog record has flags of $flags"
17110
17111         # unlink a file having nlink > 1 (changelog flag 0x0)
17112         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17113         rm -f $DIR/$tdir/foobar_161c
17114         changelog_dump | grep UNLNK | tail -n 5
17115         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17116         changelog_clear 0 || error "changelog_clear failed"
17117         if [ x$flags != "x0x0" ]; then
17118                 error "flag $flags is not 0x0"
17119         fi
17120         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17121 }
17122 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17123
17124 test_161d() {
17125         remote_mds_nodsh && skip "remote MDS with nodsh"
17126         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17127
17128         local pid
17129         local fid
17130
17131         changelog_register || error "changelog_register failed"
17132
17133         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17134         # interfer with $MOUNT/.lustre/fid/ access
17135         mkdir $DIR/$tdir
17136         [[ $? -eq 0 ]] || error "mkdir failed"
17137
17138         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17139         $LCTL set_param fail_loc=0x8000140c
17140         # 5s pause
17141         $LCTL set_param fail_val=5
17142
17143         # create file
17144         echo foofoo > $DIR/$tdir/$tfile &
17145         pid=$!
17146
17147         # wait for create to be delayed
17148         sleep 2
17149
17150         ps -p $pid
17151         [[ $? -eq 0 ]] || error "create should be blocked"
17152
17153         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17154         stack_trap "rm -f $tempfile"
17155         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17156         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17157         # some delay may occur during ChangeLog publishing and file read just
17158         # above, that could allow file write to happen finally
17159         [[ -s $tempfile ]] && echo "file should be empty"
17160
17161         $LCTL set_param fail_loc=0
17162
17163         wait $pid
17164         [[ $? -eq 0 ]] || error "create failed"
17165 }
17166 run_test 161d "create with concurrent .lustre/fid access"
17167
17168 check_path() {
17169         local expected="$1"
17170         shift
17171         local fid="$2"
17172
17173         local path
17174         path=$($LFS fid2path "$@")
17175         local rc=$?
17176
17177         if [ $rc -ne 0 ]; then
17178                 error "path looked up of '$expected' failed: rc=$rc"
17179         elif [ "$path" != "$expected" ]; then
17180                 error "path looked up '$path' instead of '$expected'"
17181         else
17182                 echo "FID '$fid' resolves to path '$path' as expected"
17183         fi
17184 }
17185
17186 test_162a() { # was test_162
17187         test_mkdir -p -c1 $DIR/$tdir/d2
17188         touch $DIR/$tdir/d2/$tfile
17189         touch $DIR/$tdir/d2/x1
17190         touch $DIR/$tdir/d2/x2
17191         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17192         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17193         # regular file
17194         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17195         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17196
17197         # softlink
17198         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17199         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17200         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17201
17202         # softlink to wrong file
17203         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17204         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17205         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17206
17207         # hardlink
17208         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17209         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17210         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17211         # fid2path dir/fsname should both work
17212         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17213         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17214
17215         # hardlink count: check that there are 2 links
17216         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17217         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17218
17219         # hardlink indexing: remove the first link
17220         rm $DIR/$tdir/d2/p/q/r/hlink
17221         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17222 }
17223 run_test 162a "path lookup sanity"
17224
17225 test_162b() {
17226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17227         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17228
17229         mkdir $DIR/$tdir
17230         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17231                                 error "create striped dir failed"
17232
17233         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17234                                         tail -n 1 | awk '{print $2}')
17235         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17236
17237         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17238         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17239
17240         # regular file
17241         for ((i=0;i<5;i++)); do
17242                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17243                         error "get fid for f$i failed"
17244                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17245
17246                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17247                         error "get fid for d$i failed"
17248                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17249         done
17250
17251         return 0
17252 }
17253 run_test 162b "striped directory path lookup sanity"
17254
17255 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17256 test_162c() {
17257         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17258                 skip "Need MDS version at least 2.7.51"
17259
17260         local lpath=$tdir.local
17261         local rpath=$tdir.remote
17262
17263         test_mkdir $DIR/$lpath
17264         test_mkdir $DIR/$rpath
17265
17266         for ((i = 0; i <= 101; i++)); do
17267                 lpath="$lpath/$i"
17268                 mkdir $DIR/$lpath
17269                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17270                         error "get fid for local directory $DIR/$lpath failed"
17271                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17272
17273                 rpath="$rpath/$i"
17274                 test_mkdir $DIR/$rpath
17275                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17276                         error "get fid for remote directory $DIR/$rpath failed"
17277                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17278         done
17279
17280         return 0
17281 }
17282 run_test 162c "fid2path works with paths 100 or more directories deep"
17283
17284 oalr_event_count() {
17285         local event="${1}"
17286         local trace="${2}"
17287
17288         awk -v name="${FSNAME}-OST0000" \
17289             -v event="${event}" \
17290             '$1 == "TRACE" && $2 == event && $3 == name' \
17291             "${trace}" |
17292         wc -l
17293 }
17294
17295 oalr_expect_event_count() {
17296         local event="${1}"
17297         local trace="${2}"
17298         local expect="${3}"
17299         local count
17300
17301         count=$(oalr_event_count "${event}" "${trace}")
17302         if ((count == expect)); then
17303                 return 0
17304         fi
17305
17306         error_noexit "${event} event count was '${count}', expected ${expect}"
17307         cat "${trace}" >&2
17308         exit 1
17309 }
17310
17311 cleanup_165() {
17312         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17313         stop ost1
17314         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17315 }
17316
17317 setup_165() {
17318         sync # Flush previous IOs so we can count log entries.
17319         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17320         stack_trap cleanup_165 EXIT
17321 }
17322
17323 test_165a() {
17324         local trace="/tmp/${tfile}.trace"
17325         local rc
17326         local count
17327
17328         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17329                 skip "OFD access log unsupported"
17330
17331         setup_165
17332         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17333         sleep 5
17334
17335         do_facet ost1 ofd_access_log_reader --list
17336         stop ost1
17337
17338         do_facet ost1 killall -TERM ofd_access_log_reader
17339         wait
17340         rc=$?
17341
17342         if ((rc != 0)); then
17343                 error "ofd_access_log_reader exited with rc = '${rc}'"
17344         fi
17345
17346         # Parse trace file for discovery events:
17347         oalr_expect_event_count alr_log_add "${trace}" 1
17348         oalr_expect_event_count alr_log_eof "${trace}" 1
17349         oalr_expect_event_count alr_log_free "${trace}" 1
17350 }
17351 run_test 165a "ofd access log discovery"
17352
17353 test_165b() {
17354         local trace="/tmp/${tfile}.trace"
17355         local file="${DIR}/${tfile}"
17356         local pfid1
17357         local pfid2
17358         local -a entry
17359         local rc
17360         local count
17361         local size
17362         local flags
17363
17364         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17365                 skip "OFD access log unsupported"
17366
17367         setup_165
17368         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17369         sleep 5
17370
17371         do_facet ost1 ofd_access_log_reader --list
17372
17373         lfs setstripe -c 1 -i 0 "${file}"
17374         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17375                 error "cannot create '${file}'"
17376
17377         sleep 5
17378         do_facet ost1 killall -TERM ofd_access_log_reader
17379         wait
17380         rc=$?
17381
17382         if ((rc != 0)); then
17383                 error "ofd_access_log_reader exited with rc = '${rc}'"
17384         fi
17385
17386         oalr_expect_event_count alr_log_entry "${trace}" 1
17387
17388         pfid1=$($LFS path2fid "${file}")
17389
17390         # 1     2             3   4    5     6   7    8    9     10
17391         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17392         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17393
17394         echo "entry = '${entry[*]}'" >&2
17395
17396         pfid2=${entry[4]}
17397         if [[ "${pfid1}" != "${pfid2}" ]]; then
17398                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17399         fi
17400
17401         size=${entry[8]}
17402         if ((size != 1048576)); then
17403                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17404         fi
17405
17406         flags=${entry[10]}
17407         if [[ "${flags}" != "w" ]]; then
17408                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17409         fi
17410
17411         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17412         sleep 5
17413
17414         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17415                 error "cannot read '${file}'"
17416         sleep 5
17417
17418         do_facet ost1 killall -TERM ofd_access_log_reader
17419         wait
17420         rc=$?
17421
17422         if ((rc != 0)); then
17423                 error "ofd_access_log_reader exited with rc = '${rc}'"
17424         fi
17425
17426         oalr_expect_event_count alr_log_entry "${trace}" 1
17427
17428         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17429         echo "entry = '${entry[*]}'" >&2
17430
17431         pfid2=${entry[4]}
17432         if [[ "${pfid1}" != "${pfid2}" ]]; then
17433                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17434         fi
17435
17436         size=${entry[8]}
17437         if ((size != 524288)); then
17438                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17439         fi
17440
17441         flags=${entry[10]}
17442         if [[ "${flags}" != "r" ]]; then
17443                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17444         fi
17445 }
17446 run_test 165b "ofd access log entries are produced and consumed"
17447
17448 test_165c() {
17449         local trace="/tmp/${tfile}.trace"
17450         local file="${DIR}/${tdir}/${tfile}"
17451
17452         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17453                 skip "OFD access log unsupported"
17454
17455         test_mkdir "${DIR}/${tdir}"
17456
17457         setup_165
17458         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17459         sleep 5
17460
17461         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17462
17463         # 4096 / 64 = 64. Create twice as many entries.
17464         for ((i = 0; i < 128; i++)); do
17465                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17466                         error "cannot create file"
17467         done
17468
17469         sync
17470
17471         do_facet ost1 killall -TERM ofd_access_log_reader
17472         wait
17473         rc=$?
17474         if ((rc != 0)); then
17475                 error "ofd_access_log_reader exited with rc = '${rc}'"
17476         fi
17477
17478         unlinkmany  "${file}-%d" 128
17479 }
17480 run_test 165c "full ofd access logs do not block IOs"
17481
17482 oal_get_read_count() {
17483         local stats="$1"
17484
17485         # STATS lustre-OST0001 alr_read_count 1
17486
17487         do_facet ost1 cat "${stats}" |
17488         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17489              END { print count; }'
17490 }
17491
17492 oal_expect_read_count() {
17493         local stats="$1"
17494         local count
17495         local expect="$2"
17496
17497         # Ask ofd_access_log_reader to write stats.
17498         do_facet ost1 killall -USR1 ofd_access_log_reader
17499
17500         # Allow some time for things to happen.
17501         sleep 1
17502
17503         count=$(oal_get_read_count "${stats}")
17504         if ((count == expect)); then
17505                 return 0
17506         fi
17507
17508         error_noexit "bad read count, got ${count}, expected ${expect}"
17509         do_facet ost1 cat "${stats}" >&2
17510         exit 1
17511 }
17512
17513 test_165d() {
17514         local stats="/tmp/${tfile}.stats"
17515         local file="${DIR}/${tdir}/${tfile}"
17516         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17517
17518         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17519                 skip "OFD access log unsupported"
17520
17521         test_mkdir "${DIR}/${tdir}"
17522
17523         setup_165
17524         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17525         sleep 5
17526
17527         lfs setstripe -c 1 -i 0 "${file}"
17528
17529         do_facet ost1 lctl set_param "${param}=rw"
17530         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17531                 error "cannot create '${file}'"
17532         oal_expect_read_count "${stats}" 1
17533
17534         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17535                 error "cannot read '${file}'"
17536         oal_expect_read_count "${stats}" 2
17537
17538         do_facet ost1 lctl set_param "${param}=r"
17539         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17540                 error "cannot create '${file}'"
17541         oal_expect_read_count "${stats}" 2
17542
17543         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17544                 error "cannot read '${file}'"
17545         oal_expect_read_count "${stats}" 3
17546
17547         do_facet ost1 lctl set_param "${param}=w"
17548         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17549                 error "cannot create '${file}'"
17550         oal_expect_read_count "${stats}" 4
17551
17552         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17553                 error "cannot read '${file}'"
17554         oal_expect_read_count "${stats}" 4
17555
17556         do_facet ost1 lctl set_param "${param}=0"
17557         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17558                 error "cannot create '${file}'"
17559         oal_expect_read_count "${stats}" 4
17560
17561         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17562                 error "cannot read '${file}'"
17563         oal_expect_read_count "${stats}" 4
17564
17565         do_facet ost1 killall -TERM ofd_access_log_reader
17566         wait
17567         rc=$?
17568         if ((rc != 0)); then
17569                 error "ofd_access_log_reader exited with rc = '${rc}'"
17570         fi
17571 }
17572 run_test 165d "ofd_access_log mask works"
17573
17574 test_165e() {
17575         local stats="/tmp/${tfile}.stats"
17576         local file0="${DIR}/${tdir}-0/${tfile}"
17577         local file1="${DIR}/${tdir}-1/${tfile}"
17578
17579         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17580                 skip "OFD access log unsupported"
17581
17582         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17583
17584         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17585         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17586
17587         lfs setstripe -c 1 -i 0 "${file0}"
17588         lfs setstripe -c 1 -i 0 "${file1}"
17589
17590         setup_165
17591         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17592         sleep 5
17593
17594         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17595                 error "cannot create '${file0}'"
17596         sync
17597         oal_expect_read_count "${stats}" 0
17598
17599         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17600                 error "cannot create '${file1}'"
17601         sync
17602         oal_expect_read_count "${stats}" 1
17603
17604         do_facet ost1 killall -TERM ofd_access_log_reader
17605         wait
17606         rc=$?
17607         if ((rc != 0)); then
17608                 error "ofd_access_log_reader exited with rc = '${rc}'"
17609         fi
17610 }
17611 run_test 165e "ofd_access_log MDT index filter works"
17612
17613 test_165f() {
17614         local trace="/tmp/${tfile}.trace"
17615         local rc
17616         local count
17617
17618         setup_165
17619         do_facet ost1 timeout 60 ofd_access_log_reader \
17620                 --exit-on-close --debug=- --trace=- > "${trace}" &
17621         sleep 5
17622         stop ost1
17623
17624         wait
17625         rc=$?
17626
17627         if ((rc != 0)); then
17628                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17629                 cat "${trace}"
17630                 exit 1
17631         fi
17632 }
17633 run_test 165f "ofd_access_log_reader --exit-on-close works"
17634
17635 test_169() {
17636         # do directio so as not to populate the page cache
17637         log "creating a 10 Mb file"
17638         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17639                 error "multiop failed while creating a file"
17640         log "starting reads"
17641         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17642         log "truncating the file"
17643         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17644                 error "multiop failed while truncating the file"
17645         log "killing dd"
17646         kill %+ || true # reads might have finished
17647         echo "wait until dd is finished"
17648         wait
17649         log "removing the temporary file"
17650         rm -rf $DIR/$tfile || error "tmp file removal failed"
17651 }
17652 run_test 169 "parallel read and truncate should not deadlock"
17653
17654 test_170() {
17655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17656
17657         $LCTL clear     # bug 18514
17658         $LCTL debug_daemon start $TMP/${tfile}_log_good
17659         touch $DIR/$tfile
17660         $LCTL debug_daemon stop
17661         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17662                 error "sed failed to read log_good"
17663
17664         $LCTL debug_daemon start $TMP/${tfile}_log_good
17665         rm -rf $DIR/$tfile
17666         $LCTL debug_daemon stop
17667
17668         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17669                error "lctl df log_bad failed"
17670
17671         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17672         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17673
17674         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17675         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17676
17677         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17678                 error "bad_line good_line1 good_line2 are empty"
17679
17680         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17681         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17682         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17683
17684         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17685         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17686         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17687
17688         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17689                 error "bad_line_new good_line_new are empty"
17690
17691         local expected_good=$((good_line1 + good_line2*2))
17692
17693         rm -f $TMP/${tfile}*
17694         # LU-231, short malformed line may not be counted into bad lines
17695         if [ $bad_line -ne $bad_line_new ] &&
17696                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17697                 error "expected $bad_line bad lines, but got $bad_line_new"
17698                 return 1
17699         fi
17700
17701         if [ $expected_good -ne $good_line_new ]; then
17702                 error "expected $expected_good good lines, but got $good_line_new"
17703                 return 2
17704         fi
17705         true
17706 }
17707 run_test 170 "test lctl df to handle corrupted log ====================="
17708
17709 test_171() { # bug20592
17710         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17711
17712         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17713         $LCTL set_param fail_loc=0x50e
17714         $LCTL set_param fail_val=3000
17715         multiop_bg_pause $DIR/$tfile O_s || true
17716         local MULTIPID=$!
17717         kill -USR1 $MULTIPID
17718         # cause log dump
17719         sleep 3
17720         wait $MULTIPID
17721         if dmesg | grep "recursive fault"; then
17722                 error "caught a recursive fault"
17723         fi
17724         $LCTL set_param fail_loc=0
17725         true
17726 }
17727 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17728
17729 # it would be good to share it with obdfilter-survey/iokit-libecho code
17730 setup_obdecho_osc () {
17731         local rc=0
17732         local ost_nid=$1
17733         local obdfilter_name=$2
17734         echo "Creating new osc for $obdfilter_name on $ost_nid"
17735         # make sure we can find loopback nid
17736         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17737
17738         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17739                            ${obdfilter_name}_osc_UUID || rc=2; }
17740         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17741                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17742         return $rc
17743 }
17744
17745 cleanup_obdecho_osc () {
17746         local obdfilter_name=$1
17747         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17748         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17749         return 0
17750 }
17751
17752 obdecho_test() {
17753         local OBD=$1
17754         local node=$2
17755         local pages=${3:-64}
17756         local rc=0
17757         local id
17758
17759         local count=10
17760         local obd_size=$(get_obd_size $node $OBD)
17761         local page_size=$(get_page_size $node)
17762         if [[ -n "$obd_size" ]]; then
17763                 local new_count=$((obd_size / (pages * page_size / 1024)))
17764                 [[ $new_count -ge $count ]] || count=$new_count
17765         fi
17766
17767         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17768         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17769                            rc=2; }
17770         if [ $rc -eq 0 ]; then
17771             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17772             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17773         fi
17774         echo "New object id is $id"
17775         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17776                            rc=4; }
17777         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17778                            "test_brw $count w v $pages $id" || rc=4; }
17779         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17780                            rc=4; }
17781         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17782                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17783         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17784                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17785         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17786         return $rc
17787 }
17788
17789 test_180a() {
17790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17791
17792         if ! [ -d /sys/fs/lustre/echo_client ] &&
17793            ! module_loaded obdecho; then
17794                 load_module obdecho/obdecho &&
17795                         stack_trap "rmmod obdecho" EXIT ||
17796                         error "unable to load obdecho on client"
17797         fi
17798
17799         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17800         local host=$($LCTL get_param -n osc.$osc.import |
17801                      awk '/current_connection:/ { print $2 }' )
17802         local target=$($LCTL get_param -n osc.$osc.import |
17803                        awk '/target:/ { print $2 }' )
17804         target=${target%_UUID}
17805
17806         if [ -n "$target" ]; then
17807                 setup_obdecho_osc $host $target &&
17808                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17809                         { error "obdecho setup failed with $?"; return; }
17810
17811                 obdecho_test ${target}_osc client ||
17812                         error "obdecho_test failed on ${target}_osc"
17813         else
17814                 $LCTL get_param osc.$osc.import
17815                 error "there is no osc.$osc.import target"
17816         fi
17817 }
17818 run_test 180a "test obdecho on osc"
17819
17820 test_180b() {
17821         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17822         remote_ost_nodsh && skip "remote OST with nodsh"
17823
17824         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17825                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17826                 error "failed to load module obdecho"
17827
17828         local target=$(do_facet ost1 $LCTL dl |
17829                        awk '/obdfilter/ { print $4; exit; }')
17830
17831         if [ -n "$target" ]; then
17832                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17833         else
17834                 do_facet ost1 $LCTL dl
17835                 error "there is no obdfilter target on ost1"
17836         fi
17837 }
17838 run_test 180b "test obdecho directly on obdfilter"
17839
17840 test_180c() { # LU-2598
17841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17842         remote_ost_nodsh && skip "remote OST with nodsh"
17843         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17844                 skip "Need MDS version at least 2.4.0"
17845
17846         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17847                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17848                 error "failed to load module obdecho"
17849
17850         local target=$(do_facet ost1 $LCTL dl |
17851                        awk '/obdfilter/ { print $4; exit; }')
17852
17853         if [ -n "$target" ]; then
17854                 local pages=16384 # 64MB bulk I/O RPC size
17855
17856                 obdecho_test "$target" ost1 "$pages" ||
17857                         error "obdecho_test with pages=$pages failed with $?"
17858         else
17859                 do_facet ost1 $LCTL dl
17860                 error "there is no obdfilter target on ost1"
17861         fi
17862 }
17863 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17864
17865 test_181() { # bug 22177
17866         test_mkdir $DIR/$tdir
17867         # create enough files to index the directory
17868         createmany -o $DIR/$tdir/foobar 4000
17869         # print attributes for debug purpose
17870         lsattr -d .
17871         # open dir
17872         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17873         MULTIPID=$!
17874         # remove the files & current working dir
17875         unlinkmany $DIR/$tdir/foobar 4000
17876         rmdir $DIR/$tdir
17877         kill -USR1 $MULTIPID
17878         wait $MULTIPID
17879         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17880         return 0
17881 }
17882 run_test 181 "Test open-unlinked dir ========================"
17883
17884 test_182() {
17885         local fcount=1000
17886         local tcount=10
17887
17888         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17889
17890         $LCTL set_param mdc.*.rpc_stats=clear
17891
17892         for (( i = 0; i < $tcount; i++ )) ; do
17893                 mkdir $DIR/$tdir/$i
17894         done
17895
17896         for (( i = 0; i < $tcount; i++ )) ; do
17897                 createmany -o $DIR/$tdir/$i/f- $fcount &
17898         done
17899         wait
17900
17901         for (( i = 0; i < $tcount; i++ )) ; do
17902                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17903         done
17904         wait
17905
17906         $LCTL get_param mdc.*.rpc_stats
17907
17908         rm -rf $DIR/$tdir
17909 }
17910 run_test 182 "Test parallel modify metadata operations ================"
17911
17912 test_183() { # LU-2275
17913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17914         remote_mds_nodsh && skip "remote MDS with nodsh"
17915         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17916                 skip "Need MDS version at least 2.3.56"
17917
17918         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17919         echo aaa > $DIR/$tdir/$tfile
17920
17921 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17922         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17923
17924         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17925         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17926
17927         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17928
17929         # Flush negative dentry cache
17930         touch $DIR/$tdir/$tfile
17931
17932         # We are not checking for any leaked references here, they'll
17933         # become evident next time we do cleanup with module unload.
17934         rm -rf $DIR/$tdir
17935 }
17936 run_test 183 "No crash or request leak in case of strange dispositions ========"
17937
17938 # test suite 184 is for LU-2016, LU-2017
17939 test_184a() {
17940         check_swap_layouts_support
17941
17942         dir0=$DIR/$tdir/$testnum
17943         test_mkdir -p -c1 $dir0
17944         ref1=/etc/passwd
17945         ref2=/etc/group
17946         file1=$dir0/f1
17947         file2=$dir0/f2
17948         $LFS setstripe -c1 $file1
17949         cp $ref1 $file1
17950         $LFS setstripe -c2 $file2
17951         cp $ref2 $file2
17952         gen1=$($LFS getstripe -g $file1)
17953         gen2=$($LFS getstripe -g $file2)
17954
17955         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17956         gen=$($LFS getstripe -g $file1)
17957         [[ $gen1 != $gen ]] ||
17958                 error "Layout generation on $file1 does not change"
17959         gen=$($LFS getstripe -g $file2)
17960         [[ $gen2 != $gen ]] ||
17961                 error "Layout generation on $file2 does not change"
17962
17963         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17964         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17965
17966         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17967 }
17968 run_test 184a "Basic layout swap"
17969
17970 test_184b() {
17971         check_swap_layouts_support
17972
17973         dir0=$DIR/$tdir/$testnum
17974         mkdir -p $dir0 || error "creating dir $dir0"
17975         file1=$dir0/f1
17976         file2=$dir0/f2
17977         file3=$dir0/f3
17978         dir1=$dir0/d1
17979         dir2=$dir0/d2
17980         mkdir $dir1 $dir2
17981         $LFS setstripe -c1 $file1
17982         $LFS setstripe -c2 $file2
17983         $LFS setstripe -c1 $file3
17984         chown $RUNAS_ID $file3
17985         gen1=$($LFS getstripe -g $file1)
17986         gen2=$($LFS getstripe -g $file2)
17987
17988         $LFS swap_layouts $dir1 $dir2 &&
17989                 error "swap of directories layouts should fail"
17990         $LFS swap_layouts $dir1 $file1 &&
17991                 error "swap of directory and file layouts should fail"
17992         $RUNAS $LFS swap_layouts $file1 $file2 &&
17993                 error "swap of file we cannot write should fail"
17994         $LFS swap_layouts $file1 $file3 &&
17995                 error "swap of file with different owner should fail"
17996         /bin/true # to clear error code
17997 }
17998 run_test 184b "Forbidden layout swap (will generate errors)"
17999
18000 test_184c() {
18001         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18002         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18003         check_swap_layouts_support
18004         check_swap_layout_no_dom $DIR
18005
18006         local dir0=$DIR/$tdir/$testnum
18007         mkdir -p $dir0 || error "creating dir $dir0"
18008
18009         local ref1=$dir0/ref1
18010         local ref2=$dir0/ref2
18011         local file1=$dir0/file1
18012         local file2=$dir0/file2
18013         # create a file large enough for the concurrent test
18014         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18015         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18016         echo "ref file size: ref1($(stat -c %s $ref1))," \
18017              "ref2($(stat -c %s $ref2))"
18018
18019         cp $ref2 $file2
18020         dd if=$ref1 of=$file1 bs=16k &
18021         local DD_PID=$!
18022
18023         # Make sure dd starts to copy file, but wait at most 5 seconds
18024         local loops=0
18025         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18026
18027         $LFS swap_layouts $file1 $file2
18028         local rc=$?
18029         wait $DD_PID
18030         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18031         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18032
18033         # how many bytes copied before swapping layout
18034         local copied=$(stat -c %s $file2)
18035         local remaining=$(stat -c %s $ref1)
18036         remaining=$((remaining - copied))
18037         echo "Copied $copied bytes before swapping layout..."
18038
18039         cmp -n $copied $file1 $ref2 | grep differ &&
18040                 error "Content mismatch [0, $copied) of ref2 and file1"
18041         cmp -n $copied $file2 $ref1 ||
18042                 error "Content mismatch [0, $copied) of ref1 and file2"
18043         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18044                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18045
18046         # clean up
18047         rm -f $ref1 $ref2 $file1 $file2
18048 }
18049 run_test 184c "Concurrent write and layout swap"
18050
18051 test_184d() {
18052         check_swap_layouts_support
18053         check_swap_layout_no_dom $DIR
18054         [ -z "$(which getfattr 2>/dev/null)" ] &&
18055                 skip_env "no getfattr command"
18056
18057         local file1=$DIR/$tdir/$tfile-1
18058         local file2=$DIR/$tdir/$tfile-2
18059         local file3=$DIR/$tdir/$tfile-3
18060         local lovea1
18061         local lovea2
18062
18063         mkdir -p $DIR/$tdir
18064         touch $file1 || error "create $file1 failed"
18065         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18066                 error "create $file2 failed"
18067         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18068                 error "create $file3 failed"
18069         lovea1=$(get_layout_param $file1)
18070
18071         $LFS swap_layouts $file2 $file3 ||
18072                 error "swap $file2 $file3 layouts failed"
18073         $LFS swap_layouts $file1 $file2 ||
18074                 error "swap $file1 $file2 layouts failed"
18075
18076         lovea2=$(get_layout_param $file2)
18077         echo "$lovea1"
18078         echo "$lovea2"
18079         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18080
18081         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18082         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18083 }
18084 run_test 184d "allow stripeless layouts swap"
18085
18086 test_184e() {
18087         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18088                 skip "Need MDS version at least 2.6.94"
18089         check_swap_layouts_support
18090         check_swap_layout_no_dom $DIR
18091         [ -z "$(which getfattr 2>/dev/null)" ] &&
18092                 skip_env "no getfattr command"
18093
18094         local file1=$DIR/$tdir/$tfile-1
18095         local file2=$DIR/$tdir/$tfile-2
18096         local file3=$DIR/$tdir/$tfile-3
18097         local lovea
18098
18099         mkdir -p $DIR/$tdir
18100         touch $file1 || error "create $file1 failed"
18101         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18102                 error "create $file2 failed"
18103         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18104                 error "create $file3 failed"
18105
18106         $LFS swap_layouts $file1 $file2 ||
18107                 error "swap $file1 $file2 layouts failed"
18108
18109         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18110         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18111
18112         echo 123 > $file1 || error "Should be able to write into $file1"
18113
18114         $LFS swap_layouts $file1 $file3 ||
18115                 error "swap $file1 $file3 layouts failed"
18116
18117         echo 123 > $file1 || error "Should be able to write into $file1"
18118
18119         rm -rf $file1 $file2 $file3
18120 }
18121 run_test 184e "Recreate layout after stripeless layout swaps"
18122
18123 test_184f() {
18124         # Create a file with name longer than sizeof(struct stat) ==
18125         # 144 to see if we can get chars from the file name to appear
18126         # in the returned striping. Note that 'f' == 0x66.
18127         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18128
18129         mkdir -p $DIR/$tdir
18130         mcreate $DIR/$tdir/$file
18131         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18132                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18133         fi
18134 }
18135 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18136
18137 test_185() { # LU-2441
18138         # LU-3553 - no volatile file support in old servers
18139         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18140                 skip "Need MDS version at least 2.3.60"
18141
18142         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18143         touch $DIR/$tdir/spoo
18144         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18145         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18146                 error "cannot create/write a volatile file"
18147         [ "$FILESET" == "" ] &&
18148         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18149                 error "FID is still valid after close"
18150
18151         multiop_bg_pause $DIR/$tdir vVw4096_c
18152         local multi_pid=$!
18153
18154         local OLD_IFS=$IFS
18155         IFS=":"
18156         local fidv=($fid)
18157         IFS=$OLD_IFS
18158         # assume that the next FID for this client is sequential, since stdout
18159         # is unfortunately eaten by multiop_bg_pause
18160         local n=$((${fidv[1]} + 1))
18161         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18162         if [ "$FILESET" == "" ]; then
18163                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18164                         error "FID is missing before close"
18165         fi
18166         kill -USR1 $multi_pid
18167         # 1 second delay, so if mtime change we will see it
18168         sleep 1
18169         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18170         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18171 }
18172 run_test 185 "Volatile file support"
18173
18174 function create_check_volatile() {
18175         local idx=$1
18176         local tgt
18177
18178         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18179         local PID=$!
18180         sleep 1
18181         local FID=$(cat /tmp/${tfile}.fid)
18182         [ "$FID" == "" ] && error "can't get FID for volatile"
18183         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18184         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18185         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18186         kill -USR1 $PID
18187         wait
18188         sleep 1
18189         cancel_lru_locks mdc # flush opencache
18190         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18191         return 0
18192 }
18193
18194 test_185a(){
18195         # LU-12516 - volatile creation via .lustre
18196         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18197                 skip "Need MDS version at least 2.3.55"
18198
18199         create_check_volatile 0
18200         [ $MDSCOUNT -lt 2 ] && return 0
18201
18202         # DNE case
18203         create_check_volatile 1
18204
18205         return 0
18206 }
18207 run_test 185a "Volatile file creation in .lustre/fid/"
18208
18209 test_187a() {
18210         remote_mds_nodsh && skip "remote MDS with nodsh"
18211         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18212                 skip "Need MDS version at least 2.3.0"
18213
18214         local dir0=$DIR/$tdir/$testnum
18215         mkdir -p $dir0 || error "creating dir $dir0"
18216
18217         local file=$dir0/file1
18218         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18219         local dv1=$($LFS data_version $file)
18220         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18221         local dv2=$($LFS data_version $file)
18222         [[ $dv1 != $dv2 ]] ||
18223                 error "data version did not change on write $dv1 == $dv2"
18224
18225         # clean up
18226         rm -f $file1
18227 }
18228 run_test 187a "Test data version change"
18229
18230 test_187b() {
18231         remote_mds_nodsh && skip "remote MDS with nodsh"
18232         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18233                 skip "Need MDS version at least 2.3.0"
18234
18235         local dir0=$DIR/$tdir/$testnum
18236         mkdir -p $dir0 || error "creating dir $dir0"
18237
18238         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18239         [[ ${DV[0]} != ${DV[1]} ]] ||
18240                 error "data version did not change on write"\
18241                       " ${DV[0]} == ${DV[1]}"
18242
18243         # clean up
18244         rm -f $file1
18245 }
18246 run_test 187b "Test data version change on volatile file"
18247
18248 test_200() {
18249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18250         remote_mgs_nodsh && skip "remote MGS with nodsh"
18251         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18252
18253         local POOL=${POOL:-cea1}
18254         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18255         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18256         # Pool OST targets
18257         local first_ost=0
18258         local last_ost=$(($OSTCOUNT - 1))
18259         local ost_step=2
18260         local ost_list=$(seq $first_ost $ost_step $last_ost)
18261         local ost_range="$first_ost $last_ost $ost_step"
18262         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18263         local file_dir=$POOL_ROOT/file_tst
18264         local subdir=$test_path/subdir
18265         local rc=0
18266
18267         while : ; do
18268                 # former test_200a test_200b
18269                 pool_add $POOL                          || { rc=$? ; break; }
18270                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18271                 # former test_200c test_200d
18272                 mkdir -p $test_path
18273                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18274                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18275                 mkdir -p $subdir
18276                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18277                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18278                                                         || { rc=$? ; break; }
18279                 # former test_200e test_200f
18280                 local files=$((OSTCOUNT*3))
18281                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18282                                                         || { rc=$? ; break; }
18283                 pool_create_files $POOL $file_dir $files "$ost_list" \
18284                                                         || { rc=$? ; break; }
18285                 # former test_200g test_200h
18286                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18287                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18288
18289                 # former test_201a test_201b test_201c
18290                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18291
18292                 local f=$test_path/$tfile
18293                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18294                 pool_remove $POOL $f                    || { rc=$? ; break; }
18295                 break
18296         done
18297
18298         destroy_test_pools
18299
18300         return $rc
18301 }
18302 run_test 200 "OST pools"
18303
18304 # usage: default_attr <count | size | offset>
18305 default_attr() {
18306         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18307 }
18308
18309 # usage: check_default_stripe_attr
18310 check_default_stripe_attr() {
18311         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18312         case $1 in
18313         --stripe-count|-c)
18314                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18315         --stripe-size|-S)
18316                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18317         --stripe-index|-i)
18318                 EXPECTED=-1;;
18319         *)
18320                 error "unknown getstripe attr '$1'"
18321         esac
18322
18323         [ $ACTUAL == $EXPECTED ] ||
18324                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18325 }
18326
18327 test_204a() {
18328         test_mkdir $DIR/$tdir
18329         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18330
18331         check_default_stripe_attr --stripe-count
18332         check_default_stripe_attr --stripe-size
18333         check_default_stripe_attr --stripe-index
18334 }
18335 run_test 204a "Print default stripe attributes"
18336
18337 test_204b() {
18338         test_mkdir $DIR/$tdir
18339         $LFS setstripe --stripe-count 1 $DIR/$tdir
18340
18341         check_default_stripe_attr --stripe-size
18342         check_default_stripe_attr --stripe-index
18343 }
18344 run_test 204b "Print default stripe size and offset"
18345
18346 test_204c() {
18347         test_mkdir $DIR/$tdir
18348         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18349
18350         check_default_stripe_attr --stripe-count
18351         check_default_stripe_attr --stripe-index
18352 }
18353 run_test 204c "Print default stripe count and offset"
18354
18355 test_204d() {
18356         test_mkdir $DIR/$tdir
18357         $LFS setstripe --stripe-index 0 $DIR/$tdir
18358
18359         check_default_stripe_attr --stripe-count
18360         check_default_stripe_attr --stripe-size
18361 }
18362 run_test 204d "Print default stripe count and size"
18363
18364 test_204e() {
18365         test_mkdir $DIR/$tdir
18366         $LFS setstripe -d $DIR/$tdir
18367
18368         check_default_stripe_attr --stripe-count --raw
18369         check_default_stripe_attr --stripe-size --raw
18370         check_default_stripe_attr --stripe-index --raw
18371 }
18372 run_test 204e "Print raw stripe attributes"
18373
18374 test_204f() {
18375         test_mkdir $DIR/$tdir
18376         $LFS setstripe --stripe-count 1 $DIR/$tdir
18377
18378         check_default_stripe_attr --stripe-size --raw
18379         check_default_stripe_attr --stripe-index --raw
18380 }
18381 run_test 204f "Print raw stripe size and offset"
18382
18383 test_204g() {
18384         test_mkdir $DIR/$tdir
18385         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18386
18387         check_default_stripe_attr --stripe-count --raw
18388         check_default_stripe_attr --stripe-index --raw
18389 }
18390 run_test 204g "Print raw stripe count and offset"
18391
18392 test_204h() {
18393         test_mkdir $DIR/$tdir
18394         $LFS setstripe --stripe-index 0 $DIR/$tdir
18395
18396         check_default_stripe_attr --stripe-count --raw
18397         check_default_stripe_attr --stripe-size --raw
18398 }
18399 run_test 204h "Print raw stripe count and size"
18400
18401 # Figure out which job scheduler is being used, if any,
18402 # or use a fake one
18403 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18404         JOBENV=SLURM_JOB_ID
18405 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18406         JOBENV=LSB_JOBID
18407 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18408         JOBENV=PBS_JOBID
18409 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18410         JOBENV=LOADL_STEP_ID
18411 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18412         JOBENV=JOB_ID
18413 else
18414         $LCTL list_param jobid_name > /dev/null 2>&1
18415         if [ $? -eq 0 ]; then
18416                 JOBENV=nodelocal
18417         else
18418                 JOBENV=FAKE_JOBID
18419         fi
18420 fi
18421 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18422
18423 verify_jobstats() {
18424         local cmd=($1)
18425         shift
18426         local facets="$@"
18427
18428 # we don't really need to clear the stats for this test to work, since each
18429 # command has a unique jobid, but it makes debugging easier if needed.
18430 #       for facet in $facets; do
18431 #               local dev=$(convert_facet2label $facet)
18432 #               # clear old jobstats
18433 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18434 #       done
18435
18436         # use a new JobID for each test, or we might see an old one
18437         [ "$JOBENV" = "FAKE_JOBID" ] &&
18438                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18439
18440         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18441
18442         [ "$JOBENV" = "nodelocal" ] && {
18443                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18444                 $LCTL set_param jobid_name=$FAKE_JOBID
18445                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18446         }
18447
18448         log "Test: ${cmd[*]}"
18449         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18450
18451         if [ $JOBENV = "FAKE_JOBID" ]; then
18452                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18453         else
18454                 ${cmd[*]}
18455         fi
18456
18457         # all files are created on OST0000
18458         for facet in $facets; do
18459                 local stats="*.$(convert_facet2label $facet).job_stats"
18460
18461                 # strip out libtool wrappers for in-tree executables
18462                 if (( $(do_facet $facet lctl get_param $stats |
18463                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18464                         do_facet $facet lctl get_param $stats
18465                         error "No jobstats for $JOBVAL found on $facet::$stats"
18466                 fi
18467         done
18468 }
18469
18470 jobstats_set() {
18471         local new_jobenv=$1
18472
18473         set_persistent_param_and_check client "jobid_var" \
18474                 "$FSNAME.sys.jobid_var" $new_jobenv
18475 }
18476
18477 test_205a() { # Job stats
18478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18479         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18480                 skip "Need MDS version with at least 2.7.1"
18481         remote_mgs_nodsh && skip "remote MGS with nodsh"
18482         remote_mds_nodsh && skip "remote MDS with nodsh"
18483         remote_ost_nodsh && skip "remote OST with nodsh"
18484         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18485                 skip "Server doesn't support jobstats"
18486         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18487
18488         local old_jobenv=$($LCTL get_param -n jobid_var)
18489         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18490
18491         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18492                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18493         else
18494                 stack_trap "do_facet mgs $PERM_CMD \
18495                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18496         fi
18497         changelog_register
18498
18499         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18500                                 mdt.*.job_cleanup_interval | head -n 1)
18501         local new_interval=5
18502         do_facet $SINGLEMDS \
18503                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18504         stack_trap "do_facet $SINGLEMDS \
18505                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18506         local start=$SECONDS
18507
18508         local cmd
18509         # mkdir
18510         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18511         verify_jobstats "$cmd" "$SINGLEMDS"
18512         # rmdir
18513         cmd="rmdir $DIR/$tdir"
18514         verify_jobstats "$cmd" "$SINGLEMDS"
18515         # mkdir on secondary MDT
18516         if [ $MDSCOUNT -gt 1 ]; then
18517                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18518                 verify_jobstats "$cmd" "mds2"
18519         fi
18520         # mknod
18521         cmd="mknod $DIR/$tfile c 1 3"
18522         verify_jobstats "$cmd" "$SINGLEMDS"
18523         # unlink
18524         cmd="rm -f $DIR/$tfile"
18525         verify_jobstats "$cmd" "$SINGLEMDS"
18526         # create all files on OST0000 so verify_jobstats can find OST stats
18527         # open & close
18528         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18529         verify_jobstats "$cmd" "$SINGLEMDS"
18530         # setattr
18531         cmd="touch $DIR/$tfile"
18532         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18533         # write
18534         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18535         verify_jobstats "$cmd" "ost1"
18536         # read
18537         cancel_lru_locks osc
18538         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18539         verify_jobstats "$cmd" "ost1"
18540         # truncate
18541         cmd="$TRUNCATE $DIR/$tfile 0"
18542         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18543         # rename
18544         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18545         verify_jobstats "$cmd" "$SINGLEMDS"
18546         # jobstats expiry - sleep until old stats should be expired
18547         local left=$((new_interval + 5 - (SECONDS - start)))
18548         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18549                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18550                         "0" $left
18551         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18552         verify_jobstats "$cmd" "$SINGLEMDS"
18553         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18554             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18555
18556         # Ensure that jobid are present in changelog (if supported by MDS)
18557         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18558                 changelog_dump | tail -10
18559                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18560                 [ $jobids -eq 9 ] ||
18561                         error "Wrong changelog jobid count $jobids != 9"
18562
18563                 # LU-5862
18564                 JOBENV="disable"
18565                 jobstats_set $JOBENV
18566                 touch $DIR/$tfile
18567                 changelog_dump | grep $tfile
18568                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18569                 [ $jobids -eq 0 ] ||
18570                         error "Unexpected jobids when jobid_var=$JOBENV"
18571         fi
18572
18573         # test '%j' access to environment variable - if supported
18574         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18575                 JOBENV="JOBCOMPLEX"
18576                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18577
18578                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18579         fi
18580
18581         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18582                 JOBENV="JOBCOMPLEX"
18583                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18584
18585                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18586         fi
18587
18588         # test '%j' access to per-session jobid - if supported
18589         if lctl list_param jobid_this_session > /dev/null 2>&1
18590         then
18591                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18592                 lctl set_param jobid_this_session=$USER
18593
18594                 JOBENV="JOBCOMPLEX"
18595                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18596
18597                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18598         fi
18599 }
18600 run_test 205a "Verify job stats"
18601
18602 # LU-13117, LU-13597
18603 test_205b() {
18604         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18605                 skip "Need MDS version at least 2.13.54.91"
18606
18607         job_stats="mdt.*.job_stats"
18608         $LCTL set_param $job_stats=clear
18609         # Setting jobid_var to USER might not be supported
18610         $LCTL set_param jobid_var=USER || true
18611         $LCTL set_param jobid_name="%e.%u"
18612         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18613         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18614                 grep "job_id:.*foolish" &&
18615                         error "Unexpected jobid found"
18616         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18617                 grep "open:.*min.*max.*sum" ||
18618                         error "wrong job_stats format found"
18619 }
18620 run_test 205b "Verify job stats jobid and output format"
18621
18622 # LU-13733
18623 test_205c() {
18624         $LCTL set_param llite.*.stats=0
18625         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18626         $LCTL get_param llite.*.stats
18627         $LCTL get_param llite.*.stats | grep \
18628                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18629                         error "wrong client stats format found"
18630 }
18631 run_test 205c "Verify client stats format"
18632
18633 # LU-1480, LU-1773 and LU-1657
18634 test_206() {
18635         mkdir -p $DIR/$tdir
18636         $LFS setstripe -c -1 $DIR/$tdir
18637 #define OBD_FAIL_LOV_INIT 0x1403
18638         $LCTL set_param fail_loc=0xa0001403
18639         $LCTL set_param fail_val=1
18640         touch $DIR/$tdir/$tfile || true
18641 }
18642 run_test 206 "fail lov_init_raid0() doesn't lbug"
18643
18644 test_207a() {
18645         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18646         local fsz=`stat -c %s $DIR/$tfile`
18647         cancel_lru_locks mdc
18648
18649         # do not return layout in getattr intent
18650 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18651         $LCTL set_param fail_loc=0x170
18652         local sz=`stat -c %s $DIR/$tfile`
18653
18654         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18655
18656         rm -rf $DIR/$tfile
18657 }
18658 run_test 207a "can refresh layout at glimpse"
18659
18660 test_207b() {
18661         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18662         local cksum=`md5sum $DIR/$tfile`
18663         local fsz=`stat -c %s $DIR/$tfile`
18664         cancel_lru_locks mdc
18665         cancel_lru_locks osc
18666
18667         # do not return layout in getattr intent
18668 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18669         $LCTL set_param fail_loc=0x171
18670
18671         # it will refresh layout after the file is opened but before read issues
18672         echo checksum is "$cksum"
18673         echo "$cksum" |md5sum -c --quiet || error "file differs"
18674
18675         rm -rf $DIR/$tfile
18676 }
18677 run_test 207b "can refresh layout at open"
18678
18679 test_208() {
18680         # FIXME: in this test suite, only RD lease is used. This is okay
18681         # for now as only exclusive open is supported. After generic lease
18682         # is done, this test suite should be revised. - Jinshan
18683
18684         remote_mds_nodsh && skip "remote MDS with nodsh"
18685         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18686                 skip "Need MDS version at least 2.4.52"
18687
18688         echo "==== test 1: verify get lease work"
18689         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18690
18691         echo "==== test 2: verify lease can be broken by upcoming open"
18692         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18693         local PID=$!
18694         sleep 2
18695
18696         $MULTIOP $DIR/$tfile oO_RDWR:c
18697         kill -USR1 $PID && wait $PID || error "break lease error"
18698
18699         echo "==== test 3: verify lease can't be granted if an open already exists"
18700         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18701         local PID=$!
18702         sleep 2
18703
18704         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18705         kill -USR1 $PID && wait $PID || error "open file error"
18706
18707         echo "==== test 4: lease can sustain over recovery"
18708         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18709         PID=$!
18710         sleep 2
18711
18712         fail mds1
18713
18714         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18715
18716         echo "==== test 5: lease broken can't be regained by replay"
18717         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18718         PID=$!
18719         sleep 2
18720
18721         # open file to break lease and then recovery
18722         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18723         fail mds1
18724
18725         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18726
18727         rm -f $DIR/$tfile
18728 }
18729 run_test 208 "Exclusive open"
18730
18731 test_209() {
18732         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18733                 skip_env "must have disp_stripe"
18734
18735         touch $DIR/$tfile
18736         sync; sleep 5; sync;
18737
18738         echo 3 > /proc/sys/vm/drop_caches
18739         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18740                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18741         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18742
18743         # open/close 500 times
18744         for i in $(seq 500); do
18745                 cat $DIR/$tfile
18746         done
18747
18748         echo 3 > /proc/sys/vm/drop_caches
18749         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18750                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18751         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18752
18753         echo "before: $req_before, after: $req_after"
18754         [ $((req_after - req_before)) -ge 300 ] &&
18755                 error "open/close requests are not freed"
18756         return 0
18757 }
18758 run_test 209 "read-only open/close requests should be freed promptly"
18759
18760 test_210() {
18761         local pid
18762
18763         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18764         pid=$!
18765         sleep 1
18766
18767         $LFS getstripe $DIR/$tfile
18768         kill -USR1 $pid
18769         wait $pid || error "multiop failed"
18770
18771         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18772         pid=$!
18773         sleep 1
18774
18775         $LFS getstripe $DIR/$tfile
18776         kill -USR1 $pid
18777         wait $pid || error "multiop failed"
18778 }
18779 run_test 210 "lfs getstripe does not break leases"
18780
18781 test_212() {
18782         size=`date +%s`
18783         size=$((size % 8192 + 1))
18784         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18785         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18786         rm -f $DIR/f212 $DIR/f212.xyz
18787 }
18788 run_test 212 "Sendfile test ============================================"
18789
18790 test_213() {
18791         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18792         cancel_lru_locks osc
18793         lctl set_param fail_loc=0x8000040f
18794         # generate a read lock
18795         cat $DIR/$tfile > /dev/null
18796         # write to the file, it will try to cancel the above read lock.
18797         cat /etc/hosts >> $DIR/$tfile
18798 }
18799 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18800
18801 test_214() { # for bug 20133
18802         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18803         for (( i=0; i < 340; i++ )) ; do
18804                 touch $DIR/$tdir/d214c/a$i
18805         done
18806
18807         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18808         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18809         ls $DIR/d214c || error "ls $DIR/d214c failed"
18810         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18811         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18812 }
18813 run_test 214 "hash-indexed directory test - bug 20133"
18814
18815 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18816 create_lnet_proc_files() {
18817         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18818 }
18819
18820 # counterpart of create_lnet_proc_files
18821 remove_lnet_proc_files() {
18822         rm -f $TMP/lnet_$1.sys
18823 }
18824
18825 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18826 # 3rd arg as regexp for body
18827 check_lnet_proc_stats() {
18828         local l=$(cat "$TMP/lnet_$1" |wc -l)
18829         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18830
18831         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18832 }
18833
18834 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18835 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18836 # optional and can be regexp for 2nd line (lnet.routes case)
18837 check_lnet_proc_entry() {
18838         local blp=2          # blp stands for 'position of 1st line of body'
18839         [ -z "$5" ] || blp=3 # lnet.routes case
18840
18841         local l=$(cat "$TMP/lnet_$1" |wc -l)
18842         # subtracting one from $blp because the body can be empty
18843         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18844
18845         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18846                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18847
18848         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18849                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18850
18851         # bail out if any unexpected line happened
18852         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18853         [ "$?" != 0 ] || error "$2 misformatted"
18854 }
18855
18856 test_215() { # for bugs 18102, 21079, 21517
18857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18858
18859         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18860         local P='[1-9][0-9]*'           # positive numeric
18861         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18862         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18863         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18864         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18865
18866         local L1 # regexp for 1st line
18867         local L2 # regexp for 2nd line (optional)
18868         local BR # regexp for the rest (body)
18869
18870         # lnet.stats should look as 11 space-separated non-negative numerics
18871         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18872         create_lnet_proc_files "stats"
18873         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18874         remove_lnet_proc_files "stats"
18875
18876         # lnet.routes should look like this:
18877         # Routing disabled/enabled
18878         # net hops priority state router
18879         # where net is a string like tcp0, hops > 0, priority >= 0,
18880         # state is up/down,
18881         # router is a string like 192.168.1.1@tcp2
18882         L1="^Routing (disabled|enabled)$"
18883         L2="^net +hops +priority +state +router$"
18884         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18885         create_lnet_proc_files "routes"
18886         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18887         remove_lnet_proc_files "routes"
18888
18889         # lnet.routers should look like this:
18890         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18891         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18892         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18893         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18894         L1="^ref +rtr_ref +alive +router$"
18895         BR="^$P +$P +(up|down) +$NID$"
18896         create_lnet_proc_files "routers"
18897         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18898         remove_lnet_proc_files "routers"
18899
18900         # lnet.peers should look like this:
18901         # nid refs state last max rtr min tx min queue
18902         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18903         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18904         # numeric (0 or >0 or <0), queue >= 0.
18905         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18906         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18907         create_lnet_proc_files "peers"
18908         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18909         remove_lnet_proc_files "peers"
18910
18911         # lnet.buffers  should look like this:
18912         # pages count credits min
18913         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18914         L1="^pages +count +credits +min$"
18915         BR="^ +$N +$N +$I +$I$"
18916         create_lnet_proc_files "buffers"
18917         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18918         remove_lnet_proc_files "buffers"
18919
18920         # lnet.nis should look like this:
18921         # nid status alive refs peer rtr max tx min
18922         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18923         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18924         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18925         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18926         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18927         create_lnet_proc_files "nis"
18928         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18929         remove_lnet_proc_files "nis"
18930
18931         # can we successfully write to lnet.stats?
18932         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18933 }
18934 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18935
18936 test_216() { # bug 20317
18937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18938         remote_ost_nodsh && skip "remote OST with nodsh"
18939
18940         local node
18941         local facets=$(get_facets OST)
18942         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18943
18944         save_lustre_params client "osc.*.contention_seconds" > $p
18945         save_lustre_params $facets \
18946                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18947         save_lustre_params $facets \
18948                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18949         save_lustre_params $facets \
18950                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18951         clear_stats osc.*.osc_stats
18952
18953         # agressive lockless i/o settings
18954         do_nodes $(comma_list $(osts_nodes)) \
18955                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18956                         ldlm.namespaces.filter-*.contended_locks=0 \
18957                         ldlm.namespaces.filter-*.contention_seconds=60"
18958         lctl set_param -n osc.*.contention_seconds=60
18959
18960         $DIRECTIO write $DIR/$tfile 0 10 4096
18961         $CHECKSTAT -s 40960 $DIR/$tfile
18962
18963         # disable lockless i/o
18964         do_nodes $(comma_list $(osts_nodes)) \
18965                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18966                         ldlm.namespaces.filter-*.contended_locks=32 \
18967                         ldlm.namespaces.filter-*.contention_seconds=0"
18968         lctl set_param -n osc.*.contention_seconds=0
18969         clear_stats osc.*.osc_stats
18970
18971         dd if=/dev/zero of=$DIR/$tfile count=0
18972         $CHECKSTAT -s 0 $DIR/$tfile
18973
18974         restore_lustre_params <$p
18975         rm -f $p
18976         rm $DIR/$tfile
18977 }
18978 run_test 216 "check lockless direct write updates file size and kms correctly"
18979
18980 test_217() { # bug 22430
18981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18982
18983         local node
18984         local nid
18985
18986         for node in $(nodes_list); do
18987                 nid=$(host_nids_address $node $NETTYPE)
18988                 if [[ $nid = *-* ]] ; then
18989                         echo "lctl ping $(h2nettype $nid)"
18990                         lctl ping $(h2nettype $nid)
18991                 else
18992                         echo "skipping $node (no hyphen detected)"
18993                 fi
18994         done
18995 }
18996 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18997
18998 test_218() {
18999        # do directio so as not to populate the page cache
19000        log "creating a 10 Mb file"
19001        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19002        log "starting reads"
19003        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19004        log "truncating the file"
19005        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19006        log "killing dd"
19007        kill %+ || true # reads might have finished
19008        echo "wait until dd is finished"
19009        wait
19010        log "removing the temporary file"
19011        rm -rf $DIR/$tfile || error "tmp file removal failed"
19012 }
19013 run_test 218 "parallel read and truncate should not deadlock"
19014
19015 test_219() {
19016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19017
19018         # write one partial page
19019         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19020         # set no grant so vvp_io_commit_write will do sync write
19021         $LCTL set_param fail_loc=0x411
19022         # write a full page at the end of file
19023         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19024
19025         $LCTL set_param fail_loc=0
19026         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19027         $LCTL set_param fail_loc=0x411
19028         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19029
19030         # LU-4201
19031         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19032         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19033 }
19034 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19035
19036 test_220() { #LU-325
19037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19038         remote_ost_nodsh && skip "remote OST with nodsh"
19039         remote_mds_nodsh && skip "remote MDS with nodsh"
19040         remote_mgs_nodsh && skip "remote MGS with nodsh"
19041
19042         local OSTIDX=0
19043
19044         # create on MDT0000 so the last_id and next_id are correct
19045         mkdir_on_mdt0 $DIR/$tdir
19046         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19047         OST=${OST%_UUID}
19048
19049         # on the mdt's osc
19050         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19051         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19052                         osp.$mdtosc_proc1.prealloc_last_id)
19053         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19054                         osp.$mdtosc_proc1.prealloc_next_id)
19055
19056         $LFS df -i
19057
19058         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19059         #define OBD_FAIL_OST_ENOINO              0x229
19060         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19061         create_pool $FSNAME.$TESTNAME || return 1
19062         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19063
19064         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19065
19066         MDSOBJS=$((last_id - next_id))
19067         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19068
19069         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19070         echo "OST still has $count kbytes free"
19071
19072         echo "create $MDSOBJS files @next_id..."
19073         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19074
19075         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19076                         osp.$mdtosc_proc1.prealloc_last_id)
19077         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19078                         osp.$mdtosc_proc1.prealloc_next_id)
19079
19080         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19081         $LFS df -i
19082
19083         echo "cleanup..."
19084
19085         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19086         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19087
19088         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19089                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19090         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19091                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19092         echo "unlink $MDSOBJS files @$next_id..."
19093         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19094 }
19095 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19096
19097 test_221() {
19098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19099
19100         dd if=`which date` of=$MOUNT/date oflag=sync
19101         chmod +x $MOUNT/date
19102
19103         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19104         $LCTL set_param fail_loc=0x80001401
19105
19106         $MOUNT/date > /dev/null
19107         rm -f $MOUNT/date
19108 }
19109 run_test 221 "make sure fault and truncate race to not cause OOM"
19110
19111 test_222a () {
19112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19113
19114         rm -rf $DIR/$tdir
19115         test_mkdir $DIR/$tdir
19116         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19117         createmany -o $DIR/$tdir/$tfile 10
19118         cancel_lru_locks mdc
19119         cancel_lru_locks osc
19120         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19121         $LCTL set_param fail_loc=0x31a
19122         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19123         $LCTL set_param fail_loc=0
19124         rm -r $DIR/$tdir
19125 }
19126 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19127
19128 test_222b () {
19129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19130
19131         rm -rf $DIR/$tdir
19132         test_mkdir $DIR/$tdir
19133         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19134         createmany -o $DIR/$tdir/$tfile 10
19135         cancel_lru_locks mdc
19136         cancel_lru_locks osc
19137         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19138         $LCTL set_param fail_loc=0x31a
19139         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19140         $LCTL set_param fail_loc=0
19141 }
19142 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19143
19144 test_223 () {
19145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19146
19147         rm -rf $DIR/$tdir
19148         test_mkdir $DIR/$tdir
19149         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19150         createmany -o $DIR/$tdir/$tfile 10
19151         cancel_lru_locks mdc
19152         cancel_lru_locks osc
19153         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19154         $LCTL set_param fail_loc=0x31b
19155         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19156         $LCTL set_param fail_loc=0
19157         rm -r $DIR/$tdir
19158 }
19159 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19160
19161 test_224a() { # LU-1039, MRP-303
19162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19163         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19164         $LCTL set_param fail_loc=0x508
19165         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19166         $LCTL set_param fail_loc=0
19167         df $DIR
19168 }
19169 run_test 224a "Don't panic on bulk IO failure"
19170
19171 test_224bd_sub() { # LU-1039, MRP-303
19172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19173         local timeout=$1
19174
19175         shift
19176         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19177
19178         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19179
19180         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19181         cancel_lru_locks osc
19182         set_checksums 0
19183         stack_trap "set_checksums $ORIG_CSUM" EXIT
19184         local at_max_saved=0
19185
19186         # adaptive timeouts may prevent seeing the issue
19187         if at_is_enabled; then
19188                 at_max_saved=$(at_max_get mds)
19189                 at_max_set 0 mds client
19190                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19191         fi
19192
19193         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19194         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19195         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19196
19197         do_facet ost1 $LCTL set_param fail_loc=0
19198         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19199         df $DIR
19200 }
19201
19202 test_224b() {
19203         test_224bd_sub 3 error "dd failed"
19204 }
19205 run_test 224b "Don't panic on bulk IO failure"
19206
19207 test_224c() { # LU-6441
19208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19209         remote_mds_nodsh && skip "remote MDS with nodsh"
19210
19211         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19212         save_writethrough $p
19213         set_cache writethrough on
19214
19215         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19216         local at_max=$($LCTL get_param -n at_max)
19217         local timeout=$($LCTL get_param -n timeout)
19218         local test_at="at_max"
19219         local param_at="$FSNAME.sys.at_max"
19220         local test_timeout="timeout"
19221         local param_timeout="$FSNAME.sys.timeout"
19222
19223         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19224
19225         set_persistent_param_and_check client "$test_at" "$param_at" 0
19226         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19227
19228         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19229         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19230         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19231         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19232         sync
19233         do_facet ost1 "$LCTL set_param fail_loc=0"
19234
19235         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19236         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19237                 $timeout
19238
19239         $LCTL set_param -n $pages_per_rpc
19240         restore_lustre_params < $p
19241         rm -f $p
19242 }
19243 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19244
19245 test_224d() { # LU-11169
19246         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19247 }
19248 run_test 224d "Don't corrupt data on bulk IO timeout"
19249
19250 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19251 test_225a () {
19252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19253         if [ -z ${MDSSURVEY} ]; then
19254                 skip_env "mds-survey not found"
19255         fi
19256         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19257                 skip "Need MDS version at least 2.2.51"
19258
19259         local mds=$(facet_host $SINGLEMDS)
19260         local target=$(do_nodes $mds 'lctl dl' |
19261                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19262
19263         local cmd1="file_count=1000 thrhi=4"
19264         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19265         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19266         local cmd="$cmd1 $cmd2 $cmd3"
19267
19268         rm -f ${TMP}/mds_survey*
19269         echo + $cmd
19270         eval $cmd || error "mds-survey with zero-stripe failed"
19271         cat ${TMP}/mds_survey*
19272         rm -f ${TMP}/mds_survey*
19273 }
19274 run_test 225a "Metadata survey sanity with zero-stripe"
19275
19276 test_225b () {
19277         if [ -z ${MDSSURVEY} ]; then
19278                 skip_env "mds-survey not found"
19279         fi
19280         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19281                 skip "Need MDS version at least 2.2.51"
19282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19283         remote_mds_nodsh && skip "remote MDS with nodsh"
19284         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19285                 skip_env "Need to mount OST to test"
19286         fi
19287
19288         local mds=$(facet_host $SINGLEMDS)
19289         local target=$(do_nodes $mds 'lctl dl' |
19290                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19291
19292         local cmd1="file_count=1000 thrhi=4"
19293         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19294         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19295         local cmd="$cmd1 $cmd2 $cmd3"
19296
19297         rm -f ${TMP}/mds_survey*
19298         echo + $cmd
19299         eval $cmd || error "mds-survey with stripe_count failed"
19300         cat ${TMP}/mds_survey*
19301         rm -f ${TMP}/mds_survey*
19302 }
19303 run_test 225b "Metadata survey sanity with stripe_count = 1"
19304
19305 mcreate_path2fid () {
19306         local mode=$1
19307         local major=$2
19308         local minor=$3
19309         local name=$4
19310         local desc=$5
19311         local path=$DIR/$tdir/$name
19312         local fid
19313         local rc
19314         local fid_path
19315
19316         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19317                 error "cannot create $desc"
19318
19319         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19320         rc=$?
19321         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19322
19323         fid_path=$($LFS fid2path $MOUNT $fid)
19324         rc=$?
19325         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19326
19327         [ "$path" == "$fid_path" ] ||
19328                 error "fid2path returned $fid_path, expected $path"
19329
19330         echo "pass with $path and $fid"
19331 }
19332
19333 test_226a () {
19334         rm -rf $DIR/$tdir
19335         mkdir -p $DIR/$tdir
19336
19337         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19338         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19339         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19340         mcreate_path2fid 0040666 0 0 dir "directory"
19341         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19342         mcreate_path2fid 0100666 0 0 file "regular file"
19343         mcreate_path2fid 0120666 0 0 link "symbolic link"
19344         mcreate_path2fid 0140666 0 0 sock "socket"
19345 }
19346 run_test 226a "call path2fid and fid2path on files of all type"
19347
19348 test_226b () {
19349         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19350
19351         local MDTIDX=1
19352
19353         rm -rf $DIR/$tdir
19354         mkdir -p $DIR/$tdir
19355         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19356                 error "create remote directory failed"
19357         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19358         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19359                                 "character special file (null)"
19360         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19361                                 "character special file (no device)"
19362         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19363         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19364                                 "block special file (loop)"
19365         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19366         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19367         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19368 }
19369 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19370
19371 test_226c () {
19372         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19373         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19374                 skip "Need MDS version at least 2.13.55"
19375
19376         local submnt=/mnt/submnt
19377         local srcfile=/etc/passwd
19378         local dstfile=$submnt/passwd
19379         local path
19380         local fid
19381
19382         rm -rf $DIR/$tdir
19383         rm -rf $submnt
19384         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19385                 error "create remote directory failed"
19386         mkdir -p $submnt || error "create $submnt failed"
19387         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19388                 error "mount $submnt failed"
19389         stack_trap "umount $submnt" EXIT
19390
19391         cp $srcfile $dstfile
19392         fid=$($LFS path2fid $dstfile)
19393         path=$($LFS fid2path $submnt "$fid")
19394         [ "$path" = "$dstfile" ] ||
19395                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19396 }
19397 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19398
19399 # LU-1299 Executing or running ldd on a truncated executable does not
19400 # cause an out-of-memory condition.
19401 test_227() {
19402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19403         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19404
19405         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19406         chmod +x $MOUNT/date
19407
19408         $MOUNT/date > /dev/null
19409         ldd $MOUNT/date > /dev/null
19410         rm -f $MOUNT/date
19411 }
19412 run_test 227 "running truncated executable does not cause OOM"
19413
19414 # LU-1512 try to reuse idle OI blocks
19415 test_228a() {
19416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19417         remote_mds_nodsh && skip "remote MDS with nodsh"
19418         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19419
19420         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19421         local myDIR=$DIR/$tdir
19422
19423         mkdir -p $myDIR
19424         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19425         $LCTL set_param fail_loc=0x80001002
19426         createmany -o $myDIR/t- 10000
19427         $LCTL set_param fail_loc=0
19428         # The guard is current the largest FID holder
19429         touch $myDIR/guard
19430         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19431                     tr -d '[')
19432         local IDX=$(($SEQ % 64))
19433
19434         do_facet $SINGLEMDS sync
19435         # Make sure journal flushed.
19436         sleep 6
19437         local blk1=$(do_facet $SINGLEMDS \
19438                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19439                      grep Blockcount | awk '{print $4}')
19440
19441         # Remove old files, some OI blocks will become idle.
19442         unlinkmany $myDIR/t- 10000
19443         # Create new files, idle OI blocks should be reused.
19444         createmany -o $myDIR/t- 2000
19445         do_facet $SINGLEMDS sync
19446         # Make sure journal flushed.
19447         sleep 6
19448         local blk2=$(do_facet $SINGLEMDS \
19449                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19450                      grep Blockcount | awk '{print $4}')
19451
19452         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19453 }
19454 run_test 228a "try to reuse idle OI blocks"
19455
19456 test_228b() {
19457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19458         remote_mds_nodsh && skip "remote MDS with nodsh"
19459         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19460
19461         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19462         local myDIR=$DIR/$tdir
19463
19464         mkdir -p $myDIR
19465         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19466         $LCTL set_param fail_loc=0x80001002
19467         createmany -o $myDIR/t- 10000
19468         $LCTL set_param fail_loc=0
19469         # The guard is current the largest FID holder
19470         touch $myDIR/guard
19471         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19472                     tr -d '[')
19473         local IDX=$(($SEQ % 64))
19474
19475         do_facet $SINGLEMDS sync
19476         # Make sure journal flushed.
19477         sleep 6
19478         local blk1=$(do_facet $SINGLEMDS \
19479                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19480                      grep Blockcount | awk '{print $4}')
19481
19482         # Remove old files, some OI blocks will become idle.
19483         unlinkmany $myDIR/t- 10000
19484
19485         # stop the MDT
19486         stop $SINGLEMDS || error "Fail to stop MDT."
19487         # remount the MDT
19488         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
19489                 error "Fail to start MDT."
19490
19491         df $MOUNT || error "Fail to df."
19492         # Create new files, idle OI blocks should be reused.
19493         createmany -o $myDIR/t- 2000
19494         do_facet $SINGLEMDS sync
19495         # Make sure journal flushed.
19496         sleep 6
19497         local blk2=$(do_facet $SINGLEMDS \
19498                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19499                      grep Blockcount | awk '{print $4}')
19500
19501         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19502 }
19503 run_test 228b "idle OI blocks can be reused after MDT restart"
19504
19505 #LU-1881
19506 test_228c() {
19507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19508         remote_mds_nodsh && skip "remote MDS with nodsh"
19509         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19510
19511         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19512         local myDIR=$DIR/$tdir
19513
19514         mkdir -p $myDIR
19515         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19516         $LCTL set_param fail_loc=0x80001002
19517         # 20000 files can guarantee there are index nodes in the OI file
19518         createmany -o $myDIR/t- 20000
19519         $LCTL set_param fail_loc=0
19520         # The guard is current the largest FID holder
19521         touch $myDIR/guard
19522         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19523                     tr -d '[')
19524         local IDX=$(($SEQ % 64))
19525
19526         do_facet $SINGLEMDS sync
19527         # Make sure journal flushed.
19528         sleep 6
19529         local blk1=$(do_facet $SINGLEMDS \
19530                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19531                      grep Blockcount | awk '{print $4}')
19532
19533         # Remove old files, some OI blocks will become idle.
19534         unlinkmany $myDIR/t- 20000
19535         rm -f $myDIR/guard
19536         # The OI file should become empty now
19537
19538         # Create new files, idle OI blocks should be reused.
19539         createmany -o $myDIR/t- 2000
19540         do_facet $SINGLEMDS sync
19541         # Make sure journal flushed.
19542         sleep 6
19543         local blk2=$(do_facet $SINGLEMDS \
19544                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19545                      grep Blockcount | awk '{print $4}')
19546
19547         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19548 }
19549 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19550
19551 test_229() { # LU-2482, LU-3448
19552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19553         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19554         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19555                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19556
19557         rm -f $DIR/$tfile
19558
19559         # Create a file with a released layout and stripe count 2.
19560         $MULTIOP $DIR/$tfile H2c ||
19561                 error "failed to create file with released layout"
19562
19563         $LFS getstripe -v $DIR/$tfile
19564
19565         local pattern=$($LFS getstripe -L $DIR/$tfile)
19566         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19567
19568         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19569                 error "getstripe"
19570         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19571         stat $DIR/$tfile || error "failed to stat released file"
19572
19573         chown $RUNAS_ID $DIR/$tfile ||
19574                 error "chown $RUNAS_ID $DIR/$tfile failed"
19575
19576         chgrp $RUNAS_ID $DIR/$tfile ||
19577                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19578
19579         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19580         rm $DIR/$tfile || error "failed to remove released file"
19581 }
19582 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19583
19584 test_230a() {
19585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19586         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19587         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19588                 skip "Need MDS version at least 2.11.52"
19589
19590         local MDTIDX=1
19591
19592         test_mkdir $DIR/$tdir
19593         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19594         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19595         [ $mdt_idx -ne 0 ] &&
19596                 error "create local directory on wrong MDT $mdt_idx"
19597
19598         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19599                         error "create remote directory failed"
19600         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19601         [ $mdt_idx -ne $MDTIDX ] &&
19602                 error "create remote directory on wrong MDT $mdt_idx"
19603
19604         createmany -o $DIR/$tdir/test_230/t- 10 ||
19605                 error "create files on remote directory failed"
19606         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19607         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19608         rm -r $DIR/$tdir || error "unlink remote directory failed"
19609 }
19610 run_test 230a "Create remote directory and files under the remote directory"
19611
19612 test_230b() {
19613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19614         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19615         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19616                 skip "Need MDS version at least 2.11.52"
19617
19618         local MDTIDX=1
19619         local mdt_index
19620         local i
19621         local file
19622         local pid
19623         local stripe_count
19624         local migrate_dir=$DIR/$tdir/migrate_dir
19625         local other_dir=$DIR/$tdir/other_dir
19626
19627         test_mkdir $DIR/$tdir
19628         test_mkdir -i0 -c1 $migrate_dir
19629         test_mkdir -i0 -c1 $other_dir
19630         for ((i=0; i<10; i++)); do
19631                 mkdir -p $migrate_dir/dir_${i}
19632                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19633                         error "create files under remote dir failed $i"
19634         done
19635
19636         cp /etc/passwd $migrate_dir/$tfile
19637         cp /etc/passwd $other_dir/$tfile
19638         chattr +SAD $migrate_dir
19639         chattr +SAD $migrate_dir/$tfile
19640
19641         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19642         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19643         local old_dir_mode=$(stat -c%f $migrate_dir)
19644         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19645
19646         mkdir -p $migrate_dir/dir_default_stripe2
19647         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19648         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19649
19650         mkdir -p $other_dir
19651         ln $migrate_dir/$tfile $other_dir/luna
19652         ln $migrate_dir/$tfile $migrate_dir/sofia
19653         ln $other_dir/$tfile $migrate_dir/david
19654         ln -s $migrate_dir/$tfile $other_dir/zachary
19655         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19656         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19657
19658         local len
19659         local lnktgt
19660
19661         # inline symlink
19662         for len in 58 59 60; do
19663                 lnktgt=$(str_repeat 'l' $len)
19664                 touch $migrate_dir/$lnktgt
19665                 ln -s $lnktgt $migrate_dir/${len}char_ln
19666         done
19667
19668         # PATH_MAX
19669         for len in 4094 4095; do
19670                 lnktgt=$(str_repeat 'l' $len)
19671                 ln -s $lnktgt $migrate_dir/${len}char_ln
19672         done
19673
19674         # NAME_MAX
19675         for len in 254 255; do
19676                 touch $migrate_dir/$(str_repeat 'l' $len)
19677         done
19678
19679         $LFS migrate -m $MDTIDX $migrate_dir ||
19680                 error "fails on migrating remote dir to MDT1"
19681
19682         echo "migratate to MDT1, then checking.."
19683         for ((i = 0; i < 10; i++)); do
19684                 for file in $(find $migrate_dir/dir_${i}); do
19685                         mdt_index=$($LFS getstripe -m $file)
19686                         # broken symlink getstripe will fail
19687                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19688                                 error "$file is not on MDT${MDTIDX}"
19689                 done
19690         done
19691
19692         # the multiple link file should still in MDT0
19693         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19694         [ $mdt_index == 0 ] ||
19695                 error "$file is not on MDT${MDTIDX}"
19696
19697         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19698         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19699                 error " expect $old_dir_flag get $new_dir_flag"
19700
19701         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19702         [ "$old_file_flag" = "$new_file_flag" ] ||
19703                 error " expect $old_file_flag get $new_file_flag"
19704
19705         local new_dir_mode=$(stat -c%f $migrate_dir)
19706         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19707                 error "expect mode $old_dir_mode get $new_dir_mode"
19708
19709         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19710         [ "$old_file_mode" = "$new_file_mode" ] ||
19711                 error "expect mode $old_file_mode get $new_file_mode"
19712
19713         diff /etc/passwd $migrate_dir/$tfile ||
19714                 error "$tfile different after migration"
19715
19716         diff /etc/passwd $other_dir/luna ||
19717                 error "luna different after migration"
19718
19719         diff /etc/passwd $migrate_dir/sofia ||
19720                 error "sofia different after migration"
19721
19722         diff /etc/passwd $migrate_dir/david ||
19723                 error "david different after migration"
19724
19725         diff /etc/passwd $other_dir/zachary ||
19726                 error "zachary different after migration"
19727
19728         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19729                 error "${tfile}_ln different after migration"
19730
19731         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19732                 error "${tfile}_ln_other different after migration"
19733
19734         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19735         [ $stripe_count = 2 ] ||
19736                 error "dir strpe_count $d != 2 after migration."
19737
19738         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19739         [ $stripe_count = 2 ] ||
19740                 error "file strpe_count $d != 2 after migration."
19741
19742         #migrate back to MDT0
19743         MDTIDX=0
19744
19745         $LFS migrate -m $MDTIDX $migrate_dir ||
19746                 error "fails on migrating remote dir to MDT0"
19747
19748         echo "migrate back to MDT0, checking.."
19749         for file in $(find $migrate_dir); do
19750                 mdt_index=$($LFS getstripe -m $file)
19751                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19752                         error "$file is not on MDT${MDTIDX}"
19753         done
19754
19755         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19756         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19757                 error " expect $old_dir_flag get $new_dir_flag"
19758
19759         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19760         [ "$old_file_flag" = "$new_file_flag" ] ||
19761                 error " expect $old_file_flag get $new_file_flag"
19762
19763         local new_dir_mode=$(stat -c%f $migrate_dir)
19764         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19765                 error "expect mode $old_dir_mode get $new_dir_mode"
19766
19767         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19768         [ "$old_file_mode" = "$new_file_mode" ] ||
19769                 error "expect mode $old_file_mode get $new_file_mode"
19770
19771         diff /etc/passwd ${migrate_dir}/$tfile ||
19772                 error "$tfile different after migration"
19773
19774         diff /etc/passwd ${other_dir}/luna ||
19775                 error "luna different after migration"
19776
19777         diff /etc/passwd ${migrate_dir}/sofia ||
19778                 error "sofia different after migration"
19779
19780         diff /etc/passwd ${other_dir}/zachary ||
19781                 error "zachary different after migration"
19782
19783         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19784                 error "${tfile}_ln different after migration"
19785
19786         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19787                 error "${tfile}_ln_other different after migration"
19788
19789         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19790         [ $stripe_count = 2 ] ||
19791                 error "dir strpe_count $d != 2 after migration."
19792
19793         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19794         [ $stripe_count = 2 ] ||
19795                 error "file strpe_count $d != 2 after migration."
19796
19797         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19798 }
19799 run_test 230b "migrate directory"
19800
19801 test_230c() {
19802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19803         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19804         remote_mds_nodsh && skip "remote MDS with nodsh"
19805         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19806                 skip "Need MDS version at least 2.11.52"
19807
19808         local MDTIDX=1
19809         local total=3
19810         local mdt_index
19811         local file
19812         local migrate_dir=$DIR/$tdir/migrate_dir
19813
19814         #If migrating directory fails in the middle, all entries of
19815         #the directory is still accessiable.
19816         test_mkdir $DIR/$tdir
19817         test_mkdir -i0 -c1 $migrate_dir
19818         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19819         stat $migrate_dir
19820         createmany -o $migrate_dir/f $total ||
19821                 error "create files under ${migrate_dir} failed"
19822
19823         # fail after migrating top dir, and this will fail only once, so the
19824         # first sub file migration will fail (currently f3), others succeed.
19825         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19826         do_facet mds1 lctl set_param fail_loc=0x1801
19827         local t=$(ls $migrate_dir | wc -l)
19828         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19829                 error "migrate should fail"
19830         local u=$(ls $migrate_dir | wc -l)
19831         [ "$u" == "$t" ] || error "$u != $t during migration"
19832
19833         # add new dir/file should succeed
19834         mkdir $migrate_dir/dir ||
19835                 error "mkdir failed under migrating directory"
19836         touch $migrate_dir/file ||
19837                 error "create file failed under migrating directory"
19838
19839         # add file with existing name should fail
19840         for file in $migrate_dir/f*; do
19841                 stat $file > /dev/null || error "stat $file failed"
19842                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19843                         error "open(O_CREAT|O_EXCL) $file should fail"
19844                 $MULTIOP $file m && error "create $file should fail"
19845                 touch $DIR/$tdir/remote_dir/$tfile ||
19846                         error "touch $tfile failed"
19847                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19848                         error "link $file should fail"
19849                 mdt_index=$($LFS getstripe -m $file)
19850                 if [ $mdt_index == 0 ]; then
19851                         # file failed to migrate is not allowed to rename to
19852                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19853                                 error "rename to $file should fail"
19854                 else
19855                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19856                                 error "rename to $file failed"
19857                 fi
19858                 echo hello >> $file || error "write $file failed"
19859         done
19860
19861         # resume migration with different options should fail
19862         $LFS migrate -m 0 $migrate_dir &&
19863                 error "migrate -m 0 $migrate_dir should fail"
19864
19865         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19866                 error "migrate -c 2 $migrate_dir should fail"
19867
19868         # resume migration should succeed
19869         $LFS migrate -m $MDTIDX $migrate_dir ||
19870                 error "migrate $migrate_dir failed"
19871
19872         echo "Finish migration, then checking.."
19873         for file in $(find $migrate_dir); do
19874                 mdt_index=$($LFS getstripe -m $file)
19875                 [ $mdt_index == $MDTIDX ] ||
19876                         error "$file is not on MDT${MDTIDX}"
19877         done
19878
19879         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19880 }
19881 run_test 230c "check directory accessiblity if migration failed"
19882
19883 test_230d() {
19884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19885         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19886         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19887                 skip "Need MDS version at least 2.11.52"
19888         # LU-11235
19889         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19890
19891         local migrate_dir=$DIR/$tdir/migrate_dir
19892         local old_index
19893         local new_index
19894         local old_count
19895         local new_count
19896         local new_hash
19897         local mdt_index
19898         local i
19899         local j
19900
19901         old_index=$((RANDOM % MDSCOUNT))
19902         old_count=$((MDSCOUNT - old_index))
19903         new_index=$((RANDOM % MDSCOUNT))
19904         new_count=$((MDSCOUNT - new_index))
19905         new_hash=1 # for all_char
19906
19907         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19908         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19909
19910         test_mkdir $DIR/$tdir
19911         test_mkdir -i $old_index -c $old_count $migrate_dir
19912
19913         for ((i=0; i<100; i++)); do
19914                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19915                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19916                         error "create files under remote dir failed $i"
19917         done
19918
19919         echo -n "Migrate from MDT$old_index "
19920         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19921         echo -n "to MDT$new_index"
19922         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19923         echo
19924
19925         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19926         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19927                 error "migrate remote dir error"
19928
19929         echo "Finish migration, then checking.."
19930         for file in $(find $migrate_dir -maxdepth 1); do
19931                 mdt_index=$($LFS getstripe -m $file)
19932                 if [ $mdt_index -lt $new_index ] ||
19933                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19934                         error "$file is on MDT$mdt_index"
19935                 fi
19936         done
19937
19938         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19939 }
19940 run_test 230d "check migrate big directory"
19941
19942 test_230e() {
19943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19944         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19945         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19946                 skip "Need MDS version at least 2.11.52"
19947
19948         local i
19949         local j
19950         local a_fid
19951         local b_fid
19952
19953         mkdir_on_mdt0 $DIR/$tdir
19954         mkdir $DIR/$tdir/migrate_dir
19955         mkdir $DIR/$tdir/other_dir
19956         touch $DIR/$tdir/migrate_dir/a
19957         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19958         ls $DIR/$tdir/other_dir
19959
19960         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19961                 error "migrate dir fails"
19962
19963         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19964         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19965
19966         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19967         [ $mdt_index == 0 ] || error "a is not on MDT0"
19968
19969         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19970                 error "migrate dir fails"
19971
19972         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19973         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19974
19975         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19976         [ $mdt_index == 1 ] || error "a is not on MDT1"
19977
19978         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19979         [ $mdt_index == 1 ] || error "b is not on MDT1"
19980
19981         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19982         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19983
19984         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19985
19986         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19987 }
19988 run_test 230e "migrate mulitple local link files"
19989
19990 test_230f() {
19991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19992         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19993         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19994                 skip "Need MDS version at least 2.11.52"
19995
19996         local a_fid
19997         local ln_fid
19998
19999         mkdir -p $DIR/$tdir
20000         mkdir $DIR/$tdir/migrate_dir
20001         $LFS mkdir -i1 $DIR/$tdir/other_dir
20002         touch $DIR/$tdir/migrate_dir/a
20003         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20004         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20005         ls $DIR/$tdir/other_dir
20006
20007         # a should be migrated to MDT1, since no other links on MDT0
20008         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20009                 error "#1 migrate dir fails"
20010         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20011         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20012         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20013         [ $mdt_index == 1 ] || error "a is not on MDT1"
20014
20015         # a should stay on MDT1, because it is a mulitple link file
20016         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20017                 error "#2 migrate dir fails"
20018         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20019         [ $mdt_index == 1 ] || error "a is not on MDT1"
20020
20021         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20022                 error "#3 migrate dir fails"
20023
20024         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20025         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20026         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20027
20028         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20029         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20030
20031         # a should be migrated to MDT0, since no other links on MDT1
20032         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20033                 error "#4 migrate dir fails"
20034         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20035         [ $mdt_index == 0 ] || error "a is not on MDT0"
20036
20037         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20038 }
20039 run_test 230f "migrate mulitple remote link files"
20040
20041 test_230g() {
20042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20043         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20044         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20045                 skip "Need MDS version at least 2.11.52"
20046
20047         mkdir -p $DIR/$tdir/migrate_dir
20048
20049         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20050                 error "migrating dir to non-exist MDT succeeds"
20051         true
20052 }
20053 run_test 230g "migrate dir to non-exist MDT"
20054
20055 test_230h() {
20056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20057         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20058         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20059                 skip "Need MDS version at least 2.11.52"
20060
20061         local mdt_index
20062
20063         mkdir -p $DIR/$tdir/migrate_dir
20064
20065         $LFS migrate -m1 $DIR &&
20066                 error "migrating mountpoint1 should fail"
20067
20068         $LFS migrate -m1 $DIR/$tdir/.. &&
20069                 error "migrating mountpoint2 should fail"
20070
20071         # same as mv
20072         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20073                 error "migrating $tdir/migrate_dir/.. should fail"
20074
20075         true
20076 }
20077 run_test 230h "migrate .. and root"
20078
20079 test_230i() {
20080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20081         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20082         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20083                 skip "Need MDS version at least 2.11.52"
20084
20085         mkdir -p $DIR/$tdir/migrate_dir
20086
20087         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20088                 error "migration fails with a tailing slash"
20089
20090         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20091                 error "migration fails with two tailing slashes"
20092 }
20093 run_test 230i "lfs migrate -m tolerates trailing slashes"
20094
20095 test_230j() {
20096         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20097         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20098                 skip "Need MDS version at least 2.11.52"
20099
20100         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20101         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20102                 error "create $tfile failed"
20103         cat /etc/passwd > $DIR/$tdir/$tfile
20104
20105         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20106
20107         cmp /etc/passwd $DIR/$tdir/$tfile ||
20108                 error "DoM file mismatch after migration"
20109 }
20110 run_test 230j "DoM file data not changed after dir migration"
20111
20112 test_230k() {
20113         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20114         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20115                 skip "Need MDS version at least 2.11.56"
20116
20117         local total=20
20118         local files_on_starting_mdt=0
20119
20120         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20121         $LFS getdirstripe $DIR/$tdir
20122         for i in $(seq $total); do
20123                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20124                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20125                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20126         done
20127
20128         echo "$files_on_starting_mdt files on MDT0"
20129
20130         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20131         $LFS getdirstripe $DIR/$tdir
20132
20133         files_on_starting_mdt=0
20134         for i in $(seq $total); do
20135                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20136                         error "file $tfile.$i mismatch after migration"
20137                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20138                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20139         done
20140
20141         echo "$files_on_starting_mdt files on MDT1 after migration"
20142         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20143
20144         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20145         $LFS getdirstripe $DIR/$tdir
20146
20147         files_on_starting_mdt=0
20148         for i in $(seq $total); do
20149                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20150                         error "file $tfile.$i mismatch after 2nd migration"
20151                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20152                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20153         done
20154
20155         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20156         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20157
20158         true
20159 }
20160 run_test 230k "file data not changed after dir migration"
20161
20162 test_230l() {
20163         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20164         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20165                 skip "Need MDS version at least 2.11.56"
20166
20167         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20168         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20169                 error "create files under remote dir failed $i"
20170         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20171 }
20172 run_test 230l "readdir between MDTs won't crash"
20173
20174 test_230m() {
20175         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20176         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20177                 skip "Need MDS version at least 2.11.56"
20178
20179         local MDTIDX=1
20180         local mig_dir=$DIR/$tdir/migrate_dir
20181         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20182         local shortstr="b"
20183         local val
20184
20185         echo "Creating files and dirs with xattrs"
20186         test_mkdir $DIR/$tdir
20187         test_mkdir -i0 -c1 $mig_dir
20188         mkdir $mig_dir/dir
20189         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20190                 error "cannot set xattr attr1 on dir"
20191         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20192                 error "cannot set xattr attr2 on dir"
20193         touch $mig_dir/dir/f0
20194         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20195                 error "cannot set xattr attr1 on file"
20196         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20197                 error "cannot set xattr attr2 on file"
20198         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20199         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20200         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20201         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20202         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20203         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20204         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20205         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20206         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20207
20208         echo "Migrating to MDT1"
20209         $LFS migrate -m $MDTIDX $mig_dir ||
20210                 error "fails on migrating dir to MDT1"
20211
20212         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20213         echo "Checking xattrs"
20214         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20215         [ "$val" = $longstr ] ||
20216                 error "expecting xattr1 $longstr on dir, found $val"
20217         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20218         [ "$val" = $shortstr ] ||
20219                 error "expecting xattr2 $shortstr on dir, found $val"
20220         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20221         [ "$val" = $longstr ] ||
20222                 error "expecting xattr1 $longstr on file, found $val"
20223         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20224         [ "$val" = $shortstr ] ||
20225                 error "expecting xattr2 $shortstr on file, found $val"
20226 }
20227 run_test 230m "xattrs not changed after dir migration"
20228
20229 test_230n() {
20230         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20231         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20232                 skip "Need MDS version at least 2.13.53"
20233
20234         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20235         cat /etc/hosts > $DIR/$tdir/$tfile
20236         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20237         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20238
20239         cmp /etc/hosts $DIR/$tdir/$tfile ||
20240                 error "File data mismatch after migration"
20241 }
20242 run_test 230n "Dir migration with mirrored file"
20243
20244 test_230o() {
20245         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20246         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20247                 skip "Need MDS version at least 2.13.52"
20248
20249         local mdts=$(comma_list $(mdts_nodes))
20250         local timeout=100
20251         local restripe_status
20252         local delta
20253         local i
20254
20255         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20256
20257         # in case "crush" hash type is not set
20258         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20259
20260         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20261                            mdt.*MDT0000.enable_dir_restripe)
20262         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20263         stack_trap "do_nodes $mdts $LCTL set_param \
20264                     mdt.*.enable_dir_restripe=$restripe_status"
20265
20266         mkdir $DIR/$tdir
20267         createmany -m $DIR/$tdir/f 100 ||
20268                 error "create files under remote dir failed $i"
20269         createmany -d $DIR/$tdir/d 100 ||
20270                 error "create dirs under remote dir failed $i"
20271
20272         for i in $(seq 2 $MDSCOUNT); do
20273                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20274                 $LFS setdirstripe -c $i $DIR/$tdir ||
20275                         error "split -c $i $tdir failed"
20276                 wait_update $HOSTNAME \
20277                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20278                         error "dir split not finished"
20279                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20280                         awk '/migrate/ {sum += $2} END { print sum }')
20281                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20282                 # delta is around total_files/stripe_count
20283                 (( $delta < 200 / (i - 1) + 4 )) ||
20284                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20285         done
20286 }
20287 run_test 230o "dir split"
20288
20289 test_230p() {
20290         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20291         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20292                 skip "Need MDS version at least 2.13.52"
20293
20294         local mdts=$(comma_list $(mdts_nodes))
20295         local timeout=100
20296         local restripe_status
20297         local delta
20298         local c
20299
20300         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20301
20302         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20303
20304         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20305                            mdt.*MDT0000.enable_dir_restripe)
20306         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20307         stack_trap "do_nodes $mdts $LCTL set_param \
20308                     mdt.*.enable_dir_restripe=$restripe_status"
20309
20310         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20311         createmany -m $DIR/$tdir/f 100 ||
20312                 error "create files under remote dir failed"
20313         createmany -d $DIR/$tdir/d 100 ||
20314                 error "create dirs under remote dir failed"
20315
20316         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20317                 local mdt_hash="crush"
20318
20319                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20320                 $LFS setdirstripe -c $c $DIR/$tdir ||
20321                         error "split -c $c $tdir failed"
20322                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20323                         mdt_hash="$mdt_hash,fixed"
20324                 elif [ $c -eq 1 ]; then
20325                         mdt_hash="none"
20326                 fi
20327                 wait_update $HOSTNAME \
20328                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20329                         error "dir merge not finished"
20330                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20331                         awk '/migrate/ {sum += $2} END { print sum }')
20332                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20333                 # delta is around total_files/stripe_count
20334                 (( delta < 200 / c + 4 )) ||
20335                         error "$delta files migrated >= $((200 / c + 4))"
20336         done
20337 }
20338 run_test 230p "dir merge"
20339
20340 test_230q() {
20341         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20342         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20343                 skip "Need MDS version at least 2.13.52"
20344
20345         local mdts=$(comma_list $(mdts_nodes))
20346         local saved_threshold=$(do_facet mds1 \
20347                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20348         local saved_delta=$(do_facet mds1 \
20349                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20350         local threshold=100
20351         local delta=2
20352         local total=0
20353         local stripe_count=0
20354         local stripe_index
20355         local nr_files
20356         local create
20357
20358         # test with fewer files on ZFS
20359         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20360
20361         stack_trap "do_nodes $mdts $LCTL set_param \
20362                     mdt.*.dir_split_count=$saved_threshold"
20363         stack_trap "do_nodes $mdts $LCTL set_param \
20364                     mdt.*.dir_split_delta=$saved_delta"
20365         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20366         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20367         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20368         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20369         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20370         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20371
20372         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20373         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20374
20375         create=$((threshold * 3 / 2))
20376         while [ $stripe_count -lt $MDSCOUNT ]; do
20377                 createmany -m $DIR/$tdir/f $total $create ||
20378                         error "create sub files failed"
20379                 stat $DIR/$tdir > /dev/null
20380                 total=$((total + create))
20381                 stripe_count=$((stripe_count + delta))
20382                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20383
20384                 wait_update $HOSTNAME \
20385                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20386                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20387
20388                 wait_update $HOSTNAME \
20389                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20390                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20391
20392                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20393                 echo "$nr_files/$total files on MDT$stripe_index after split"
20394                 # allow 10% margin of imbalance with crush hash
20395                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20396                         error "$nr_files files on MDT$stripe_index after split"
20397
20398                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20399                 [ $nr_files -eq $total ] ||
20400                         error "total sub files $nr_files != $total"
20401         done
20402
20403         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20404
20405         echo "fixed layout directory won't auto split"
20406         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20407         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20408                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20409         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20410                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20411 }
20412 run_test 230q "dir auto split"
20413
20414 test_230r() {
20415         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20416         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20417         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20418                 skip "Need MDS version at least 2.13.54"
20419
20420         # maximum amount of local locks:
20421         # parent striped dir - 2 locks
20422         # new stripe in parent to migrate to - 1 lock
20423         # source and target - 2 locks
20424         # Total 5 locks for regular file
20425         mkdir -p $DIR/$tdir
20426         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20427         touch $DIR/$tdir/dir1/eee
20428
20429         # create 4 hardlink for 4 more locks
20430         # Total: 9 locks > RS_MAX_LOCKS (8)
20431         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20432         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20433         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20434         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20435         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20436         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20437         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20438         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20439
20440         cancel_lru_locks mdc
20441
20442         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20443                 error "migrate dir fails"
20444
20445         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20446 }
20447 run_test 230r "migrate with too many local locks"
20448
20449 test_230s() {
20450         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
20451                 skip "Need MDS version at least 2.13.57"
20452
20453         local mdts=$(comma_list $(mdts_nodes))
20454         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20455                                 mdt.*MDT0000.enable_dir_restripe)
20456
20457         stack_trap "do_nodes $mdts $LCTL set_param \
20458                     mdt.*.enable_dir_restripe=$restripe_status"
20459
20460         local st
20461         for st in 0 1; do
20462                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20463                 test_mkdir $DIR/$tdir
20464                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20465                         error "$LFS mkdir doesn't return -EEXIST if target exists"
20466                 rmdir $DIR/$tdir
20467         done
20468 }
20469 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20470
20471 test_230t()
20472 {
20473         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20474         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20475                 skip "Need MDS version at least 2.14.50"
20476
20477         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20478         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20479         $LFS project -p 1 -s $DIR/$tdir ||
20480                 error "set $tdir project id failed"
20481         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20482                 error "set subdir project id failed"
20483         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20484 }
20485 run_test 230t "migrate directory with project ID set"
20486
20487 test_230u()
20488 {
20489         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20490         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20491                 skip "Need MDS version at least 2.14.53"
20492
20493         local count
20494
20495         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20496         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20497         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20498         for i in $(seq 0 $((MDSCOUNT - 1))); do
20499                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20500                 echo "$count dirs migrated to MDT$i"
20501         done
20502         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20503         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20504 }
20505 run_test 230u "migrate directory by QOS"
20506
20507 test_230v()
20508 {
20509         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20510         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20511                 skip "Need MDS version at least 2.14.53"
20512
20513         local count
20514
20515         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20516         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20517         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20518         for i in $(seq 0 $((MDSCOUNT - 1))); do
20519                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20520                 echo "$count subdirs migrated to MDT$i"
20521                 (( i == 3 )) && (( count > 0 )) &&
20522                         error "subdir shouldn't be migrated to MDT3"
20523         done
20524         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20525         (( count == 3 )) || error "dirs migrated to $count MDTs"
20526 }
20527 run_test 230v "subdir migrated to the MDT where its parent is located"
20528
20529 test_230w() {
20530         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20531         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20532                 skip "Need MDS version at least 2.14.53"
20533
20534         mkdir -p $DIR/$tdir/sub || error "mkdir failed"
20535
20536         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
20537                 error "migrate failed"
20538
20539         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
20540                 error "$tdir stripe count mismatch"
20541
20542         (( $($LFS getdirstripe -c $DIR/$tdir/sub) == 0 )) ||
20543                 error "$tdir/sub is striped"
20544 }
20545 run_test 230w "non-recursive mode dir migration"
20546
20547 test_231a()
20548 {
20549         # For simplicity this test assumes that max_pages_per_rpc
20550         # is the same across all OSCs
20551         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20552         local bulk_size=$((max_pages * PAGE_SIZE))
20553         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20554                                        head -n 1)
20555
20556         mkdir -p $DIR/$tdir
20557         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20558                 error "failed to set stripe with -S ${brw_size}M option"
20559
20560         # clear the OSC stats
20561         $LCTL set_param osc.*.stats=0 &>/dev/null
20562         stop_writeback
20563
20564         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20565         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20566                 oflag=direct &>/dev/null || error "dd failed"
20567
20568         sync; sleep 1; sync # just to be safe
20569         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20570         if [ x$nrpcs != "x1" ]; then
20571                 $LCTL get_param osc.*.stats
20572                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20573         fi
20574
20575         start_writeback
20576         # Drop the OSC cache, otherwise we will read from it
20577         cancel_lru_locks osc
20578
20579         # clear the OSC stats
20580         $LCTL set_param osc.*.stats=0 &>/dev/null
20581
20582         # Client reads $bulk_size.
20583         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20584                 iflag=direct &>/dev/null || error "dd failed"
20585
20586         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20587         if [ x$nrpcs != "x1" ]; then
20588                 $LCTL get_param osc.*.stats
20589                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20590         fi
20591 }
20592 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20593
20594 test_231b() {
20595         mkdir -p $DIR/$tdir
20596         local i
20597         for i in {0..1023}; do
20598                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20599                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20600                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20601         done
20602         sync
20603 }
20604 run_test 231b "must not assert on fully utilized OST request buffer"
20605
20606 test_232a() {
20607         mkdir -p $DIR/$tdir
20608         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20609
20610         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20611         do_facet ost1 $LCTL set_param fail_loc=0x31c
20612
20613         # ignore dd failure
20614         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20615
20616         do_facet ost1 $LCTL set_param fail_loc=0
20617         umount_client $MOUNT || error "umount failed"
20618         mount_client $MOUNT || error "mount failed"
20619         stop ost1 || error "cannot stop ost1"
20620         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20621 }
20622 run_test 232a "failed lock should not block umount"
20623
20624 test_232b() {
20625         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20626                 skip "Need MDS version at least 2.10.58"
20627
20628         mkdir -p $DIR/$tdir
20629         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20630         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20631         sync
20632         cancel_lru_locks osc
20633
20634         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20635         do_facet ost1 $LCTL set_param fail_loc=0x31c
20636
20637         # ignore failure
20638         $LFS data_version $DIR/$tdir/$tfile || true
20639
20640         do_facet ost1 $LCTL set_param fail_loc=0
20641         umount_client $MOUNT || error "umount failed"
20642         mount_client $MOUNT || error "mount failed"
20643         stop ost1 || error "cannot stop ost1"
20644         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20645 }
20646 run_test 232b "failed data version lock should not block umount"
20647
20648 test_233a() {
20649         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20650                 skip "Need MDS version at least 2.3.64"
20651         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20652
20653         local fid=$($LFS path2fid $MOUNT)
20654
20655         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20656                 error "cannot access $MOUNT using its FID '$fid'"
20657 }
20658 run_test 233a "checking that OBF of the FS root succeeds"
20659
20660 test_233b() {
20661         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20662                 skip "Need MDS version at least 2.5.90"
20663         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20664
20665         local fid=$($LFS path2fid $MOUNT/.lustre)
20666
20667         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20668                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20669
20670         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20671         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20672                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20673 }
20674 run_test 233b "checking that OBF of the FS .lustre succeeds"
20675
20676 test_234() {
20677         local p="$TMP/sanityN-$TESTNAME.parameters"
20678         save_lustre_params client "llite.*.xattr_cache" > $p
20679         lctl set_param llite.*.xattr_cache 1 ||
20680                 skip_env "xattr cache is not supported"
20681
20682         mkdir -p $DIR/$tdir || error "mkdir failed"
20683         touch $DIR/$tdir/$tfile || error "touch failed"
20684         # OBD_FAIL_LLITE_XATTR_ENOMEM
20685         $LCTL set_param fail_loc=0x1405
20686         getfattr -n user.attr $DIR/$tdir/$tfile &&
20687                 error "getfattr should have failed with ENOMEM"
20688         $LCTL set_param fail_loc=0x0
20689         rm -rf $DIR/$tdir
20690
20691         restore_lustre_params < $p
20692         rm -f $p
20693 }
20694 run_test 234 "xattr cache should not crash on ENOMEM"
20695
20696 test_235() {
20697         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20698                 skip "Need MDS version at least 2.4.52"
20699
20700         flock_deadlock $DIR/$tfile
20701         local RC=$?
20702         case $RC in
20703                 0)
20704                 ;;
20705                 124) error "process hangs on a deadlock"
20706                 ;;
20707                 *) error "error executing flock_deadlock $DIR/$tfile"
20708                 ;;
20709         esac
20710 }
20711 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20712
20713 #LU-2935
20714 test_236() {
20715         check_swap_layouts_support
20716
20717         local ref1=/etc/passwd
20718         local ref2=/etc/group
20719         local file1=$DIR/$tdir/f1
20720         local file2=$DIR/$tdir/f2
20721
20722         test_mkdir -c1 $DIR/$tdir
20723         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20724         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20725         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20726         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20727         local fd=$(free_fd)
20728         local cmd="exec $fd<>$file2"
20729         eval $cmd
20730         rm $file2
20731         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20732                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20733         cmd="exec $fd>&-"
20734         eval $cmd
20735         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20736
20737         #cleanup
20738         rm -rf $DIR/$tdir
20739 }
20740 run_test 236 "Layout swap on open unlinked file"
20741
20742 # LU-4659 linkea consistency
20743 test_238() {
20744         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20745                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20746                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20747                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20748
20749         touch $DIR/$tfile
20750         ln $DIR/$tfile $DIR/$tfile.lnk
20751         touch $DIR/$tfile.new
20752         mv $DIR/$tfile.new $DIR/$tfile
20753         local fid1=$($LFS path2fid $DIR/$tfile)
20754         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20755         local path1=$($LFS fid2path $FSNAME "$fid1")
20756         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20757         local path2=$($LFS fid2path $FSNAME "$fid2")
20758         [ $tfile.lnk == $path2 ] ||
20759                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20760         rm -f $DIR/$tfile*
20761 }
20762 run_test 238 "Verify linkea consistency"
20763
20764 test_239A() { # was test_239
20765         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20766                 skip "Need MDS version at least 2.5.60"
20767
20768         local list=$(comma_list $(mdts_nodes))
20769
20770         mkdir -p $DIR/$tdir
20771         createmany -o $DIR/$tdir/f- 5000
20772         unlinkmany $DIR/$tdir/f- 5000
20773         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20774                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20775         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20776                         osp.*MDT*.sync_in_flight" | calc_sum)
20777         [ "$changes" -eq 0 ] || error "$changes not synced"
20778 }
20779 run_test 239A "osp_sync test"
20780
20781 test_239a() { #LU-5297
20782         remote_mds_nodsh && skip "remote MDS with nodsh"
20783
20784         touch $DIR/$tfile
20785         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20786         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20787         chgrp $RUNAS_GID $DIR/$tfile
20788         wait_delete_completed
20789 }
20790 run_test 239a "process invalid osp sync record correctly"
20791
20792 test_239b() { #LU-5297
20793         remote_mds_nodsh && skip "remote MDS with nodsh"
20794
20795         touch $DIR/$tfile1
20796         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20797         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20798         chgrp $RUNAS_GID $DIR/$tfile1
20799         wait_delete_completed
20800         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20801         touch $DIR/$tfile2
20802         chgrp $RUNAS_GID $DIR/$tfile2
20803         wait_delete_completed
20804 }
20805 run_test 239b "process osp sync record with ENOMEM error correctly"
20806
20807 test_240() {
20808         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20809         remote_mds_nodsh && skip "remote MDS with nodsh"
20810
20811         mkdir -p $DIR/$tdir
20812
20813         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20814                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20815         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20816                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20817
20818         umount_client $MOUNT || error "umount failed"
20819         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20820         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20821         mount_client $MOUNT || error "failed to mount client"
20822
20823         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20824         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20825 }
20826 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20827
20828 test_241_bio() {
20829         local count=$1
20830         local bsize=$2
20831
20832         for LOOP in $(seq $count); do
20833                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20834                 cancel_lru_locks $OSC || true
20835         done
20836 }
20837
20838 test_241_dio() {
20839         local count=$1
20840         local bsize=$2
20841
20842         for LOOP in $(seq $1); do
20843                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20844                         2>/dev/null
20845         done
20846 }
20847
20848 test_241a() { # was test_241
20849         local bsize=$PAGE_SIZE
20850
20851         (( bsize < 40960 )) && bsize=40960
20852         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20853         ls -la $DIR/$tfile
20854         cancel_lru_locks $OSC
20855         test_241_bio 1000 $bsize &
20856         PID=$!
20857         test_241_dio 1000 $bsize
20858         wait $PID
20859 }
20860 run_test 241a "bio vs dio"
20861
20862 test_241b() {
20863         local bsize=$PAGE_SIZE
20864
20865         (( bsize < 40960 )) && bsize=40960
20866         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20867         ls -la $DIR/$tfile
20868         test_241_dio 1000 $bsize &
20869         PID=$!
20870         test_241_dio 1000 $bsize
20871         wait $PID
20872 }
20873 run_test 241b "dio vs dio"
20874
20875 test_242() {
20876         remote_mds_nodsh && skip "remote MDS with nodsh"
20877
20878         mkdir_on_mdt0 $DIR/$tdir
20879         touch $DIR/$tdir/$tfile
20880
20881         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20882         do_facet mds1 lctl set_param fail_loc=0x105
20883         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20884
20885         do_facet mds1 lctl set_param fail_loc=0
20886         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20887 }
20888 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20889
20890 test_243()
20891 {
20892         test_mkdir $DIR/$tdir
20893         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20894 }
20895 run_test 243 "various group lock tests"
20896
20897 test_244a()
20898 {
20899         test_mkdir $DIR/$tdir
20900         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20901         sendfile_grouplock $DIR/$tdir/$tfile || \
20902                 error "sendfile+grouplock failed"
20903         rm -rf $DIR/$tdir
20904 }
20905 run_test 244a "sendfile with group lock tests"
20906
20907 test_244b()
20908 {
20909         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20910
20911         local threads=50
20912         local size=$((1024*1024))
20913
20914         test_mkdir $DIR/$tdir
20915         for i in $(seq 1 $threads); do
20916                 local file=$DIR/$tdir/file_$((i / 10))
20917                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20918                 local pids[$i]=$!
20919         done
20920         for i in $(seq 1 $threads); do
20921                 wait ${pids[$i]}
20922         done
20923 }
20924 run_test 244b "multi-threaded write with group lock"
20925
20926 test_245() {
20927         local flagname="multi_mod_rpcs"
20928         local connect_data_name="max_mod_rpcs"
20929         local out
20930
20931         # check if multiple modify RPCs flag is set
20932         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20933                 grep "connect_flags:")
20934         echo "$out"
20935
20936         echo "$out" | grep -qw $flagname
20937         if [ $? -ne 0 ]; then
20938                 echo "connect flag $flagname is not set"
20939                 return
20940         fi
20941
20942         # check if multiple modify RPCs data is set
20943         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20944         echo "$out"
20945
20946         echo "$out" | grep -qw $connect_data_name ||
20947                 error "import should have connect data $connect_data_name"
20948 }
20949 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
20950
20951 cleanup_247() {
20952         local submount=$1
20953
20954         trap 0
20955         umount_client $submount
20956         rmdir $submount
20957 }
20958
20959 test_247a() {
20960         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20961                 grep -q subtree ||
20962                 skip_env "Fileset feature is not supported"
20963
20964         local submount=${MOUNT}_$tdir
20965
20966         mkdir $MOUNT/$tdir
20967         mkdir -p $submount || error "mkdir $submount failed"
20968         FILESET="$FILESET/$tdir" mount_client $submount ||
20969                 error "mount $submount failed"
20970         trap "cleanup_247 $submount" EXIT
20971         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
20972         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
20973                 error "read $MOUNT/$tdir/$tfile failed"
20974         cleanup_247 $submount
20975 }
20976 run_test 247a "mount subdir as fileset"
20977
20978 test_247b() {
20979         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20980                 skip_env "Fileset feature is not supported"
20981
20982         local submount=${MOUNT}_$tdir
20983
20984         rm -rf $MOUNT/$tdir
20985         mkdir -p $submount || error "mkdir $submount failed"
20986         SKIP_FILESET=1
20987         FILESET="$FILESET/$tdir" mount_client $submount &&
20988                 error "mount $submount should fail"
20989         rmdir $submount
20990 }
20991 run_test 247b "mount subdir that dose not exist"
20992
20993 test_247c() {
20994         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20995                 skip_env "Fileset feature is not supported"
20996
20997         local submount=${MOUNT}_$tdir
20998
20999         mkdir -p $MOUNT/$tdir/dir1
21000         mkdir -p $submount || error "mkdir $submount failed"
21001         trap "cleanup_247 $submount" EXIT
21002         FILESET="$FILESET/$tdir" mount_client $submount ||
21003                 error "mount $submount failed"
21004         local fid=$($LFS path2fid $MOUNT/)
21005         $LFS fid2path $submount $fid && error "fid2path should fail"
21006         cleanup_247 $submount
21007 }
21008 run_test 247c "running fid2path outside subdirectory root"
21009
21010 test_247d() {
21011         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21012                 skip "Fileset feature is not supported"
21013
21014         local submount=${MOUNT}_$tdir
21015
21016         mkdir -p $MOUNT/$tdir/dir1
21017         mkdir -p $submount || error "mkdir $submount failed"
21018         FILESET="$FILESET/$tdir" mount_client $submount ||
21019                 error "mount $submount failed"
21020         trap "cleanup_247 $submount" EXIT
21021
21022         local td=$submount/dir1
21023         local fid=$($LFS path2fid $td)
21024         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21025
21026         # check that we get the same pathname back
21027         local rootpath
21028         local found
21029         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21030                 echo "$rootpath $fid"
21031                 found=$($LFS fid2path $rootpath "$fid")
21032                 [ -n "found" ] || error "fid2path should succeed"
21033                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21034         done
21035         # check wrong root path format
21036         rootpath=$submount"_wrong"
21037         found=$($LFS fid2path $rootpath "$fid")
21038         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21039
21040         cleanup_247 $submount
21041 }
21042 run_test 247d "running fid2path inside subdirectory root"
21043
21044 # LU-8037
21045 test_247e() {
21046         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21047                 grep -q subtree ||
21048                 skip "Fileset feature is not supported"
21049
21050         local submount=${MOUNT}_$tdir
21051
21052         mkdir $MOUNT/$tdir
21053         mkdir -p $submount || error "mkdir $submount failed"
21054         FILESET="$FILESET/.." mount_client $submount &&
21055                 error "mount $submount should fail"
21056         rmdir $submount
21057 }
21058 run_test 247e "mount .. as fileset"
21059
21060 test_247f() {
21061         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21062         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21063                 skip "Need at least version 2.13.52"
21064         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21065                 skip "Need at least version 2.14.50"
21066         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21067                 grep -q subtree ||
21068                 skip "Fileset feature is not supported"
21069
21070         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21071         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21072                 error "mkdir remote failed"
21073         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21074                 error "mkdir remote/subdir failed"
21075         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21076                 error "mkdir striped failed"
21077         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21078
21079         local submount=${MOUNT}_$tdir
21080
21081         mkdir -p $submount || error "mkdir $submount failed"
21082         stack_trap "rmdir $submount"
21083
21084         local dir
21085         local stat
21086         local fileset=$FILESET
21087         local mdts=$(comma_list $(mdts_nodes))
21088
21089         stat=$(do_facet mds1 $LCTL get_param -n \
21090                 mdt.*MDT0000.enable_remote_subdir_mount)
21091         stack_trap "do_nodes $mdts $LCTL set_param \
21092                 mdt.*.enable_remote_subdir_mount=$stat"
21093
21094         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21095         stack_trap "umount_client $submount"
21096         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21097                 error "mount remote dir $dir should fail"
21098
21099         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21100                 $tdir/striped/. ; do
21101                 FILESET="$fileset/$dir" mount_client $submount ||
21102                         error "mount $dir failed"
21103                 umount_client $submount
21104         done
21105
21106         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21107         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21108                 error "mount $tdir/remote failed"
21109 }
21110 run_test 247f "mount striped or remote directory as fileset"
21111
21112 test_247g() {
21113         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21114         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21115                 skip "Need at least version 2.14.50"
21116
21117         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21118                 error "mkdir $tdir failed"
21119         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21120
21121         local submount=${MOUNT}_$tdir
21122
21123         mkdir -p $submount || error "mkdir $submount failed"
21124         stack_trap "rmdir $submount"
21125
21126         FILESET="$fileset/$tdir" mount_client $submount ||
21127                 error "mount $dir failed"
21128         stack_trap "umount $submount"
21129
21130         local mdts=$(comma_list $(mdts_nodes))
21131
21132         local nrpcs
21133
21134         stat $submount > /dev/null
21135         cancel_lru_locks $MDC
21136         stat $submount > /dev/null
21137         stat $submount/$tfile > /dev/null
21138         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21139         stat $submount/$tfile > /dev/null
21140         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21141                 awk '/getattr/ {sum += $2} END {print sum}')
21142
21143         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21144 }
21145 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21146
21147 test_248a() {
21148         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21149         [ -z "$fast_read_sav" ] && skip "no fast read support"
21150
21151         # create a large file for fast read verification
21152         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21153
21154         # make sure the file is created correctly
21155         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21156                 { rm -f $DIR/$tfile; skip "file creation error"; }
21157
21158         echo "Test 1: verify that fast read is 4 times faster on cache read"
21159
21160         # small read with fast read enabled
21161         $LCTL set_param -n llite.*.fast_read=1
21162         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21163                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21164                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21165         # small read with fast read disabled
21166         $LCTL set_param -n llite.*.fast_read=0
21167         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21168                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21169                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21170
21171         # verify that fast read is 4 times faster for cache read
21172         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21173                 error_not_in_vm "fast read was not 4 times faster: " \
21174                            "$t_fast vs $t_slow"
21175
21176         echo "Test 2: verify the performance between big and small read"
21177         $LCTL set_param -n llite.*.fast_read=1
21178
21179         # 1k non-cache read
21180         cancel_lru_locks osc
21181         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21182                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21183                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21184
21185         # 1M non-cache read
21186         cancel_lru_locks osc
21187         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21188                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21189                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21190
21191         # verify that big IO is not 4 times faster than small IO
21192         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21193                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21194
21195         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21196         rm -f $DIR/$tfile
21197 }
21198 run_test 248a "fast read verification"
21199
21200 test_248b() {
21201         # Default short_io_bytes=16384, try both smaller and larger sizes.
21202         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21203         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21204         echo "bs=53248 count=113 normal buffered write"
21205         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21206                 error "dd of initial data file failed"
21207         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21208
21209         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21210         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21211                 error "dd with sync normal writes failed"
21212         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21213
21214         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21215         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21216                 error "dd with sync small writes failed"
21217         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21218
21219         cancel_lru_locks osc
21220
21221         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21222         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21223         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21224         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21225                 iflag=direct || error "dd with O_DIRECT small read failed"
21226         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21227         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21228                 error "compare $TMP/$tfile.1 failed"
21229
21230         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21231         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21232
21233         # just to see what the maximum tunable value is, and test parsing
21234         echo "test invalid parameter 2MB"
21235         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21236                 error "too-large short_io_bytes allowed"
21237         echo "test maximum parameter 512KB"
21238         # if we can set a larger short_io_bytes, run test regardless of version
21239         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21240                 # older clients may not allow setting it this large, that's OK
21241                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21242                         skip "Need at least client version 2.13.50"
21243                 error "medium short_io_bytes failed"
21244         fi
21245         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21246         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21247
21248         echo "test large parameter 64KB"
21249         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21250         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21251
21252         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21253         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21254                 error "dd with sync large writes failed"
21255         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21256
21257         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21258         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21259         num=$((113 * 4096 / PAGE_SIZE))
21260         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21261         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21262                 error "dd with O_DIRECT large writes failed"
21263         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21264                 error "compare $DIR/$tfile.3 failed"
21265
21266         cancel_lru_locks osc
21267
21268         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21269         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21270                 error "dd with O_DIRECT large read failed"
21271         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21272                 error "compare $TMP/$tfile.2 failed"
21273
21274         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21275         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21276                 error "dd with O_DIRECT large read failed"
21277         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21278                 error "compare $TMP/$tfile.3 failed"
21279 }
21280 run_test 248b "test short_io read and write for both small and large sizes"
21281
21282 test_249() { # LU-7890
21283         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21284                 skip "Need at least version 2.8.54"
21285
21286         rm -f $DIR/$tfile
21287         $LFS setstripe -c 1 $DIR/$tfile
21288         # Offset 2T == 4k * 512M
21289         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21290                 error "dd to 2T offset failed"
21291 }
21292 run_test 249 "Write above 2T file size"
21293
21294 test_250() {
21295         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21296          && skip "no 16TB file size limit on ZFS"
21297
21298         $LFS setstripe -c 1 $DIR/$tfile
21299         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21300         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21301         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21302         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21303                 conv=notrunc,fsync && error "append succeeded"
21304         return 0
21305 }
21306 run_test 250 "Write above 16T limit"
21307
21308 test_251() {
21309         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21310
21311         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21312         #Skip once - writing the first stripe will succeed
21313         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21314         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21315                 error "short write happened"
21316
21317         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21318         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21319                 error "short read happened"
21320
21321         rm -f $DIR/$tfile
21322 }
21323 run_test 251 "Handling short read and write correctly"
21324
21325 test_252() {
21326         remote_mds_nodsh && skip "remote MDS with nodsh"
21327         remote_ost_nodsh && skip "remote OST with nodsh"
21328         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21329                 skip_env "ldiskfs only test"
21330         fi
21331
21332         local tgt
21333         local dev
21334         local out
21335         local uuid
21336         local num
21337         local gen
21338
21339         # check lr_reader on OST0000
21340         tgt=ost1
21341         dev=$(facet_device $tgt)
21342         out=$(do_facet $tgt $LR_READER $dev)
21343         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21344         echo "$out"
21345         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21346         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21347                 error "Invalid uuid returned by $LR_READER on target $tgt"
21348         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21349
21350         # check lr_reader -c on MDT0000
21351         tgt=mds1
21352         dev=$(facet_device $tgt)
21353         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21354                 skip "$LR_READER does not support additional options"
21355         fi
21356         out=$(do_facet $tgt $LR_READER -c $dev)
21357         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21358         echo "$out"
21359         num=$(echo "$out" | grep -c "mdtlov")
21360         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21361                 error "Invalid number of mdtlov clients returned by $LR_READER"
21362         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21363
21364         # check lr_reader -cr on MDT0000
21365         out=$(do_facet $tgt $LR_READER -cr $dev)
21366         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21367         echo "$out"
21368         echo "$out" | grep -q "^reply_data:$" ||
21369                 error "$LR_READER should have returned 'reply_data' section"
21370         num=$(echo "$out" | grep -c "client_generation")
21371         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21372 }
21373 run_test 252 "check lr_reader tool"
21374
21375 test_253() {
21376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21377         remote_mds_nodsh && skip "remote MDS with nodsh"
21378         remote_mgs_nodsh && skip "remote MGS with nodsh"
21379
21380         local ostidx=0
21381         local rc=0
21382         local ost_name=$(ostname_from_index $ostidx)
21383
21384         # on the mdt's osc
21385         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21386         do_facet $SINGLEMDS $LCTL get_param -n \
21387                 osp.$mdtosc_proc1.reserved_mb_high ||
21388                 skip  "remote MDS does not support reserved_mb_high"
21389
21390         rm -rf $DIR/$tdir
21391         wait_mds_ost_sync
21392         wait_delete_completed
21393         mkdir $DIR/$tdir
21394
21395         pool_add $TESTNAME || error "Pool creation failed"
21396         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21397
21398         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21399                 error "Setstripe failed"
21400
21401         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21402
21403         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21404                     grep "watermarks")
21405         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21406
21407         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21408                         osp.$mdtosc_proc1.prealloc_status)
21409         echo "prealloc_status $oa_status"
21410
21411         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21412                 error "File creation should fail"
21413
21414         #object allocation was stopped, but we still able to append files
21415         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21416                 oflag=append || error "Append failed"
21417
21418         rm -f $DIR/$tdir/$tfile.0
21419
21420         # For this test, we want to delete the files we created to go out of
21421         # space but leave the watermark, so we remain nearly out of space
21422         ost_watermarks_enospc_delete_files $tfile $ostidx
21423
21424         wait_delete_completed
21425
21426         sleep_maxage
21427
21428         for i in $(seq 10 12); do
21429                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21430                         2>/dev/null || error "File creation failed after rm"
21431         done
21432
21433         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21434                         osp.$mdtosc_proc1.prealloc_status)
21435         echo "prealloc_status $oa_status"
21436
21437         if (( oa_status != 0 )); then
21438                 error "Object allocation still disable after rm"
21439         fi
21440 }
21441 run_test 253 "Check object allocation limit"
21442
21443 test_254() {
21444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21445         remote_mds_nodsh && skip "remote MDS with nodsh"
21446
21447         local mdt=$(facet_svc $SINGLEMDS)
21448
21449         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21450                 skip "MDS does not support changelog_size"
21451
21452         local cl_user
21453
21454         changelog_register || error "changelog_register failed"
21455
21456         changelog_clear 0 || error "changelog_clear failed"
21457
21458         local size1=$(do_facet $SINGLEMDS \
21459                       $LCTL get_param -n mdd.$mdt.changelog_size)
21460         echo "Changelog size $size1"
21461
21462         rm -rf $DIR/$tdir
21463         $LFS mkdir -i 0 $DIR/$tdir
21464         # change something
21465         mkdir -p $DIR/$tdir/pics/2008/zachy
21466         touch $DIR/$tdir/pics/2008/zachy/timestamp
21467         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21468         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21469         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21470         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21471         rm $DIR/$tdir/pics/desktop.jpg
21472
21473         local size2=$(do_facet $SINGLEMDS \
21474                       $LCTL get_param -n mdd.$mdt.changelog_size)
21475         echo "Changelog size after work $size2"
21476
21477         (( $size2 > $size1 )) ||
21478                 error "new Changelog size=$size2 less than old size=$size1"
21479 }
21480 run_test 254 "Check changelog size"
21481
21482 ladvise_no_type()
21483 {
21484         local type=$1
21485         local file=$2
21486
21487         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21488                 awk -F: '{print $2}' | grep $type > /dev/null
21489         if [ $? -ne 0 ]; then
21490                 return 0
21491         fi
21492         return 1
21493 }
21494
21495 ladvise_no_ioctl()
21496 {
21497         local file=$1
21498
21499         lfs ladvise -a willread $file > /dev/null 2>&1
21500         if [ $? -eq 0 ]; then
21501                 return 1
21502         fi
21503
21504         lfs ladvise -a willread $file 2>&1 |
21505                 grep "Inappropriate ioctl for device" > /dev/null
21506         if [ $? -eq 0 ]; then
21507                 return 0
21508         fi
21509         return 1
21510 }
21511
21512 percent() {
21513         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21514 }
21515
21516 # run a random read IO workload
21517 # usage: random_read_iops <filename> <filesize> <iosize>
21518 random_read_iops() {
21519         local file=$1
21520         local fsize=$2
21521         local iosize=${3:-4096}
21522
21523         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21524                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21525 }
21526
21527 drop_file_oss_cache() {
21528         local file="$1"
21529         local nodes="$2"
21530
21531         $LFS ladvise -a dontneed $file 2>/dev/null ||
21532                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21533 }
21534
21535 ladvise_willread_performance()
21536 {
21537         local repeat=10
21538         local average_origin=0
21539         local average_cache=0
21540         local average_ladvise=0
21541
21542         for ((i = 1; i <= $repeat; i++)); do
21543                 echo "Iter $i/$repeat: reading without willread hint"
21544                 cancel_lru_locks osc
21545                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21546                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21547                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21548                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21549
21550                 cancel_lru_locks osc
21551                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21552                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21553                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21554
21555                 cancel_lru_locks osc
21556                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21557                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21558                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21559                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21560                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21561         done
21562         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21563         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21564         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21565
21566         speedup_cache=$(percent $average_cache $average_origin)
21567         speedup_ladvise=$(percent $average_ladvise $average_origin)
21568
21569         echo "Average uncached read: $average_origin"
21570         echo "Average speedup with OSS cached read: " \
21571                 "$average_cache = +$speedup_cache%"
21572         echo "Average speedup with ladvise willread: " \
21573                 "$average_ladvise = +$speedup_ladvise%"
21574
21575         local lowest_speedup=20
21576         if (( ${average_cache%.*} < $lowest_speedup )); then
21577                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
21578                      " got $average_cache%. Skipping ladvise willread check."
21579                 return 0
21580         fi
21581
21582         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21583         # it is still good to run until then to exercise 'ladvise willread'
21584         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21585                 [ "$ost1_FSTYPE" = "zfs" ] &&
21586                 echo "osd-zfs does not support dontneed or drop_caches" &&
21587                 return 0
21588
21589         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21590         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
21591                 error_not_in_vm "Speedup with willread is less than " \
21592                         "$lowest_speedup%, got $average_ladvise%"
21593 }
21594
21595 test_255a() {
21596         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21597                 skip "lustre < 2.8.54 does not support ladvise "
21598         remote_ost_nodsh && skip "remote OST with nodsh"
21599
21600         stack_trap "rm -f $DIR/$tfile"
21601         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21602
21603         ladvise_no_type willread $DIR/$tfile &&
21604                 skip "willread ladvise is not supported"
21605
21606         ladvise_no_ioctl $DIR/$tfile &&
21607                 skip "ladvise ioctl is not supported"
21608
21609         local size_mb=100
21610         local size=$((size_mb * 1048576))
21611         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21612                 error "dd to $DIR/$tfile failed"
21613
21614         lfs ladvise -a willread $DIR/$tfile ||
21615                 error "Ladvise failed with no range argument"
21616
21617         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21618                 error "Ladvise failed with no -l or -e argument"
21619
21620         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21621                 error "Ladvise failed with only -e argument"
21622
21623         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21624                 error "Ladvise failed with only -l argument"
21625
21626         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21627                 error "End offset should not be smaller than start offset"
21628
21629         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21630                 error "End offset should not be equal to start offset"
21631
21632         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21633                 error "Ladvise failed with overflowing -s argument"
21634
21635         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21636                 error "Ladvise failed with overflowing -e argument"
21637
21638         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21639                 error "Ladvise failed with overflowing -l argument"
21640
21641         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21642                 error "Ladvise succeeded with conflicting -l and -e arguments"
21643
21644         echo "Synchronous ladvise should wait"
21645         local delay=4
21646 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21647         do_nodes $(comma_list $(osts_nodes)) \
21648                 $LCTL set_param fail_val=$delay fail_loc=0x237
21649
21650         local start_ts=$SECONDS
21651         lfs ladvise -a willread $DIR/$tfile ||
21652                 error "Ladvise failed with no range argument"
21653         local end_ts=$SECONDS
21654         local inteval_ts=$((end_ts - start_ts))
21655
21656         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21657                 error "Synchronous advice didn't wait reply"
21658         fi
21659
21660         echo "Asynchronous ladvise shouldn't wait"
21661         local start_ts=$SECONDS
21662         lfs ladvise -a willread -b $DIR/$tfile ||
21663                 error "Ladvise failed with no range argument"
21664         local end_ts=$SECONDS
21665         local inteval_ts=$((end_ts - start_ts))
21666
21667         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21668                 error "Asynchronous advice blocked"
21669         fi
21670
21671         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21672         ladvise_willread_performance
21673 }
21674 run_test 255a "check 'lfs ladvise -a willread'"
21675
21676 facet_meminfo() {
21677         local facet=$1
21678         local info=$2
21679
21680         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21681 }
21682
21683 test_255b() {
21684         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21685                 skip "lustre < 2.8.54 does not support ladvise "
21686         remote_ost_nodsh && skip "remote OST with nodsh"
21687
21688         stack_trap "rm -f $DIR/$tfile"
21689         lfs setstripe -c 1 -i 0 $DIR/$tfile
21690
21691         ladvise_no_type dontneed $DIR/$tfile &&
21692                 skip "dontneed ladvise is not supported"
21693
21694         ladvise_no_ioctl $DIR/$tfile &&
21695                 skip "ladvise ioctl is not supported"
21696
21697         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21698                 [ "$ost1_FSTYPE" = "zfs" ] &&
21699                 skip "zfs-osd does not support 'ladvise dontneed'"
21700
21701         local size_mb=100
21702         local size=$((size_mb * 1048576))
21703         # In order to prevent disturbance of other processes, only check 3/4
21704         # of the memory usage
21705         local kibibytes=$((size_mb * 1024 * 3 / 4))
21706
21707         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21708                 error "dd to $DIR/$tfile failed"
21709
21710         #force write to complete before dropping OST cache & checking memory
21711         sync
21712
21713         local total=$(facet_meminfo ost1 MemTotal)
21714         echo "Total memory: $total KiB"
21715
21716         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21717         local before_read=$(facet_meminfo ost1 Cached)
21718         echo "Cache used before read: $before_read KiB"
21719
21720         lfs ladvise -a willread $DIR/$tfile ||
21721                 error "Ladvise willread failed"
21722         local after_read=$(facet_meminfo ost1 Cached)
21723         echo "Cache used after read: $after_read KiB"
21724
21725         lfs ladvise -a dontneed $DIR/$tfile ||
21726                 error "Ladvise dontneed again failed"
21727         local no_read=$(facet_meminfo ost1 Cached)
21728         echo "Cache used after dontneed ladvise: $no_read KiB"
21729
21730         if [ $total -lt $((before_read + kibibytes)) ]; then
21731                 echo "Memory is too small, abort checking"
21732                 return 0
21733         fi
21734
21735         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21736                 error "Ladvise willread should use more memory" \
21737                         "than $kibibytes KiB"
21738         fi
21739
21740         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21741                 error "Ladvise dontneed should release more memory" \
21742                         "than $kibibytes KiB"
21743         fi
21744 }
21745 run_test 255b "check 'lfs ladvise -a dontneed'"
21746
21747 test_255c() {
21748         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21749                 skip "lustre < 2.10.50 does not support lockahead"
21750
21751         local ost1_imp=$(get_osc_import_name client ost1)
21752         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21753                          cut -d'.' -f2)
21754         local count
21755         local new_count
21756         local difference
21757         local i
21758         local rc
21759
21760         test_mkdir -p $DIR/$tdir
21761         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21762
21763         #test 10 returns only success/failure
21764         i=10
21765         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21766         rc=$?
21767         if [ $rc -eq 255 ]; then
21768                 error "Ladvise test${i} failed, ${rc}"
21769         fi
21770
21771         #test 11 counts lock enqueue requests, all others count new locks
21772         i=11
21773         count=$(do_facet ost1 \
21774                 $LCTL get_param -n ost.OSS.ost.stats)
21775         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21776
21777         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21778         rc=$?
21779         if [ $rc -eq 255 ]; then
21780                 error "Ladvise test${i} failed, ${rc}"
21781         fi
21782
21783         new_count=$(do_facet ost1 \
21784                 $LCTL get_param -n ost.OSS.ost.stats)
21785         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21786                    awk '{ print $2 }')
21787
21788         difference="$((new_count - count))"
21789         if [ $difference -ne $rc ]; then
21790                 error "Ladvise test${i}, bad enqueue count, returned " \
21791                       "${rc}, actual ${difference}"
21792         fi
21793
21794         for i in $(seq 12 21); do
21795                 # If we do not do this, we run the risk of having too many
21796                 # locks and starting lock cancellation while we are checking
21797                 # lock counts.
21798                 cancel_lru_locks osc
21799
21800                 count=$($LCTL get_param -n \
21801                        ldlm.namespaces.$imp_name.lock_unused_count)
21802
21803                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21804                 rc=$?
21805                 if [ $rc -eq 255 ]; then
21806                         error "Ladvise test ${i} failed, ${rc}"
21807                 fi
21808
21809                 new_count=$($LCTL get_param -n \
21810                        ldlm.namespaces.$imp_name.lock_unused_count)
21811                 difference="$((new_count - count))"
21812
21813                 # Test 15 output is divided by 100 to map down to valid return
21814                 if [ $i -eq 15 ]; then
21815                         rc="$((rc * 100))"
21816                 fi
21817
21818                 if [ $difference -ne $rc ]; then
21819                         error "Ladvise test ${i}, bad lock count, returned " \
21820                               "${rc}, actual ${difference}"
21821                 fi
21822         done
21823
21824         #test 22 returns only success/failure
21825         i=22
21826         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21827         rc=$?
21828         if [ $rc -eq 255 ]; then
21829                 error "Ladvise test${i} failed, ${rc}"
21830         fi
21831 }
21832 run_test 255c "suite of ladvise lockahead tests"
21833
21834 test_256() {
21835         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21836         remote_mds_nodsh && skip "remote MDS with nodsh"
21837         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21838         changelog_users $SINGLEMDS | grep "^cl" &&
21839                 skip "active changelog user"
21840
21841         local cl_user
21842         local cat_sl
21843         local mdt_dev
21844
21845         mdt_dev=$(facet_device $SINGLEMDS)
21846         echo $mdt_dev
21847
21848         changelog_register || error "changelog_register failed"
21849
21850         rm -rf $DIR/$tdir
21851         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
21852
21853         changelog_clear 0 || error "changelog_clear failed"
21854
21855         # change something
21856         touch $DIR/$tdir/{1..10}
21857
21858         # stop the MDT
21859         stop $SINGLEMDS || error "Fail to stop MDT"
21860
21861         # remount the MDT
21862         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21863                 error "Fail to start MDT"
21864
21865         #after mount new plainllog is used
21866         touch $DIR/$tdir/{11..19}
21867         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21868         stack_trap "rm -f $tmpfile"
21869         cat_sl=$(do_facet $SINGLEMDS "sync; \
21870                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21871                  llog_reader $tmpfile | grep -c type=1064553b")
21872         do_facet $SINGLEMDS llog_reader $tmpfile
21873
21874         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21875
21876         changelog_clear 0 || error "changelog_clear failed"
21877
21878         cat_sl=$(do_facet $SINGLEMDS "sync; \
21879                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21880                  llog_reader $tmpfile | grep -c type=1064553b")
21881
21882         if (( cat_sl == 2 )); then
21883                 error "Empty plain llog was not deleted from changelog catalog"
21884         elif (( cat_sl != 1 )); then
21885                 error "Active plain llog shouldn't be deleted from catalog"
21886         fi
21887 }
21888 run_test 256 "Check llog delete for empty and not full state"
21889
21890 test_257() {
21891         remote_mds_nodsh && skip "remote MDS with nodsh"
21892         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21893                 skip "Need MDS version at least 2.8.55"
21894
21895         test_mkdir $DIR/$tdir
21896
21897         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21898                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21899         stat $DIR/$tdir
21900
21901 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21902         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21903         local facet=mds$((mdtidx + 1))
21904         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21905         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21906
21907         stop $facet || error "stop MDS failed"
21908         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21909                 error "start MDS fail"
21910         wait_recovery_complete $facet
21911 }
21912 run_test 257 "xattr locks are not lost"
21913
21914 # Verify we take the i_mutex when security requires it
21915 test_258a() {
21916 #define OBD_FAIL_IMUTEX_SEC 0x141c
21917         $LCTL set_param fail_loc=0x141c
21918         touch $DIR/$tfile
21919         chmod u+s $DIR/$tfile
21920         chmod a+rwx $DIR/$tfile
21921         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21922         RC=$?
21923         if [ $RC -ne 0 ]; then
21924                 error "error, failed to take i_mutex, rc=$?"
21925         fi
21926         rm -f $DIR/$tfile
21927 }
21928 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21929
21930 # Verify we do NOT take the i_mutex in the normal case
21931 test_258b() {
21932 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21933         $LCTL set_param fail_loc=0x141d
21934         touch $DIR/$tfile
21935         chmod a+rwx $DIR
21936         chmod a+rw $DIR/$tfile
21937         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21938         RC=$?
21939         if [ $RC -ne 0 ]; then
21940                 error "error, took i_mutex unnecessarily, rc=$?"
21941         fi
21942         rm -f $DIR/$tfile
21943
21944 }
21945 run_test 258b "verify i_mutex security behavior"
21946
21947 test_259() {
21948         local file=$DIR/$tfile
21949         local before
21950         local after
21951
21952         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21953
21954         stack_trap "rm -f $file" EXIT
21955
21956         wait_delete_completed
21957         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21958         echo "before: $before"
21959
21960         $LFS setstripe -i 0 -c 1 $file
21961         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21962         sync_all_data
21963         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21964         echo "after write: $after"
21965
21966 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
21967         do_facet ost1 $LCTL set_param fail_loc=0x2301
21968         $TRUNCATE $file 0
21969         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21970         echo "after truncate: $after"
21971
21972         stop ost1
21973         do_facet ost1 $LCTL set_param fail_loc=0
21974         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21975         sleep 2
21976         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21977         echo "after restart: $after"
21978         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
21979                 error "missing truncate?"
21980
21981         return 0
21982 }
21983 run_test 259 "crash at delayed truncate"
21984
21985 test_260() {
21986 #define OBD_FAIL_MDC_CLOSE               0x806
21987         $LCTL set_param fail_loc=0x80000806
21988         touch $DIR/$tfile
21989
21990 }
21991 run_test 260 "Check mdc_close fail"
21992
21993 ### Data-on-MDT sanity tests ###
21994 test_270a() {
21995         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21996                 skip "Need MDS version at least 2.10.55 for DoM"
21997
21998         # create DoM file
21999         local dom=$DIR/$tdir/dom_file
22000         local tmp=$DIR/$tdir/tmp_file
22001
22002         mkdir_on_mdt0 $DIR/$tdir
22003
22004         # basic checks for DoM component creation
22005         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22006                 error "Can set MDT layout to non-first entry"
22007
22008         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22009                 error "Can define multiple entries as MDT layout"
22010
22011         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22012
22013         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22014         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22015         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22016
22017         local mdtidx=$($LFS getstripe -m $dom)
22018         local mdtname=MDT$(printf %04x $mdtidx)
22019         local facet=mds$((mdtidx + 1))
22020         local space_check=1
22021
22022         # Skip free space checks with ZFS
22023         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22024
22025         # write
22026         sync
22027         local size_tmp=$((65536 * 3))
22028         local mdtfree1=$(do_facet $facet \
22029                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22030
22031         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22032         # check also direct IO along write
22033         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22034         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22035         sync
22036         cmp $tmp $dom || error "file data is different"
22037         [ $(stat -c%s $dom) == $size_tmp ] ||
22038                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22039         if [ $space_check == 1 ]; then
22040                 local mdtfree2=$(do_facet $facet \
22041                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22042
22043                 # increase in usage from by $size_tmp
22044                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22045                         error "MDT free space wrong after write: " \
22046                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22047         fi
22048
22049         # truncate
22050         local size_dom=10000
22051
22052         $TRUNCATE $dom $size_dom
22053         [ $(stat -c%s $dom) == $size_dom ] ||
22054                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22055         if [ $space_check == 1 ]; then
22056                 mdtfree1=$(do_facet $facet \
22057                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22058                 # decrease in usage from $size_tmp to new $size_dom
22059                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22060                   $(((size_tmp - size_dom) / 1024)) ] ||
22061                         error "MDT free space is wrong after truncate: " \
22062                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22063         fi
22064
22065         # append
22066         cat $tmp >> $dom
22067         sync
22068         size_dom=$((size_dom + size_tmp))
22069         [ $(stat -c%s $dom) == $size_dom ] ||
22070                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22071         if [ $space_check == 1 ]; then
22072                 mdtfree2=$(do_facet $facet \
22073                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22074                 # increase in usage by $size_tmp from previous
22075                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22076                         error "MDT free space is wrong after append: " \
22077                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22078         fi
22079
22080         # delete
22081         rm $dom
22082         if [ $space_check == 1 ]; then
22083                 mdtfree1=$(do_facet $facet \
22084                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22085                 # decrease in usage by $size_dom from previous
22086                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22087                         error "MDT free space is wrong after removal: " \
22088                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22089         fi
22090
22091         # combined striping
22092         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22093                 error "Can't create DoM + OST striping"
22094
22095         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22096         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22097         # check also direct IO along write
22098         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22099         sync
22100         cmp $tmp $dom || error "file data is different"
22101         [ $(stat -c%s $dom) == $size_tmp ] ||
22102                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22103         rm $dom $tmp
22104
22105         return 0
22106 }
22107 run_test 270a "DoM: basic functionality tests"
22108
22109 test_270b() {
22110         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22111                 skip "Need MDS version at least 2.10.55"
22112
22113         local dom=$DIR/$tdir/dom_file
22114         local max_size=1048576
22115
22116         mkdir -p $DIR/$tdir
22117         $LFS setstripe -E $max_size -L mdt $dom
22118
22119         # truncate over the limit
22120         $TRUNCATE $dom $(($max_size + 1)) &&
22121                 error "successful truncate over the maximum size"
22122         # write over the limit
22123         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22124                 error "successful write over the maximum size"
22125         # append over the limit
22126         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22127         echo "12345" >> $dom && error "successful append over the maximum size"
22128         rm $dom
22129
22130         return 0
22131 }
22132 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22133
22134 test_270c() {
22135         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22136                 skip "Need MDS version at least 2.10.55"
22137
22138         mkdir -p $DIR/$tdir
22139         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22140
22141         # check files inherit DoM EA
22142         touch $DIR/$tdir/first
22143         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22144                 error "bad pattern"
22145         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22146                 error "bad stripe count"
22147         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22148                 error "bad stripe size"
22149
22150         # check directory inherits DoM EA and uses it as default
22151         mkdir $DIR/$tdir/subdir
22152         touch $DIR/$tdir/subdir/second
22153         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22154                 error "bad pattern in sub-directory"
22155         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22156                 error "bad stripe count in sub-directory"
22157         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22158                 error "bad stripe size in sub-directory"
22159         return 0
22160 }
22161 run_test 270c "DoM: DoM EA inheritance tests"
22162
22163 test_270d() {
22164         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22165                 skip "Need MDS version at least 2.10.55"
22166
22167         mkdir -p $DIR/$tdir
22168         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22169
22170         # inherit default DoM striping
22171         mkdir $DIR/$tdir/subdir
22172         touch $DIR/$tdir/subdir/f1
22173
22174         # change default directory striping
22175         $LFS setstripe -c 1 $DIR/$tdir/subdir
22176         touch $DIR/$tdir/subdir/f2
22177         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22178                 error "wrong default striping in file 2"
22179         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22180                 error "bad pattern in file 2"
22181         return 0
22182 }
22183 run_test 270d "DoM: change striping from DoM to RAID0"
22184
22185 test_270e() {
22186         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22187                 skip "Need MDS version at least 2.10.55"
22188
22189         mkdir -p $DIR/$tdir/dom
22190         mkdir -p $DIR/$tdir/norm
22191         DOMFILES=20
22192         NORMFILES=10
22193         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22194         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22195
22196         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22197         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22198
22199         # find DoM files by layout
22200         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22201         [ $NUM -eq  $DOMFILES ] ||
22202                 error "lfs find -L: found $NUM, expected $DOMFILES"
22203         echo "Test 1: lfs find 20 DOM files by layout: OK"
22204
22205         # there should be 1 dir with default DOM striping
22206         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22207         [ $NUM -eq  1 ] ||
22208                 error "lfs find -L: found $NUM, expected 1 dir"
22209         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22210
22211         # find DoM files by stripe size
22212         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22213         [ $NUM -eq  $DOMFILES ] ||
22214                 error "lfs find -S: found $NUM, expected $DOMFILES"
22215         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22216
22217         # find files by stripe offset except DoM files
22218         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22219         [ $NUM -eq  $NORMFILES ] ||
22220                 error "lfs find -i: found $NUM, expected $NORMFILES"
22221         echo "Test 5: lfs find no DOM files by stripe index: OK"
22222         return 0
22223 }
22224 run_test 270e "DoM: lfs find with DoM files test"
22225
22226 test_270f() {
22227         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22228                 skip "Need MDS version at least 2.10.55"
22229
22230         local mdtname=${FSNAME}-MDT0000-mdtlov
22231         local dom=$DIR/$tdir/dom_file
22232         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22233                                                 lod.$mdtname.dom_stripesize)
22234         local dom_limit=131072
22235
22236         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22237         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22238                                                 lod.$mdtname.dom_stripesize)
22239         [ ${dom_limit} -eq ${dom_current} ] ||
22240                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22241
22242         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22243         $LFS setstripe -d $DIR/$tdir
22244         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22245                 error "Can't set directory default striping"
22246
22247         # exceed maximum stripe size
22248         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22249                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22250         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22251                 error "Able to create DoM component size more than LOD limit"
22252
22253         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22254         dom_current=$(do_facet mds1 $LCTL get_param -n \
22255                                                 lod.$mdtname.dom_stripesize)
22256         [ 0 -eq ${dom_current} ] ||
22257                 error "Can't set zero DoM stripe limit"
22258         rm $dom
22259
22260         # attempt to create DoM file on server with disabled DoM should
22261         # remove DoM entry from layout and be succeed
22262         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22263                 error "Can't create DoM file (DoM is disabled)"
22264         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22265                 error "File has DoM component while DoM is disabled"
22266         rm $dom
22267
22268         # attempt to create DoM file with only DoM stripe should return error
22269         $LFS setstripe -E $dom_limit -L mdt $dom &&
22270                 error "Able to create DoM-only file while DoM is disabled"
22271
22272         # too low values to be aligned with smallest stripe size 64K
22273         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22274         dom_current=$(do_facet mds1 $LCTL get_param -n \
22275                                                 lod.$mdtname.dom_stripesize)
22276         [ 30000 -eq ${dom_current} ] &&
22277                 error "Can set too small DoM stripe limit"
22278
22279         # 64K is a minimal stripe size in Lustre, expect limit of that size
22280         [ 65536 -eq ${dom_current} ] ||
22281                 error "Limit is not set to 64K but ${dom_current}"
22282
22283         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22284         dom_current=$(do_facet mds1 $LCTL get_param -n \
22285                                                 lod.$mdtname.dom_stripesize)
22286         echo $dom_current
22287         [ 2147483648 -eq ${dom_current} ] &&
22288                 error "Can set too large DoM stripe limit"
22289
22290         do_facet mds1 $LCTL set_param -n \
22291                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22292         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22293                 error "Can't create DoM component size after limit change"
22294         do_facet mds1 $LCTL set_param -n \
22295                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22296         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22297                 error "Can't create DoM file after limit decrease"
22298         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22299                 error "Can create big DoM component after limit decrease"
22300         touch ${dom}_def ||
22301                 error "Can't create file with old default layout"
22302
22303         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22304         return 0
22305 }
22306 run_test 270f "DoM: maximum DoM stripe size checks"
22307
22308 test_270g() {
22309         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22310                 skip "Need MDS version at least 2.13.52"
22311         local dom=$DIR/$tdir/$tfile
22312
22313         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22314         local lodname=${FSNAME}-MDT0000-mdtlov
22315
22316         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22317         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22318         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22319         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22320
22321         local dom_limit=1024
22322         local dom_threshold="50%"
22323
22324         $LFS setstripe -d $DIR/$tdir
22325         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22326                 error "Can't set directory default striping"
22327
22328         do_facet mds1 $LCTL set_param -n \
22329                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22330         # set 0 threshold and create DOM file to change tunable stripesize
22331         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22332         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22333                 error "Failed to create $dom file"
22334         # now tunable dom_cur_stripesize should reach maximum
22335         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22336                                         lod.${lodname}.dom_stripesize_cur_kb)
22337         [[ $dom_current == $dom_limit ]] ||
22338                 error "Current DOM stripesize is not maximum"
22339         rm $dom
22340
22341         # set threshold for further tests
22342         do_facet mds1 $LCTL set_param -n \
22343                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22344         echo "DOM threshold is $dom_threshold free space"
22345         local dom_def
22346         local dom_set
22347         # Spoof bfree to exceed threshold
22348         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22349         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22350         for spfree in 40 20 0 15 30 55; do
22351                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22352                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22353                         error "Failed to create $dom file"
22354                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22355                                         lod.${lodname}.dom_stripesize_cur_kb)
22356                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22357                 [[ $dom_def != $dom_current ]] ||
22358                         error "Default stripe size was not changed"
22359                 if [[ $spfree > 0 ]] ; then
22360                         dom_set=$($LFS getstripe -S $dom)
22361                         [[ $dom_set == $((dom_def * 1024)) ]] ||
22362                                 error "DOM component size is still old"
22363                 else
22364                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22365                                 error "DoM component is set with no free space"
22366                 fi
22367                 rm $dom
22368                 dom_current=$dom_def
22369         done
22370 }
22371 run_test 270g "DoM: default DoM stripe size depends on free space"
22372
22373 test_270h() {
22374         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22375                 skip "Need MDS version at least 2.13.53"
22376
22377         local mdtname=${FSNAME}-MDT0000-mdtlov
22378         local dom=$DIR/$tdir/$tfile
22379         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22380
22381         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22382         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22383
22384         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22385         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22386                 error "can't create OST file"
22387         # mirrored file with DOM entry in the second mirror
22388         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22389                 error "can't create mirror with DoM component"
22390
22391         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22392
22393         # DOM component in the middle and has other enries in the same mirror,
22394         # should succeed but lost DoM component
22395         $LFS setstripe --copy=${dom}_1 $dom ||
22396                 error "Can't create file from OST|DOM mirror layout"
22397         # check new file has no DoM layout after all
22398         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22399                 error "File has DoM component while DoM is disabled"
22400 }
22401 run_test 270h "DoM: DoM stripe removal when disabled on server"
22402
22403 test_270i() {
22404         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22405                 skip "Need MDS version at least 2.14.54"
22406
22407         mkdir $DIR/$tdir
22408         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22409                 error "setstripe should fail" || true
22410 }
22411 run_test 270i "DoM: setting invalid DoM striping should fail"
22412
22413 test_271a() {
22414         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22415                 skip "Need MDS version at least 2.10.55"
22416
22417         local dom=$DIR/$tdir/dom
22418
22419         mkdir -p $DIR/$tdir
22420
22421         $LFS setstripe -E 1024K -L mdt $dom
22422
22423         lctl set_param -n mdc.*.stats=clear
22424         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22425         cat $dom > /dev/null
22426         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22427         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22428         ls $dom
22429         rm -f $dom
22430 }
22431 run_test 271a "DoM: data is cached for read after write"
22432
22433 test_271b() {
22434         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22435                 skip "Need MDS version at least 2.10.55"
22436
22437         local dom=$DIR/$tdir/dom
22438
22439         mkdir -p $DIR/$tdir
22440
22441         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22442
22443         lctl set_param -n mdc.*.stats=clear
22444         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22445         cancel_lru_locks mdc
22446         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22447         # second stat to check size is cached on client
22448         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22449         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22450         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22451         rm -f $dom
22452 }
22453 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22454
22455 test_271ba() {
22456         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22457                 skip "Need MDS version at least 2.10.55"
22458
22459         local dom=$DIR/$tdir/dom
22460
22461         mkdir -p $DIR/$tdir
22462
22463         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22464
22465         lctl set_param -n mdc.*.stats=clear
22466         lctl set_param -n osc.*.stats=clear
22467         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22468         cancel_lru_locks mdc
22469         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22470         # second stat to check size is cached on client
22471         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22472         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22473         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22474         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22475         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22476         rm -f $dom
22477 }
22478 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22479
22480
22481 get_mdc_stats() {
22482         local mdtidx=$1
22483         local param=$2
22484         local mdt=MDT$(printf %04x $mdtidx)
22485
22486         if [ -z $param ]; then
22487                 lctl get_param -n mdc.*$mdt*.stats
22488         else
22489                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22490         fi
22491 }
22492
22493 test_271c() {
22494         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22495                 skip "Need MDS version at least 2.10.55"
22496
22497         local dom=$DIR/$tdir/dom
22498
22499         mkdir -p $DIR/$tdir
22500
22501         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22502
22503         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22504         local facet=mds$((mdtidx + 1))
22505
22506         cancel_lru_locks mdc
22507         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22508         createmany -o $dom 1000
22509         lctl set_param -n mdc.*.stats=clear
22510         smalliomany -w $dom 1000 200
22511         get_mdc_stats $mdtidx
22512         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22513         # Each file has 1 open, 1 IO enqueues, total 2000
22514         # but now we have also +1 getxattr for security.capability, total 3000
22515         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22516         unlinkmany $dom 1000
22517
22518         cancel_lru_locks mdc
22519         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22520         createmany -o $dom 1000
22521         lctl set_param -n mdc.*.stats=clear
22522         smalliomany -w $dom 1000 200
22523         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22524         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22525         # for OPEN and IO lock.
22526         [ $((enq - enq_2)) -ge 1000 ] ||
22527                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22528         unlinkmany $dom 1000
22529         return 0
22530 }
22531 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22532
22533 cleanup_271def_tests() {
22534         trap 0
22535         rm -f $1
22536 }
22537
22538 test_271d() {
22539         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22540                 skip "Need MDS version at least 2.10.57"
22541
22542         local dom=$DIR/$tdir/dom
22543         local tmp=$TMP/$tfile
22544         trap "cleanup_271def_tests $tmp" EXIT
22545
22546         mkdir -p $DIR/$tdir
22547
22548         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22549
22550         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22551
22552         cancel_lru_locks mdc
22553         dd if=/dev/urandom of=$tmp bs=1000 count=1
22554         dd if=$tmp of=$dom bs=1000 count=1
22555         cancel_lru_locks mdc
22556
22557         cat /etc/hosts >> $tmp
22558         lctl set_param -n mdc.*.stats=clear
22559
22560         # append data to the same file it should update local page
22561         echo "Append to the same page"
22562         cat /etc/hosts >> $dom
22563         local num=$(get_mdc_stats $mdtidx ost_read)
22564         local ra=$(get_mdc_stats $mdtidx req_active)
22565         local rw=$(get_mdc_stats $mdtidx req_waittime)
22566
22567         [ -z $num ] || error "$num READ RPC occured"
22568         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22569         echo "... DONE"
22570
22571         # compare content
22572         cmp $tmp $dom || error "file miscompare"
22573
22574         cancel_lru_locks mdc
22575         lctl set_param -n mdc.*.stats=clear
22576
22577         echo "Open and read file"
22578         cat $dom > /dev/null
22579         local num=$(get_mdc_stats $mdtidx ost_read)
22580         local ra=$(get_mdc_stats $mdtidx req_active)
22581         local rw=$(get_mdc_stats $mdtidx req_waittime)
22582
22583         [ -z $num ] || error "$num READ RPC occured"
22584         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22585         echo "... DONE"
22586
22587         # compare content
22588         cmp $tmp $dom || error "file miscompare"
22589
22590         return 0
22591 }
22592 run_test 271d "DoM: read on open (1K file in reply buffer)"
22593
22594 test_271f() {
22595         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22596                 skip "Need MDS version at least 2.10.57"
22597
22598         local dom=$DIR/$tdir/dom
22599         local tmp=$TMP/$tfile
22600         trap "cleanup_271def_tests $tmp" EXIT
22601
22602         mkdir -p $DIR/$tdir
22603
22604         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22605
22606         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22607
22608         cancel_lru_locks mdc
22609         dd if=/dev/urandom of=$tmp bs=265000 count=1
22610         dd if=$tmp of=$dom bs=265000 count=1
22611         cancel_lru_locks mdc
22612         cat /etc/hosts >> $tmp
22613         lctl set_param -n mdc.*.stats=clear
22614
22615         echo "Append to the same page"
22616         cat /etc/hosts >> $dom
22617         local num=$(get_mdc_stats $mdtidx ost_read)
22618         local ra=$(get_mdc_stats $mdtidx req_active)
22619         local rw=$(get_mdc_stats $mdtidx req_waittime)
22620
22621         [ -z $num ] || error "$num READ RPC occured"
22622         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22623         echo "... DONE"
22624
22625         # compare content
22626         cmp $tmp $dom || error "file miscompare"
22627
22628         cancel_lru_locks mdc
22629         lctl set_param -n mdc.*.stats=clear
22630
22631         echo "Open and read file"
22632         cat $dom > /dev/null
22633         local num=$(get_mdc_stats $mdtidx ost_read)
22634         local ra=$(get_mdc_stats $mdtidx req_active)
22635         local rw=$(get_mdc_stats $mdtidx req_waittime)
22636
22637         [ -z $num ] && num=0
22638         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22639         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22640         echo "... DONE"
22641
22642         # compare content
22643         cmp $tmp $dom || error "file miscompare"
22644
22645         return 0
22646 }
22647 run_test 271f "DoM: read on open (200K file and read tail)"
22648
22649 test_271g() {
22650         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22651                 skip "Skipping due to old client or server version"
22652
22653         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22654         # to get layout
22655         $CHECKSTAT -t file $DIR1/$tfile
22656
22657         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22658         MULTIOP_PID=$!
22659         sleep 1
22660         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22661         $LCTL set_param fail_loc=0x80000314
22662         rm $DIR1/$tfile || error "Unlink fails"
22663         RC=$?
22664         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22665         [ $RC -eq 0 ] || error "Failed write to stale object"
22666 }
22667 run_test 271g "Discard DoM data vs client flush race"
22668
22669 test_272a() {
22670         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22671                 skip "Need MDS version at least 2.11.50"
22672
22673         local dom=$DIR/$tdir/dom
22674         mkdir -p $DIR/$tdir
22675
22676         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22677         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22678                 error "failed to write data into $dom"
22679         local old_md5=$(md5sum $dom)
22680
22681         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22682                 error "failed to migrate to the same DoM component"
22683
22684         local new_md5=$(md5sum $dom)
22685
22686         [ "$old_md5" == "$new_md5" ] ||
22687                 error "md5sum differ: $old_md5, $new_md5"
22688
22689         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22690                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22691 }
22692 run_test 272a "DoM migration: new layout with the same DOM component"
22693
22694 test_272b() {
22695         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22696                 skip "Need MDS version at least 2.11.50"
22697
22698         local dom=$DIR/$tdir/dom
22699         mkdir -p $DIR/$tdir
22700         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22701
22702         local mdtidx=$($LFS getstripe -m $dom)
22703         local mdtname=MDT$(printf %04x $mdtidx)
22704         local facet=mds$((mdtidx + 1))
22705
22706         local mdtfree1=$(do_facet $facet \
22707                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22708         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22709                 error "failed to write data into $dom"
22710         local old_md5=$(md5sum $dom)
22711         cancel_lru_locks mdc
22712         local mdtfree1=$(do_facet $facet \
22713                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22714
22715         $LFS migrate -c2 $dom ||
22716                 error "failed to migrate to the new composite layout"
22717         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22718                 error "MDT stripe was not removed"
22719
22720         cancel_lru_locks mdc
22721         local new_md5=$(md5sum $dom)
22722         [ "$old_md5" == "$new_md5" ] ||
22723                 error "$old_md5 != $new_md5"
22724
22725         # Skip free space checks with ZFS
22726         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22727                 local mdtfree2=$(do_facet $facet \
22728                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22729                 [ $mdtfree2 -gt $mdtfree1 ] ||
22730                         error "MDT space is not freed after migration"
22731         fi
22732         return 0
22733 }
22734 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22735
22736 test_272c() {
22737         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22738                 skip "Need MDS version at least 2.11.50"
22739
22740         local dom=$DIR/$tdir/$tfile
22741         mkdir -p $DIR/$tdir
22742         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22743
22744         local mdtidx=$($LFS getstripe -m $dom)
22745         local mdtname=MDT$(printf %04x $mdtidx)
22746         local facet=mds$((mdtidx + 1))
22747
22748         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22749                 error "failed to write data into $dom"
22750         local old_md5=$(md5sum $dom)
22751         cancel_lru_locks mdc
22752         local mdtfree1=$(do_facet $facet \
22753                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22754
22755         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22756                 error "failed to migrate to the new composite layout"
22757         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22758                 error "MDT stripe was not removed"
22759
22760         cancel_lru_locks mdc
22761         local new_md5=$(md5sum $dom)
22762         [ "$old_md5" == "$new_md5" ] ||
22763                 error "$old_md5 != $new_md5"
22764
22765         # Skip free space checks with ZFS
22766         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22767                 local mdtfree2=$(do_facet $facet \
22768                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22769                 [ $mdtfree2 -gt $mdtfree1 ] ||
22770                         error "MDS space is not freed after migration"
22771         fi
22772         return 0
22773 }
22774 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22775
22776 test_272d() {
22777         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22778                 skip "Need MDS version at least 2.12.55"
22779
22780         local dom=$DIR/$tdir/$tfile
22781         mkdir -p $DIR/$tdir
22782         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22783
22784         local mdtidx=$($LFS getstripe -m $dom)
22785         local mdtname=MDT$(printf %04x $mdtidx)
22786         local facet=mds$((mdtidx + 1))
22787
22788         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22789                 error "failed to write data into $dom"
22790         local old_md5=$(md5sum $dom)
22791         cancel_lru_locks mdc
22792         local mdtfree1=$(do_facet $facet \
22793                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22794
22795         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22796                 error "failed mirroring to the new composite layout"
22797         $LFS mirror resync $dom ||
22798                 error "failed mirror resync"
22799         $LFS mirror split --mirror-id 1 -d $dom ||
22800                 error "failed mirror split"
22801
22802         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22803                 error "MDT stripe was not removed"
22804
22805         cancel_lru_locks mdc
22806         local new_md5=$(md5sum $dom)
22807         [ "$old_md5" == "$new_md5" ] ||
22808                 error "$old_md5 != $new_md5"
22809
22810         # Skip free space checks with ZFS
22811         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22812                 local mdtfree2=$(do_facet $facet \
22813                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22814                 [ $mdtfree2 -gt $mdtfree1 ] ||
22815                         error "MDS space is not freed after DOM mirror deletion"
22816         fi
22817         return 0
22818 }
22819 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22820
22821 test_272e() {
22822         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22823                 skip "Need MDS version at least 2.12.55"
22824
22825         local dom=$DIR/$tdir/$tfile
22826         mkdir -p $DIR/$tdir
22827         $LFS setstripe -c 2 $dom
22828
22829         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22830                 error "failed to write data into $dom"
22831         local old_md5=$(md5sum $dom)
22832         cancel_lru_locks
22833
22834         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22835                 error "failed mirroring to the DOM layout"
22836         $LFS mirror resync $dom ||
22837                 error "failed mirror resync"
22838         $LFS mirror split --mirror-id 1 -d $dom ||
22839                 error "failed mirror split"
22840
22841         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22842                 error "MDT stripe wasn't set"
22843
22844         cancel_lru_locks
22845         local new_md5=$(md5sum $dom)
22846         [ "$old_md5" == "$new_md5" ] ||
22847                 error "$old_md5 != $new_md5"
22848
22849         return 0
22850 }
22851 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22852
22853 test_272f() {
22854         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22855                 skip "Need MDS version at least 2.12.55"
22856
22857         local dom=$DIR/$tdir/$tfile
22858         mkdir -p $DIR/$tdir
22859         $LFS setstripe -c 2 $dom
22860
22861         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22862                 error "failed to write data into $dom"
22863         local old_md5=$(md5sum $dom)
22864         cancel_lru_locks
22865
22866         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22867                 error "failed migrating to the DOM file"
22868
22869         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22870                 error "MDT stripe wasn't set"
22871
22872         cancel_lru_locks
22873         local new_md5=$(md5sum $dom)
22874         [ "$old_md5" != "$new_md5" ] &&
22875                 error "$old_md5 != $new_md5"
22876
22877         return 0
22878 }
22879 run_test 272f "DoM migration: OST-striped file to DOM file"
22880
22881 test_273a() {
22882         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22883                 skip "Need MDS version at least 2.11.50"
22884
22885         # Layout swap cannot be done if either file has DOM component,
22886         # this will never be supported, migration should be used instead
22887
22888         local dom=$DIR/$tdir/$tfile
22889         mkdir -p $DIR/$tdir
22890
22891         $LFS setstripe -c2 ${dom}_plain
22892         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22893         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22894                 error "can swap layout with DoM component"
22895         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22896                 error "can swap layout with DoM component"
22897
22898         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22899         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22900                 error "can swap layout with DoM component"
22901         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22902                 error "can swap layout with DoM component"
22903         return 0
22904 }
22905 run_test 273a "DoM: layout swapping should fail with DOM"
22906
22907 test_273b() {
22908         mkdir -p $DIR/$tdir
22909         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22910
22911 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22912         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22913
22914         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22915 }
22916 run_test 273b "DoM: race writeback and object destroy"
22917
22918 test_275() {
22919         remote_ost_nodsh && skip "remote OST with nodsh"
22920         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22921                 skip "Need OST version >= 2.10.57"
22922
22923         local file=$DIR/$tfile
22924         local oss
22925
22926         oss=$(comma_list $(osts_nodes))
22927
22928         dd if=/dev/urandom of=$file bs=1M count=2 ||
22929                 error "failed to create a file"
22930         cancel_lru_locks osc
22931
22932         #lock 1
22933         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22934                 error "failed to read a file"
22935
22936 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22937         $LCTL set_param fail_loc=0x8000031f
22938
22939         cancel_lru_locks osc &
22940         sleep 1
22941
22942 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22943         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22944         #IO takes another lock, but matches the PENDING one
22945         #and places it to the IO RPC
22946         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22947                 error "failed to read a file with PENDING lock"
22948 }
22949 run_test 275 "Read on a canceled duplicate lock"
22950
22951 test_276() {
22952         remote_ost_nodsh && skip "remote OST with nodsh"
22953         local pid
22954
22955         do_facet ost1 "(while true; do \
22956                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22957                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22958         pid=$!
22959
22960         for LOOP in $(seq 20); do
22961                 stop ost1
22962                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22963         done
22964         kill -9 $pid
22965         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
22966                 rm $TMP/sanity_276_pid"
22967 }
22968 run_test 276 "Race between mount and obd_statfs"
22969
22970 test_277() {
22971         $LCTL set_param ldlm.namespaces.*.lru_size=0
22972         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22973         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22974                         grep ^used_mb | awk '{print $2}')
22975         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
22976         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
22977                 oflag=direct conv=notrunc
22978         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22979                         grep ^used_mb | awk '{print $2}')
22980         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
22981 }
22982 run_test 277 "Direct IO shall drop page cache"
22983
22984 test_278() {
22985         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22986         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22987         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
22988                 skip "needs the same host for mdt1 mdt2" && return
22989
22990         local pid1
22991         local pid2
22992
22993 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22994         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22995         stop mds2 &
22996         pid2=$!
22997
22998         stop mds1
22999
23000         echo "Starting MDTs"
23001         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23002         wait $pid2
23003 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23004 #will return NULL
23005         do_facet mds2 $LCTL set_param fail_loc=0
23006
23007         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23008         wait_recovery_complete mds2
23009 }
23010 run_test 278 "Race starting MDS between MDTs stop/start"
23011
23012 test_280() {
23013         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23014                 skip "Need MGS version at least 2.13.52"
23015         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23016         combined_mgs_mds || skip "needs combined MGS/MDT"
23017
23018         umount_client $MOUNT
23019 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23020         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23021
23022         mount_client $MOUNT &
23023         sleep 1
23024         stop mgs || error "stop mgs failed"
23025         #for a race mgs would crash
23026         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23027         # make sure we unmount client before remounting
23028         wait
23029         umount_client $MOUNT
23030         mount_client $MOUNT || error "mount client failed"
23031 }
23032 run_test 280 "Race between MGS umount and client llog processing"
23033
23034 cleanup_test_300() {
23035         trap 0
23036         umask $SAVE_UMASK
23037 }
23038 test_striped_dir() {
23039         local mdt_index=$1
23040         local stripe_count
23041         local stripe_index
23042
23043         mkdir -p $DIR/$tdir
23044
23045         SAVE_UMASK=$(umask)
23046         trap cleanup_test_300 RETURN EXIT
23047
23048         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23049                                                 $DIR/$tdir/striped_dir ||
23050                 error "set striped dir error"
23051
23052         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23053         [ "$mode" = "755" ] || error "expect 755 got $mode"
23054
23055         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23056                 error "getdirstripe failed"
23057         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23058         if [ "$stripe_count" != "2" ]; then
23059                 error "1:stripe_count is $stripe_count, expect 2"
23060         fi
23061         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23062         if [ "$stripe_count" != "2" ]; then
23063                 error "2:stripe_count is $stripe_count, expect 2"
23064         fi
23065
23066         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23067         if [ "$stripe_index" != "$mdt_index" ]; then
23068                 error "stripe_index is $stripe_index, expect $mdt_index"
23069         fi
23070
23071         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23072                 error "nlink error after create striped dir"
23073
23074         mkdir $DIR/$tdir/striped_dir/a
23075         mkdir $DIR/$tdir/striped_dir/b
23076
23077         stat $DIR/$tdir/striped_dir/a ||
23078                 error "create dir under striped dir failed"
23079         stat $DIR/$tdir/striped_dir/b ||
23080                 error "create dir under striped dir failed"
23081
23082         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23083                 error "nlink error after mkdir"
23084
23085         rmdir $DIR/$tdir/striped_dir/a
23086         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23087                 error "nlink error after rmdir"
23088
23089         rmdir $DIR/$tdir/striped_dir/b
23090         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23091                 error "nlink error after rmdir"
23092
23093         chattr +i $DIR/$tdir/striped_dir
23094         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23095                 error "immutable flags not working under striped dir!"
23096         chattr -i $DIR/$tdir/striped_dir
23097
23098         rmdir $DIR/$tdir/striped_dir ||
23099                 error "rmdir striped dir error"
23100
23101         cleanup_test_300
23102
23103         true
23104 }
23105
23106 test_300a() {
23107         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23108                 skip "skipped for lustre < 2.7.0"
23109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23110         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23111
23112         test_striped_dir 0 || error "failed on striped dir on MDT0"
23113         test_striped_dir 1 || error "failed on striped dir on MDT0"
23114 }
23115 run_test 300a "basic striped dir sanity test"
23116
23117 test_300b() {
23118         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23119                 skip "skipped for lustre < 2.7.0"
23120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23121         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23122
23123         local i
23124         local mtime1
23125         local mtime2
23126         local mtime3
23127
23128         test_mkdir $DIR/$tdir || error "mkdir fail"
23129         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23130                 error "set striped dir error"
23131         for i in {0..9}; do
23132                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23133                 sleep 1
23134                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23135                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23136                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23137                 sleep 1
23138                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23139                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23140                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23141         done
23142         true
23143 }
23144 run_test 300b "check ctime/mtime for striped dir"
23145
23146 test_300c() {
23147         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23148                 skip "skipped for lustre < 2.7.0"
23149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23150         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23151
23152         local file_count
23153
23154         mkdir_on_mdt0 $DIR/$tdir
23155         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23156                 error "set striped dir error"
23157
23158         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23159                 error "chown striped dir failed"
23160
23161         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23162                 error "create 5k files failed"
23163
23164         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23165
23166         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23167
23168         rm -rf $DIR/$tdir
23169 }
23170 run_test 300c "chown && check ls under striped directory"
23171
23172 test_300d() {
23173         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23174                 skip "skipped for lustre < 2.7.0"
23175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23176         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23177
23178         local stripe_count
23179         local file
23180
23181         mkdir -p $DIR/$tdir
23182         $LFS setstripe -c 2 $DIR/$tdir
23183
23184         #local striped directory
23185         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23186                 error "set striped dir error"
23187         #look at the directories for debug purposes
23188         ls -l $DIR/$tdir
23189         $LFS getdirstripe $DIR/$tdir
23190         ls -l $DIR/$tdir/striped_dir
23191         $LFS getdirstripe $DIR/$tdir/striped_dir
23192         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23193                 error "create 10 files failed"
23194
23195         #remote striped directory
23196         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23197                 error "set striped dir error"
23198         #look at the directories for debug purposes
23199         ls -l $DIR/$tdir
23200         $LFS getdirstripe $DIR/$tdir
23201         ls -l $DIR/$tdir/remote_striped_dir
23202         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23203         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23204                 error "create 10 files failed"
23205
23206         for file in $(find $DIR/$tdir); do
23207                 stripe_count=$($LFS getstripe -c $file)
23208                 [ $stripe_count -eq 2 ] ||
23209                         error "wrong stripe $stripe_count for $file"
23210         done
23211
23212         rm -rf $DIR/$tdir
23213 }
23214 run_test 300d "check default stripe under striped directory"
23215
23216 test_300e() {
23217         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23218                 skip "Need MDS version at least 2.7.55"
23219         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23220         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23221
23222         local stripe_count
23223         local file
23224
23225         mkdir -p $DIR/$tdir
23226
23227         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23228                 error "set striped dir error"
23229
23230         touch $DIR/$tdir/striped_dir/a
23231         touch $DIR/$tdir/striped_dir/b
23232         touch $DIR/$tdir/striped_dir/c
23233
23234         mkdir $DIR/$tdir/striped_dir/dir_a
23235         mkdir $DIR/$tdir/striped_dir/dir_b
23236         mkdir $DIR/$tdir/striped_dir/dir_c
23237
23238         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23239                 error "set striped adir under striped dir error"
23240
23241         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23242                 error "set striped bdir under striped dir error"
23243
23244         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23245                 error "set striped cdir under striped dir error"
23246
23247         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23248                 error "rename dir under striped dir fails"
23249
23250         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23251                 error "rename dir under different stripes fails"
23252
23253         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23254                 error "rename file under striped dir should succeed"
23255
23256         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23257                 error "rename dir under striped dir should succeed"
23258
23259         rm -rf $DIR/$tdir
23260 }
23261 run_test 300e "check rename under striped directory"
23262
23263 test_300f() {
23264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23265         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23266         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23267                 skip "Need MDS version at least 2.7.55"
23268
23269         local stripe_count
23270         local file
23271
23272         rm -rf $DIR/$tdir
23273         mkdir -p $DIR/$tdir
23274
23275         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23276                 error "set striped dir error"
23277
23278         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23279                 error "set striped dir error"
23280
23281         touch $DIR/$tdir/striped_dir/a
23282         mkdir $DIR/$tdir/striped_dir/dir_a
23283         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23284                 error "create striped dir under striped dir fails"
23285
23286         touch $DIR/$tdir/striped_dir1/b
23287         mkdir $DIR/$tdir/striped_dir1/dir_b
23288         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23289                 error "create striped dir under striped dir fails"
23290
23291         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23292                 error "rename dir under different striped dir should fail"
23293
23294         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23295                 error "rename striped dir under diff striped dir should fail"
23296
23297         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23298                 error "rename file under diff striped dirs fails"
23299
23300         rm -rf $DIR/$tdir
23301 }
23302 run_test 300f "check rename cross striped directory"
23303
23304 test_300_check_default_striped_dir()
23305 {
23306         local dirname=$1
23307         local default_count=$2
23308         local default_index=$3
23309         local stripe_count
23310         local stripe_index
23311         local dir_stripe_index
23312         local dir
23313
23314         echo "checking $dirname $default_count $default_index"
23315         $LFS setdirstripe -D -c $default_count -i $default_index \
23316                                 -H all_char $DIR/$tdir/$dirname ||
23317                 error "set default stripe on striped dir error"
23318         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23319         [ $stripe_count -eq $default_count ] ||
23320                 error "expect $default_count get $stripe_count for $dirname"
23321
23322         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23323         [ $stripe_index -eq $default_index ] ||
23324                 error "expect $default_index get $stripe_index for $dirname"
23325
23326         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23327                                                 error "create dirs failed"
23328
23329         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23330         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23331         for dir in $(find $DIR/$tdir/$dirname/*); do
23332                 stripe_count=$($LFS getdirstripe -c $dir)
23333                 (( $stripe_count == $default_count )) ||
23334                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23335                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23336                 error "stripe count $default_count != $stripe_count for $dir"
23337
23338                 stripe_index=$($LFS getdirstripe -i $dir)
23339                 [ $default_index -eq -1 ] ||
23340                         [ $stripe_index -eq $default_index ] ||
23341                         error "$stripe_index != $default_index for $dir"
23342
23343                 #check default stripe
23344                 stripe_count=$($LFS getdirstripe -D -c $dir)
23345                 [ $stripe_count -eq $default_count ] ||
23346                 error "default count $default_count != $stripe_count for $dir"
23347
23348                 stripe_index=$($LFS getdirstripe -D -i $dir)
23349                 [ $stripe_index -eq $default_index ] ||
23350                 error "default index $default_index != $stripe_index for $dir"
23351         done
23352         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23353 }
23354
23355 test_300g() {
23356         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23357         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23358                 skip "Need MDS version at least 2.7.55"
23359
23360         local dir
23361         local stripe_count
23362         local stripe_index
23363
23364         mkdir_on_mdt0 $DIR/$tdir
23365         mkdir $DIR/$tdir/normal_dir
23366
23367         #Checking when client cache stripe index
23368         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23369         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23370                 error "create striped_dir failed"
23371
23372         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23373                 error "create dir0 fails"
23374         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23375         [ $stripe_index -eq 0 ] ||
23376                 error "dir0 expect index 0 got $stripe_index"
23377
23378         mkdir $DIR/$tdir/striped_dir/dir1 ||
23379                 error "create dir1 fails"
23380         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23381         [ $stripe_index -eq 1 ] ||
23382                 error "dir1 expect index 1 got $stripe_index"
23383
23384         #check default stripe count/stripe index
23385         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23386         test_300_check_default_striped_dir normal_dir 1 0
23387         test_300_check_default_striped_dir normal_dir -1 1
23388         test_300_check_default_striped_dir normal_dir 2 -1
23389
23390         #delete default stripe information
23391         echo "delete default stripeEA"
23392         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23393                 error "set default stripe on striped dir error"
23394
23395         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23396         for dir in $(find $DIR/$tdir/normal_dir/*); do
23397                 stripe_count=$($LFS getdirstripe -c $dir)
23398                 [ $stripe_count -eq 0 ] ||
23399                         error "expect 1 get $stripe_count for $dir"
23400         done
23401 }
23402 run_test 300g "check default striped directory for normal directory"
23403
23404 test_300h() {
23405         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23406         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23407                 skip "Need MDS version at least 2.7.55"
23408
23409         local dir
23410         local stripe_count
23411
23412         mkdir $DIR/$tdir
23413         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23414                 error "set striped dir error"
23415
23416         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23417         test_300_check_default_striped_dir striped_dir 1 0
23418         test_300_check_default_striped_dir striped_dir -1 1
23419         test_300_check_default_striped_dir striped_dir 2 -1
23420
23421         #delete default stripe information
23422         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23423                 error "set default stripe on striped dir error"
23424
23425         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23426         for dir in $(find $DIR/$tdir/striped_dir/*); do
23427                 stripe_count=$($LFS getdirstripe -c $dir)
23428                 [ $stripe_count -eq 0 ] ||
23429                         error "expect 1 get $stripe_count for $dir"
23430         done
23431 }
23432 run_test 300h "check default striped directory for striped directory"
23433
23434 test_300i() {
23435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23436         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23437         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23438                 skip "Need MDS version at least 2.7.55"
23439
23440         local stripe_count
23441         local file
23442
23443         mkdir $DIR/$tdir
23444
23445         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23446                 error "set striped dir error"
23447
23448         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23449                 error "create files under striped dir failed"
23450
23451         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23452                 error "set striped hashdir error"
23453
23454         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23455                 error "create dir0 under hash dir failed"
23456         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23457                 error "create dir1 under hash dir failed"
23458         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23459                 error "create dir2 under hash dir failed"
23460
23461         # unfortunately, we need to umount to clear dir layout cache for now
23462         # once we fully implement dir layout, we can drop this
23463         umount_client $MOUNT || error "umount failed"
23464         mount_client $MOUNT || error "mount failed"
23465
23466         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23467         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23468         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
23469
23470         #set the stripe to be unknown hash type
23471         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
23472         $LCTL set_param fail_loc=0x1901
23473         for ((i = 0; i < 10; i++)); do
23474                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23475                         error "stat f-$i failed"
23476                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23477         done
23478
23479         touch $DIR/$tdir/striped_dir/f0 &&
23480                 error "create under striped dir with unknown hash should fail"
23481
23482         $LCTL set_param fail_loc=0
23483
23484         umount_client $MOUNT || error "umount failed"
23485         mount_client $MOUNT || error "mount failed"
23486
23487         return 0
23488 }
23489 run_test 300i "client handle unknown hash type striped directory"
23490
23491 test_300j() {
23492         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23494         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23495                 skip "Need MDS version at least 2.7.55"
23496
23497         local stripe_count
23498         local file
23499
23500         mkdir $DIR/$tdir
23501
23502         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23503         $LCTL set_param fail_loc=0x1702
23504         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23505                 error "set striped dir error"
23506
23507         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23508                 error "create files under striped dir failed"
23509
23510         $LCTL set_param fail_loc=0
23511
23512         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23513
23514         return 0
23515 }
23516 run_test 300j "test large update record"
23517
23518 test_300k() {
23519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23520         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23521         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23522                 skip "Need MDS version at least 2.7.55"
23523
23524         # this test needs a huge transaction
23525         local kb
23526         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23527              osd*.$FSNAME-MDT0000.kbytestotal")
23528         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23529
23530         local stripe_count
23531         local file
23532
23533         mkdir $DIR/$tdir
23534
23535         #define OBD_FAIL_LARGE_STRIPE   0x1703
23536         $LCTL set_param fail_loc=0x1703
23537         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23538                 error "set striped dir error"
23539         $LCTL set_param fail_loc=0
23540
23541         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23542                 error "getstripeddir fails"
23543         rm -rf $DIR/$tdir/striped_dir ||
23544                 error "unlink striped dir fails"
23545
23546         return 0
23547 }
23548 run_test 300k "test large striped directory"
23549
23550 test_300l() {
23551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23552         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23553         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23554                 skip "Need MDS version at least 2.7.55"
23555
23556         local stripe_index
23557
23558         test_mkdir -p $DIR/$tdir/striped_dir
23559         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23560                         error "chown $RUNAS_ID failed"
23561         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23562                 error "set default striped dir failed"
23563
23564         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23565         $LCTL set_param fail_loc=0x80000158
23566         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23567
23568         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23569         [ $stripe_index -eq 1 ] ||
23570                 error "expect 1 get $stripe_index for $dir"
23571 }
23572 run_test 300l "non-root user to create dir under striped dir with stale layout"
23573
23574 test_300m() {
23575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23576         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23577         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23578                 skip "Need MDS version at least 2.7.55"
23579
23580         mkdir -p $DIR/$tdir/striped_dir
23581         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23582                 error "set default stripes dir error"
23583
23584         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23585
23586         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23587         [ $stripe_count -eq 0 ] ||
23588                         error "expect 0 get $stripe_count for a"
23589
23590         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23591                 error "set default stripes dir error"
23592
23593         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23594
23595         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23596         [ $stripe_count -eq 0 ] ||
23597                         error "expect 0 get $stripe_count for b"
23598
23599         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23600                 error "set default stripes dir error"
23601
23602         mkdir $DIR/$tdir/striped_dir/c &&
23603                 error "default stripe_index is invalid, mkdir c should fails"
23604
23605         rm -rf $DIR/$tdir || error "rmdir fails"
23606 }
23607 run_test 300m "setstriped directory on single MDT FS"
23608
23609 cleanup_300n() {
23610         local list=$(comma_list $(mdts_nodes))
23611
23612         trap 0
23613         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23614 }
23615
23616 test_300n() {
23617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23618         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23619         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23620                 skip "Need MDS version at least 2.7.55"
23621         remote_mds_nodsh && skip "remote MDS with nodsh"
23622
23623         local stripe_index
23624         local list=$(comma_list $(mdts_nodes))
23625
23626         trap cleanup_300n RETURN EXIT
23627         mkdir -p $DIR/$tdir
23628         chmod 777 $DIR/$tdir
23629         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23630                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23631                 error "create striped dir succeeds with gid=0"
23632
23633         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23634         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23635                 error "create striped dir fails with gid=-1"
23636
23637         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23638         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23639                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23640                 error "set default striped dir succeeds with gid=0"
23641
23642
23643         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23644         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23645                 error "set default striped dir fails with gid=-1"
23646
23647
23648         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23649         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23650                                         error "create test_dir fails"
23651         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23652                                         error "create test_dir1 fails"
23653         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23654                                         error "create test_dir2 fails"
23655         cleanup_300n
23656 }
23657 run_test 300n "non-root user to create dir under striped dir with default EA"
23658
23659 test_300o() {
23660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23661         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23662         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23663                 skip "Need MDS version at least 2.7.55"
23664
23665         local numfree1
23666         local numfree2
23667
23668         mkdir -p $DIR/$tdir
23669
23670         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23671         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23672         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23673                 skip "not enough free inodes $numfree1 $numfree2"
23674         fi
23675
23676         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23677         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23678         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23679                 skip "not enough free space $numfree1 $numfree2"
23680         fi
23681
23682         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23683                 error "setdirstripe fails"
23684
23685         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23686                 error "create dirs fails"
23687
23688         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23689         ls $DIR/$tdir/striped_dir > /dev/null ||
23690                 error "ls striped dir fails"
23691         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23692                 error "unlink big striped dir fails"
23693 }
23694 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23695
23696 test_300p() {
23697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23698         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23699         remote_mds_nodsh && skip "remote MDS with nodsh"
23700
23701         mkdir_on_mdt0 $DIR/$tdir
23702
23703         #define OBD_FAIL_OUT_ENOSPC     0x1704
23704         do_facet mds2 lctl set_param fail_loc=0x80001704
23705         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23706                  && error "create striped directory should fail"
23707
23708         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23709
23710         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23711         true
23712 }
23713 run_test 300p "create striped directory without space"
23714
23715 test_300q() {
23716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23717         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23718
23719         local fd=$(free_fd)
23720         local cmd="exec $fd<$tdir"
23721         cd $DIR
23722         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23723         eval $cmd
23724         cmd="exec $fd<&-"
23725         trap "eval $cmd" EXIT
23726         cd $tdir || error "cd $tdir fails"
23727         rmdir  ../$tdir || error "rmdir $tdir fails"
23728         mkdir local_dir && error "create dir succeeds"
23729         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23730         eval $cmd
23731         return 0
23732 }
23733 run_test 300q "create remote directory under orphan directory"
23734
23735 test_300r() {
23736         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23737                 skip "Need MDS version at least 2.7.55" && return
23738         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23739
23740         mkdir $DIR/$tdir
23741
23742         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23743                 error "set striped dir error"
23744
23745         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23746                 error "getstripeddir fails"
23747
23748         local stripe_count
23749         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23750                       awk '/lmv_stripe_count:/ { print $2 }')
23751
23752         [ $MDSCOUNT -ne $stripe_count ] &&
23753                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23754
23755         rm -rf $DIR/$tdir/striped_dir ||
23756                 error "unlink striped dir fails"
23757 }
23758 run_test 300r "test -1 striped directory"
23759
23760 test_300s_helper() {
23761         local count=$1
23762
23763         local stripe_dir=$DIR/$tdir/striped_dir.$count
23764
23765         $LFS mkdir -c $count $stripe_dir ||
23766                 error "lfs mkdir -c error"
23767
23768         $LFS getdirstripe $stripe_dir ||
23769                 error "lfs getdirstripe fails"
23770
23771         local stripe_count
23772         stripe_count=$($LFS getdirstripe $stripe_dir |
23773                       awk '/lmv_stripe_count:/ { print $2 }')
23774
23775         [ $count -ne $stripe_count ] &&
23776                 error_noexit "bad stripe count $stripe_count expected $count"
23777
23778         local dupe_stripes
23779         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23780                 awk '/0x/ {count[$1] += 1}; END {
23781                         for (idx in count) {
23782                                 if (count[idx]>1) {
23783                                         print "index " idx " count " count[idx]
23784                                 }
23785                         }
23786                 }')
23787
23788         if [[ -n "$dupe_stripes" ]] ; then
23789                 lfs getdirstripe $stripe_dir
23790                 error_noexit "Dupe MDT above: $dupe_stripes "
23791         fi
23792
23793         rm -rf $stripe_dir ||
23794                 error_noexit "unlink $stripe_dir fails"
23795 }
23796
23797 test_300s() {
23798         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23799                 skip "Need MDS version at least 2.7.55" && return
23800         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23801
23802         mkdir $DIR/$tdir
23803         for count in $(seq 2 $MDSCOUNT); do
23804                 test_300s_helper $count
23805         done
23806 }
23807 run_test 300s "test lfs mkdir -c without -i"
23808
23809 test_300t() {
23810         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
23811                 skip "need MDS 2.14.55 or later"
23812         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
23813
23814         local testdir="$DIR/$tdir/striped_dir"
23815         local dir1=$testdir/dir1
23816         local dir2=$testdir/dir2
23817
23818         mkdir -p $testdir
23819
23820         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
23821                 error "failed to set default stripe count for $testdir"
23822
23823         mkdir $dir1
23824         local stripe_count=$($LFS getdirstripe -c $dir1)
23825
23826         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
23827
23828         local max_count=$((MDSCOUNT - 1))
23829         local mdts=$(comma_list $(mdts_nodes))
23830
23831         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
23832         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
23833
23834         mkdir $dir2
23835         stripe_count=$($LFS getdirstripe -c $dir2)
23836
23837         (( $stripe_count == $max_count )) || error "wrong stripe count"
23838 }
23839 run_test 300t "test max_mdt_stripecount"
23840
23841 prepare_remote_file() {
23842         mkdir $DIR/$tdir/src_dir ||
23843                 error "create remote source failed"
23844
23845         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23846                  error "cp to remote source failed"
23847         touch $DIR/$tdir/src_dir/a
23848
23849         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23850                 error "create remote target dir failed"
23851
23852         touch $DIR/$tdir/tgt_dir/b
23853
23854         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23855                 error "rename dir cross MDT failed!"
23856
23857         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23858                 error "src_child still exists after rename"
23859
23860         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23861                 error "missing file(a) after rename"
23862
23863         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
23864                 error "diff after rename"
23865 }
23866
23867 test_310a() {
23868         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23870
23871         local remote_file=$DIR/$tdir/tgt_dir/b
23872
23873         mkdir -p $DIR/$tdir
23874
23875         prepare_remote_file || error "prepare remote file failed"
23876
23877         #open-unlink file
23878         $OPENUNLINK $remote_file $remote_file ||
23879                 error "openunlink $remote_file failed"
23880         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23881 }
23882 run_test 310a "open unlink remote file"
23883
23884 test_310b() {
23885         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23887
23888         local remote_file=$DIR/$tdir/tgt_dir/b
23889
23890         mkdir -p $DIR/$tdir
23891
23892         prepare_remote_file || error "prepare remote file failed"
23893
23894         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23895         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23896         $CHECKSTAT -t file $remote_file || error "check file failed"
23897 }
23898 run_test 310b "unlink remote file with multiple links while open"
23899
23900 test_310c() {
23901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23902         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23903
23904         local remote_file=$DIR/$tdir/tgt_dir/b
23905
23906         mkdir -p $DIR/$tdir
23907
23908         prepare_remote_file || error "prepare remote file failed"
23909
23910         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23911         multiop_bg_pause $remote_file O_uc ||
23912                         error "mulitop failed for remote file"
23913         MULTIPID=$!
23914         $MULTIOP $DIR/$tfile Ouc
23915         kill -USR1 $MULTIPID
23916         wait $MULTIPID
23917 }
23918 run_test 310c "open-unlink remote file with multiple links"
23919
23920 #LU-4825
23921 test_311() {
23922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23923         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23924         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23925                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23926         remote_mds_nodsh && skip "remote MDS with nodsh"
23927
23928         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23929         local mdts=$(comma_list $(mdts_nodes))
23930
23931         mkdir -p $DIR/$tdir
23932         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23933         createmany -o $DIR/$tdir/$tfile. 1000
23934
23935         # statfs data is not real time, let's just calculate it
23936         old_iused=$((old_iused + 1000))
23937
23938         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23939                         osp.*OST0000*MDT0000.create_count")
23940         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23941                                 osp.*OST0000*MDT0000.max_create_count")
23942         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23943
23944         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23945         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23946         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23947
23948         unlinkmany $DIR/$tdir/$tfile. 1000
23949
23950         do_nodes $mdts "$LCTL set_param -n \
23951                         osp.*OST0000*.max_create_count=$max_count"
23952         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23953                 do_nodes $mdts "$LCTL set_param -n \
23954                                 osp.*OST0000*.create_count=$count"
23955         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23956                         grep "=0" && error "create_count is zero"
23957
23958         local new_iused
23959         for i in $(seq 120); do
23960                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23961                 # system may be too busy to destroy all objs in time, use
23962                 # a somewhat small value to not fail autotest
23963                 [ $((old_iused - new_iused)) -gt 400 ] && break
23964                 sleep 1
23965         done
23966
23967         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
23968         [ $((old_iused - new_iused)) -gt 400 ] ||
23969                 error "objs not destroyed after unlink"
23970 }
23971 run_test 311 "disable OSP precreate, and unlink should destroy objs"
23972
23973 zfs_oid_to_objid()
23974 {
23975         local ost=$1
23976         local objid=$2
23977
23978         local vdevdir=$(dirname $(facet_vdevice $ost))
23979         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
23980         local zfs_zapid=$(do_facet $ost $cmd |
23981                           grep -w "/O/0/d$((objid%32))" -C 5 |
23982                           awk '/Object/{getline; print $1}')
23983         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
23984                           awk "/$objid = /"'{printf $3}')
23985
23986         echo $zfs_objid
23987 }
23988
23989 zfs_object_blksz() {
23990         local ost=$1
23991         local objid=$2
23992
23993         local vdevdir=$(dirname $(facet_vdevice $ost))
23994         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
23995         local blksz=$(do_facet $ost $cmd $objid |
23996                       awk '/dblk/{getline; printf $4}')
23997
23998         case "${blksz: -1}" in
23999                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24000                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24001                 *) ;;
24002         esac
24003
24004         echo $blksz
24005 }
24006
24007 test_312() { # LU-4856
24008         remote_ost_nodsh && skip "remote OST with nodsh"
24009         [ "$ost1_FSTYPE" = "zfs" ] ||
24010                 skip_env "the test only applies to zfs"
24011
24012         local max_blksz=$(do_facet ost1 \
24013                           $ZFS get -p recordsize $(facet_device ost1) |
24014                           awk '!/VALUE/{print $3}')
24015
24016         # to make life a little bit easier
24017         $LFS mkdir -c 1 -i 0 $DIR/$tdir
24018         $LFS setstripe -c 1 -i 0 $DIR/$tdir
24019
24020         local tf=$DIR/$tdir/$tfile
24021         touch $tf
24022         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24023
24024         # Get ZFS object id
24025         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24026         # block size change by sequential overwrite
24027         local bs
24028
24029         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24030                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24031
24032                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
24033                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
24034         done
24035         rm -f $tf
24036
24037         # block size change by sequential append write
24038         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24039         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24040         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24041         local count
24042
24043         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24044                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24045                         oflag=sync conv=notrunc
24046
24047                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
24048                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
24049                         error "blksz error, actual $blksz, " \
24050                                 "expected: 2 * $count * $PAGE_SIZE"
24051         done
24052         rm -f $tf
24053
24054         # random write
24055         touch $tf
24056         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24057         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24058
24059         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24060         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24061         [ $blksz -eq $PAGE_SIZE ] ||
24062                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24063
24064         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24065         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24066         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
24067
24068         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24069         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24070         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
24071 }
24072 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24073
24074 test_313() {
24075         remote_ost_nodsh && skip "remote OST with nodsh"
24076
24077         local file=$DIR/$tfile
24078
24079         rm -f $file
24080         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24081
24082         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24083         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24084         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24085                 error "write should failed"
24086         do_facet ost1 "$LCTL set_param fail_loc=0"
24087         rm -f $file
24088 }
24089 run_test 313 "io should fail after last_rcvd update fail"
24090
24091 test_314() {
24092         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24093
24094         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24095         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24096         rm -f $DIR/$tfile
24097         wait_delete_completed
24098         do_facet ost1 "$LCTL set_param fail_loc=0"
24099 }
24100 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24101
24102 test_315() { # LU-618
24103         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24104
24105         local file=$DIR/$tfile
24106         rm -f $file
24107
24108         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24109                 error "multiop file write failed"
24110         $MULTIOP $file oO_RDONLY:r4063232_c &
24111         PID=$!
24112
24113         sleep 2
24114
24115         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24116         kill -USR1 $PID
24117
24118         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24119         rm -f $file
24120 }
24121 run_test 315 "read should be accounted"
24122
24123 test_316() {
24124         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24125         large_xattr_enabled || skip_env "ea_inode feature disabled"
24126
24127         rm -rf $DIR/$tdir/d
24128         mkdir -p $DIR/$tdir/d
24129         chown nobody $DIR/$tdir/d
24130         touch $DIR/$tdir/d/file
24131
24132         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
24133 }
24134 run_test 316 "lfs mv"
24135
24136 test_317() {
24137         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24138                 skip "Need MDS version at least 2.11.53"
24139         if [ "$ost1_FSTYPE" == "zfs" ]; then
24140                 skip "LU-10370: no implementation for ZFS"
24141         fi
24142
24143         local trunc_sz
24144         local grant_blk_size
24145
24146         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24147                         awk '/grant_block_size:/ { print $2; exit; }')
24148         #
24149         # Create File of size 5M. Truncate it to below size's and verify
24150         # blocks count.
24151         #
24152         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24153                 error "Create file $DIR/$tfile failed"
24154         stack_trap "rm -f $DIR/$tfile" EXIT
24155
24156         for trunc_sz in 2097152 4097 4000 509 0; do
24157                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24158                         error "truncate $tfile to $trunc_sz failed"
24159                 local sz=$(stat --format=%s $DIR/$tfile)
24160                 local blk=$(stat --format=%b $DIR/$tfile)
24161                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24162                                      grant_blk_size) * 8))
24163
24164                 if [[ $blk -ne $trunc_blk ]]; then
24165                         $(which stat) $DIR/$tfile
24166                         error "Expected Block $trunc_blk got $blk for $tfile"
24167                 fi
24168
24169                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24170                         error "Expected Size $trunc_sz got $sz for $tfile"
24171         done
24172
24173         #
24174         # sparse file test
24175         # Create file with a hole and write actual 65536 bytes which aligned
24176         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24177         #
24178         local bs=65536
24179         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24180                 error "Create file : $DIR/$tfile"
24181
24182         #
24183         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24184         # blocks. The block count must drop to 8.
24185         #
24186         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - \
24187                 ((bs - grant_blk_size) + 1)))
24188         $TRUNCATE $DIR/$tfile $trunc_sz ||
24189                 error "truncate $tfile to $trunc_sz failed"
24190
24191         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24192         sz=$(stat --format=%s $DIR/$tfile)
24193         blk=$(stat --format=%b $DIR/$tfile)
24194
24195         if [[ $blk -ne $trunc_bsz ]]; then
24196                 $(which stat) $DIR/$tfile
24197                 error "Expected Block $trunc_bsz got $blk for $tfile"
24198         fi
24199
24200         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24201                 error "Expected Size $trunc_sz got $sz for $tfile"
24202 }
24203 run_test 317 "Verify blocks get correctly update after truncate"
24204
24205 test_318() {
24206         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24207         local old_max_active=$($LCTL get_param -n \
24208                             ${llite_name}.max_read_ahead_async_active \
24209                             2>/dev/null)
24210
24211         $LCTL set_param llite.*.max_read_ahead_async_active=256
24212         local max_active=$($LCTL get_param -n \
24213                            ${llite_name}.max_read_ahead_async_active \
24214                            2>/dev/null)
24215         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24216
24217         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24218                 error "set max_read_ahead_async_active should succeed"
24219
24220         $LCTL set_param llite.*.max_read_ahead_async_active=512
24221         max_active=$($LCTL get_param -n \
24222                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24223         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24224
24225         # restore @max_active
24226         [ $old_max_active -ne 0 ] && $LCTL set_param \
24227                 llite.*.max_read_ahead_async_active=$old_max_active
24228
24229         local old_threshold=$($LCTL get_param -n \
24230                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24231         local max_per_file_mb=$($LCTL get_param -n \
24232                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24233
24234         local invalid=$(($max_per_file_mb + 1))
24235         $LCTL set_param \
24236                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24237                         && error "set $invalid should fail"
24238
24239         local valid=$(($invalid - 1))
24240         $LCTL set_param \
24241                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24242                         error "set $valid should succeed"
24243         local threshold=$($LCTL get_param -n \
24244                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24245         [ $threshold -eq $valid ] || error \
24246                 "expect threshold $valid got $threshold"
24247         $LCTL set_param \
24248                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24249 }
24250 run_test 318 "Verify async readahead tunables"
24251
24252 test_319() {
24253         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
24254
24255         local before=$(date +%s)
24256         local evict
24257         local mdir=$DIR/$tdir
24258         local file=$mdir/xxx
24259
24260         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24261         touch $file
24262
24263 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24264         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24265         $LFS mv -m1 $file &
24266
24267         sleep 1
24268         dd if=$file of=/dev/null
24269         wait
24270         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24271           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24272
24273         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24274 }
24275 run_test 319 "lost lease lock on migrate error"
24276
24277 test_398a() { # LU-4198
24278         local ost1_imp=$(get_osc_import_name client ost1)
24279         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24280                          cut -d'.' -f2)
24281
24282         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24283         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24284
24285         # request a new lock on client
24286         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24287
24288         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24289         local lock_count=$($LCTL get_param -n \
24290                            ldlm.namespaces.$imp_name.lru_size)
24291         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24292
24293         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24294
24295         # no lock cached, should use lockless IO and not enqueue new lock
24296         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24297         lock_count=$($LCTL get_param -n \
24298                      ldlm.namespaces.$imp_name.lru_size)
24299         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24300 }
24301 run_test 398a "direct IO should cancel lock otherwise lockless"
24302
24303 test_398b() { # LU-4198
24304         which fio || skip_env "no fio installed"
24305         $LFS setstripe -c -1 $DIR/$tfile
24306
24307         local size=12
24308         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24309
24310         local njobs=4
24311         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
24312         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24313                 --numjobs=$njobs --fallocate=none \
24314                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24315                 --filename=$DIR/$tfile &
24316         bg_pid=$!
24317
24318         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
24319         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
24320                 --numjobs=$njobs --fallocate=none \
24321                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24322                 --filename=$DIR/$tfile || true
24323         wait $bg_pid
24324
24325         rm -f $DIR/$tfile
24326 }
24327 run_test 398b "DIO and buffer IO race"
24328
24329 test_398c() { # LU-4198
24330         local ost1_imp=$(get_osc_import_name client ost1)
24331         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24332                          cut -d'.' -f2)
24333
24334         which fio || skip_env "no fio installed"
24335
24336         saved_debug=$($LCTL get_param -n debug)
24337         $LCTL set_param debug=0
24338
24339         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24340         ((size /= 1024)) # by megabytes
24341         ((size /= 2)) # write half of the OST at most
24342         [ $size -gt 40 ] && size=40 #reduce test time anyway
24343
24344         $LFS setstripe -c 1 $DIR/$tfile
24345
24346         # it seems like ldiskfs reserves more space than necessary if the
24347         # writing blocks are not mapped, so it extends the file firstly
24348         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24349         cancel_lru_locks osc
24350
24351         # clear and verify rpc_stats later
24352         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24353
24354         local njobs=4
24355         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24356         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24357                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24358                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24359                 --filename=$DIR/$tfile
24360         [ $? -eq 0 ] || error "fio write error"
24361
24362         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24363                 error "Locks were requested while doing AIO"
24364
24365         # get the percentage of 1-page I/O
24366         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24367                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24368                 awk '{print $7}')
24369         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24370
24371         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24372         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24373                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24374                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24375                 --filename=$DIR/$tfile
24376         [ $? -eq 0 ] || error "fio mixed read write error"
24377
24378         echo "AIO with large block size ${size}M"
24379         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24380                 --numjobs=1 --fallocate=none --ioengine=libaio \
24381                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24382                 --filename=$DIR/$tfile
24383         [ $? -eq 0 ] || error "fio large block size failed"
24384
24385         rm -f $DIR/$tfile
24386         $LCTL set_param debug="$saved_debug"
24387 }
24388 run_test 398c "run fio to test AIO"
24389
24390 test_398d() { #  LU-13846
24391         which aiocp || skip_env "no aiocp installed"
24392         local aio_file=$DIR/$tfile.aio
24393
24394         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24395
24396         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24397         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24398         stack_trap "rm -f $DIR/$tfile $aio_file"
24399
24400         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24401
24402         # make sure we don't crash and fail properly
24403         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24404                 error "aio not aligned with PAGE SIZE should fail"
24405
24406         rm -f $DIR/$tfile $aio_file
24407 }
24408 run_test 398d "run aiocp to verify block size > stripe size"
24409
24410 test_398e() {
24411         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24412         touch $DIR/$tfile.new
24413         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24414 }
24415 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24416
24417 test_398f() { #  LU-14687
24418         which aiocp || skip_env "no aiocp installed"
24419         local aio_file=$DIR/$tfile.aio
24420
24421         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24422
24423         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24424         stack_trap "rm -f $DIR/$tfile $aio_file"
24425
24426         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24427         $LCTL set_param fail_loc=0x1418
24428         # make sure we don't crash and fail properly
24429         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24430                 error "aio with page allocation failure succeeded"
24431         $LCTL set_param fail_loc=0
24432         diff $DIR/$tfile $aio_file
24433         [[ $? != 0 ]] || error "no diff after failed aiocp"
24434 }
24435 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24436
24437 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24438 # stripe and i/o size must be > stripe size
24439 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24440 # single RPC in flight.  This test shows async DIO submission is working by
24441 # showing multiple RPCs in flight.
24442 test_398g() { #  LU-13798
24443         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24444
24445         # We need to do some i/o first to acquire enough grant to put our RPCs
24446         # in flight; otherwise a new connection may not have enough grant
24447         # available
24448         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24449                 error "parallel dio failed"
24450         stack_trap "rm -f $DIR/$tfile"
24451
24452         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24453         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24454         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24455         stack_trap "$LCTL set_param -n $pages_per_rpc"
24456
24457         # Recreate file so it's empty
24458         rm -f $DIR/$tfile
24459         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24460         #Pause rpc completion to guarantee we see multiple rpcs in flight
24461         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24462         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24463         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24464
24465         # Clear rpc stats
24466         $LCTL set_param osc.*.rpc_stats=c
24467
24468         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24469                 error "parallel dio failed"
24470         stack_trap "rm -f $DIR/$tfile"
24471
24472         $LCTL get_param osc.*-OST0000-*.rpc_stats
24473         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24474                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24475                 grep "8:" | awk '{print $8}')
24476         # We look at the "8 rpcs in flight" field, and verify A) it is present
24477         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24478         # as expected for an 8M DIO to a file with 1M stripes.
24479         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24480
24481         # Verify turning off parallel dio works as expected
24482         # Clear rpc stats
24483         $LCTL set_param osc.*.rpc_stats=c
24484         $LCTL set_param llite.*.parallel_dio=0
24485         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24486
24487         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24488                 error "dio with parallel dio disabled failed"
24489
24490         # Ideally, we would see only one RPC in flight here, but there is an
24491         # unavoidable race between i/o completion and RPC in flight counting,
24492         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24493         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24494         # So instead we just verify it's always < 8.
24495         $LCTL get_param osc.*-OST0000-*.rpc_stats
24496         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24497                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24498                 grep '^$' -B1 | grep . | awk '{print $1}')
24499         [ $ret != "8:" ] ||
24500                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24501 }
24502 run_test 398g "verify parallel dio async RPC submission"
24503
24504 test_398h() { #  LU-13798
24505         local dio_file=$DIR/$tfile.dio
24506
24507         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24508
24509         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24510         stack_trap "rm -f $DIR/$tfile $dio_file"
24511
24512         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24513                 error "parallel dio failed"
24514         diff $DIR/$tfile $dio_file
24515         [[ $? == 0 ]] || error "file diff after aiocp"
24516 }
24517 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24518
24519 test_398i() { #  LU-13798
24520         local dio_file=$DIR/$tfile.dio
24521
24522         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24523
24524         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24525         stack_trap "rm -f $DIR/$tfile $dio_file"
24526
24527         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24528         $LCTL set_param fail_loc=0x1418
24529         # make sure we don't crash and fail properly
24530         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24531                 error "parallel dio page allocation failure succeeded"
24532         diff $DIR/$tfile $dio_file
24533         [[ $? != 0 ]] || error "no diff after failed aiocp"
24534 }
24535 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24536
24537 test_398j() { #  LU-13798
24538         # Stripe size > RPC size but less than i/o size tests split across
24539         # stripes and RPCs for individual i/o op
24540         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24541
24542         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24543         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24544         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24545         stack_trap "$LCTL set_param -n $pages_per_rpc"
24546
24547         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24548                 error "parallel dio write failed"
24549         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24550
24551         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24552                 error "parallel dio read failed"
24553         diff $DIR/$tfile $DIR/$tfile.2
24554         [[ $? == 0 ]] || error "file diff after parallel dio read"
24555 }
24556 run_test 398j "test parallel dio where stripe size > rpc_size"
24557
24558 test_398k() { #  LU-13798
24559         wait_delete_completed
24560         wait_mds_ost_sync
24561
24562         # 4 stripe file; we will cause out of space on OST0
24563         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24564
24565         # Fill OST0 (if it's not too large)
24566         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24567                    head -n1)
24568         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24569                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24570         fi
24571         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24572         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24573                 error "dd should fill OST0"
24574         stack_trap "rm -f $DIR/$tfile.1"
24575
24576         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24577         err=$?
24578
24579         ls -la $DIR/$tfile
24580         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24581                 error "file is not 0 bytes in size"
24582
24583         # dd above should not succeed, but don't error until here so we can
24584         # get debug info above
24585         [[ $err != 0 ]] ||
24586                 error "parallel dio write with enospc succeeded"
24587         stack_trap "rm -f $DIR/$tfile"
24588 }
24589 run_test 398k "test enospc on first stripe"
24590
24591 test_398l() { #  LU-13798
24592         wait_delete_completed
24593         wait_mds_ost_sync
24594
24595         # 4 stripe file; we will cause out of space on OST0
24596         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24597         # happens on the second i/o chunk we issue
24598         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24599
24600         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24601         stack_trap "rm -f $DIR/$tfile"
24602
24603         # Fill OST0 (if it's not too large)
24604         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24605                    head -n1)
24606         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24607                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24608         fi
24609         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24610         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24611                 error "dd should fill OST0"
24612         stack_trap "rm -f $DIR/$tfile.1"
24613
24614         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24615         err=$?
24616         stack_trap "rm -f $DIR/$tfile.2"
24617
24618         # Check that short write completed as expected
24619         ls -la $DIR/$tfile.2
24620         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24621                 error "file is not 1M in size"
24622
24623         # dd above should not succeed, but don't error until here so we can
24624         # get debug info above
24625         [[ $err != 0 ]] ||
24626                 error "parallel dio write with enospc succeeded"
24627
24628         # Truncate source file to same length as output file and diff them
24629         $TRUNCATE $DIR/$tfile 1048576
24630         diff $DIR/$tfile $DIR/$tfile.2
24631         [[ $? == 0 ]] || error "data incorrect after short write"
24632 }
24633 run_test 398l "test enospc on intermediate stripe/RPC"
24634
24635 test_398m() { #  LU-13798
24636         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24637
24638         # Set up failure on OST0, the first stripe:
24639         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24640         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24641         # So this fail_val specifies OST0
24642         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24643         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24644
24645         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24646                 error "parallel dio write with failure on first stripe succeeded"
24647         stack_trap "rm -f $DIR/$tfile"
24648         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24649
24650         # Place data in file for read
24651         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24652                 error "parallel dio write failed"
24653
24654         # Fail read on OST0, first stripe
24655         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24656         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24657         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24658                 error "parallel dio read with error on first stripe succeeded"
24659         rm -f $DIR/$tfile.2
24660         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24661
24662         # Switch to testing on OST1, second stripe
24663         # Clear file contents, maintain striping
24664         echo > $DIR/$tfile
24665         # Set up failure on OST1, second stripe:
24666         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24667         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24668
24669         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24670                 error "parallel dio write with failure on first stripe succeeded"
24671         stack_trap "rm -f $DIR/$tfile"
24672         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24673
24674         # Place data in file for read
24675         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24676                 error "parallel dio write failed"
24677
24678         # Fail read on OST1, second stripe
24679         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24680         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24681         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24682                 error "parallel dio read with error on first stripe succeeded"
24683         rm -f $DIR/$tfile.2
24684         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24685 }
24686 run_test 398m "test RPC failures with parallel dio"
24687
24688 # Parallel submission of DIO should not cause problems for append, but it's
24689 # important to verify.
24690 test_398n() { #  LU-13798
24691         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24692
24693         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24694                 error "dd to create source file failed"
24695         stack_trap "rm -f $DIR/$tfile"
24696
24697         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24698                 error "parallel dio write with failure on second stripe succeeded"
24699         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24700         diff $DIR/$tfile $DIR/$tfile.1
24701         [[ $? == 0 ]] || error "data incorrect after append"
24702
24703 }
24704 run_test 398n "test append with parallel DIO"
24705
24706 test_fake_rw() {
24707         local read_write=$1
24708         if [ "$read_write" = "write" ]; then
24709                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24710         elif [ "$read_write" = "read" ]; then
24711                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24712         else
24713                 error "argument error"
24714         fi
24715
24716         # turn off debug for performance testing
24717         local saved_debug=$($LCTL get_param -n debug)
24718         $LCTL set_param debug=0
24719
24720         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24721
24722         # get ost1 size - $FSNAME-OST0000
24723         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24724         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
24725         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
24726
24727         if [ "$read_write" = "read" ]; then
24728                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
24729         fi
24730
24731         local start_time=$(date +%s.%N)
24732         $dd_cmd bs=1M count=$blocks oflag=sync ||
24733                 error "real dd $read_write error"
24734         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
24735
24736         if [ "$read_write" = "write" ]; then
24737                 rm -f $DIR/$tfile
24738         fi
24739
24740         # define OBD_FAIL_OST_FAKE_RW           0x238
24741         do_facet ost1 $LCTL set_param fail_loc=0x238
24742
24743         local start_time=$(date +%s.%N)
24744         $dd_cmd bs=1M count=$blocks oflag=sync ||
24745                 error "fake dd $read_write error"
24746         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
24747
24748         if [ "$read_write" = "write" ]; then
24749                 # verify file size
24750                 cancel_lru_locks osc
24751                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
24752                         error "$tfile size not $blocks MB"
24753         fi
24754         do_facet ost1 $LCTL set_param fail_loc=0
24755
24756         echo "fake $read_write $duration_fake vs. normal $read_write" \
24757                 "$duration in seconds"
24758         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
24759                 error_not_in_vm "fake write is slower"
24760
24761         $LCTL set_param -n debug="$saved_debug"
24762         rm -f $DIR/$tfile
24763 }
24764 test_399a() { # LU-7655 for OST fake write
24765         remote_ost_nodsh && skip "remote OST with nodsh"
24766
24767         test_fake_rw write
24768 }
24769 run_test 399a "fake write should not be slower than normal write"
24770
24771 test_399b() { # LU-8726 for OST fake read
24772         remote_ost_nodsh && skip "remote OST with nodsh"
24773         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
24774                 skip_env "ldiskfs only test"
24775         fi
24776
24777         test_fake_rw read
24778 }
24779 run_test 399b "fake read should not be slower than normal read"
24780
24781 test_400a() { # LU-1606, was conf-sanity test_74
24782         if ! which $CC > /dev/null 2>&1; then
24783                 skip_env "$CC is not installed"
24784         fi
24785
24786         local extra_flags=''
24787         local out=$TMP/$tfile
24788         local prefix=/usr/include/lustre
24789         local prog
24790
24791         # Oleg removes c files in his test rig so test if any c files exist
24792         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24793                 skip_env "Needed c test files are missing"
24794
24795         if ! [[ -d $prefix ]]; then
24796                 # Assume we're running in tree and fixup the include path.
24797                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24798                 extra_flags+=" -L$LUSTRE/utils/.lib"
24799         fi
24800
24801         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24802                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24803                         error "client api broken"
24804         done
24805         rm -f $out
24806 }
24807 run_test 400a "Lustre client api program can compile and link"
24808
24809 test_400b() { # LU-1606, LU-5011
24810         local header
24811         local out=$TMP/$tfile
24812         local prefix=/usr/include/linux/lustre
24813
24814         # We use a hard coded prefix so that this test will not fail
24815         # when run in tree. There are headers in lustre/include/lustre/
24816         # that are not packaged (like lustre_idl.h) and have more
24817         # complicated include dependencies (like config.h and lnet/types.h).
24818         # Since this test about correct packaging we just skip them when
24819         # they don't exist (see below) rather than try to fixup cppflags.
24820
24821         if ! which $CC > /dev/null 2>&1; then
24822                 skip_env "$CC is not installed"
24823         fi
24824
24825         for header in $prefix/*.h; do
24826                 if ! [[ -f "$header" ]]; then
24827                         continue
24828                 fi
24829
24830                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24831                         continue # lustre_ioctl.h is internal header
24832                 fi
24833
24834                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24835                         error "cannot compile '$header'"
24836         done
24837         rm -f $out
24838 }
24839 run_test 400b "packaged headers can be compiled"
24840
24841 test_401a() { #LU-7437
24842         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
24843         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
24844
24845         #count the number of parameters by "list_param -R"
24846         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
24847         #count the number of parameters by listing proc files
24848         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
24849         echo "proc_dirs='$proc_dirs'"
24850         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
24851         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
24852                       sort -u | wc -l)
24853
24854         [ $params -eq $procs ] ||
24855                 error "found $params parameters vs. $procs proc files"
24856
24857         # test the list_param -D option only returns directories
24858         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
24859         #count the number of parameters by listing proc directories
24860         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
24861                 sort -u | wc -l)
24862
24863         [ $params -eq $procs ] ||
24864                 error "found $params parameters vs. $procs proc files"
24865 }
24866 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
24867
24868 test_401b() {
24869         # jobid_var may not allow arbitrary values, so use jobid_name
24870         # if available
24871         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24872                 local testname=jobid_name tmp='testing%p'
24873         else
24874                 local testname=jobid_var tmp=testing
24875         fi
24876
24877         local save=$($LCTL get_param -n $testname)
24878
24879         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
24880                 error "no error returned when setting bad parameters"
24881
24882         local jobid_new=$($LCTL get_param -n foe $testname baz)
24883         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
24884
24885         $LCTL set_param -n fog=bam $testname=$save bat=fog
24886         local jobid_old=$($LCTL get_param -n foe $testname bag)
24887         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
24888 }
24889 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
24890
24891 test_401c() {
24892         # jobid_var may not allow arbitrary values, so use jobid_name
24893         # if available
24894         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24895                 local testname=jobid_name
24896         else
24897                 local testname=jobid_var
24898         fi
24899
24900         local jobid_var_old=$($LCTL get_param -n $testname)
24901         local jobid_var_new
24902
24903         $LCTL set_param $testname= &&
24904                 error "no error returned for 'set_param a='"
24905
24906         jobid_var_new=$($LCTL get_param -n $testname)
24907         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24908                 error "$testname was changed by setting without value"
24909
24910         $LCTL set_param $testname &&
24911                 error "no error returned for 'set_param a'"
24912
24913         jobid_var_new=$($LCTL get_param -n $testname)
24914         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24915                 error "$testname was changed by setting without value"
24916 }
24917 run_test 401c "Verify 'lctl set_param' without value fails in either format."
24918
24919 test_401d() {
24920         # jobid_var may not allow arbitrary values, so use jobid_name
24921         # if available
24922         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24923                 local testname=jobid_name new_value='foo=bar%p'
24924         else
24925                 local testname=jobid_var new_valuie=foo=bar
24926         fi
24927
24928         local jobid_var_old=$($LCTL get_param -n $testname)
24929         local jobid_var_new
24930
24931         $LCTL set_param $testname=$new_value ||
24932                 error "'set_param a=b' did not accept a value containing '='"
24933
24934         jobid_var_new=$($LCTL get_param -n $testname)
24935         [[ "$jobid_var_new" == "$new_value" ]] ||
24936                 error "'set_param a=b' failed on a value containing '='"
24937
24938         # Reset the $testname to test the other format
24939         $LCTL set_param $testname=$jobid_var_old
24940         jobid_var_new=$($LCTL get_param -n $testname)
24941         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24942                 error "failed to reset $testname"
24943
24944         $LCTL set_param $testname $new_value ||
24945                 error "'set_param a b' did not accept a value containing '='"
24946
24947         jobid_var_new=$($LCTL get_param -n $testname)
24948         [[ "$jobid_var_new" == "$new_value" ]] ||
24949                 error "'set_param a b' failed on a value containing '='"
24950
24951         $LCTL set_param $testname $jobid_var_old
24952         jobid_var_new=$($LCTL get_param -n $testname)
24953         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24954                 error "failed to reset $testname"
24955 }
24956 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
24957
24958 test_401e() { # LU-14779
24959         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
24960                 error "lctl list_param MGC* failed"
24961         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
24962         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
24963                 error "lctl get_param lru_size failed"
24964 }
24965 run_test 401e "verify 'lctl get_param' works with NID in parameter"
24966
24967 test_402() {
24968         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
24969         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
24970                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
24971         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
24972                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
24973                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
24974         remote_mds_nodsh && skip "remote MDS with nodsh"
24975
24976         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
24977 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
24978         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
24979         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
24980                 echo "Touch failed - OK"
24981 }
24982 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
24983
24984 test_403() {
24985         local file1=$DIR/$tfile.1
24986         local file2=$DIR/$tfile.2
24987         local tfile=$TMP/$tfile
24988
24989         rm -f $file1 $file2 $tfile
24990
24991         touch $file1
24992         ln $file1 $file2
24993
24994         # 30 sec OBD_TIMEOUT in ll_getattr()
24995         # right before populating st_nlink
24996         $LCTL set_param fail_loc=0x80001409
24997         stat -c %h $file1 > $tfile &
24998
24999         # create an alias, drop all locks and reclaim the dentry
25000         < $file2
25001         cancel_lru_locks mdc
25002         cancel_lru_locks osc
25003         sysctl -w vm.drop_caches=2
25004
25005         wait
25006
25007         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25008
25009         rm -f $tfile $file1 $file2
25010 }
25011 run_test 403 "i_nlink should not drop to zero due to aliasing"
25012
25013 test_404() { # LU-6601
25014         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25015                 skip "Need server version newer than 2.8.52"
25016         remote_mds_nodsh && skip "remote MDS with nodsh"
25017
25018         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25019                 awk '/osp .*-osc-MDT/ { print $4}')
25020
25021         local osp
25022         for osp in $mosps; do
25023                 echo "Deactivate: " $osp
25024                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25025                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25026                         awk -vp=$osp '$4 == p { print $2 }')
25027                 [ $stat = IN ] || {
25028                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25029                         error "deactivate error"
25030                 }
25031                 echo "Activate: " $osp
25032                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25033                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25034                         awk -vp=$osp '$4 == p { print $2 }')
25035                 [ $stat = UP ] || {
25036                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25037                         error "activate error"
25038                 }
25039         done
25040 }
25041 run_test 404 "validate manual {de}activated works properly for OSPs"
25042
25043 test_405() {
25044         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25045         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25046                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25047                         skip "Layout swap lock is not supported"
25048
25049         check_swap_layouts_support
25050         check_swap_layout_no_dom $DIR
25051
25052         test_mkdir $DIR/$tdir
25053         swap_lock_test -d $DIR/$tdir ||
25054                 error "One layout swap locked test failed"
25055 }
25056 run_test 405 "Various layout swap lock tests"
25057
25058 test_406() {
25059         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25060         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25061         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25063         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25064                 skip "Need MDS version at least 2.8.50"
25065
25066         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25067         local test_pool=$TESTNAME
25068
25069         pool_add $test_pool || error "pool_add failed"
25070         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25071                 error "pool_add_targets failed"
25072
25073         save_layout_restore_at_exit $MOUNT
25074
25075         # parent set default stripe count only, child will stripe from both
25076         # parent and fs default
25077         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25078                 error "setstripe $MOUNT failed"
25079         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25080         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25081         for i in $(seq 10); do
25082                 local f=$DIR/$tdir/$tfile.$i
25083                 touch $f || error "touch failed"
25084                 local count=$($LFS getstripe -c $f)
25085                 [ $count -eq $OSTCOUNT ] ||
25086                         error "$f stripe count $count != $OSTCOUNT"
25087                 local offset=$($LFS getstripe -i $f)
25088                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25089                 local size=$($LFS getstripe -S $f)
25090                 [ $size -eq $((def_stripe_size * 2)) ] ||
25091                         error "$f stripe size $size != $((def_stripe_size * 2))"
25092                 local pool=$($LFS getstripe -p $f)
25093                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25094         done
25095
25096         # change fs default striping, delete parent default striping, now child
25097         # will stripe from new fs default striping only
25098         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25099                 error "change $MOUNT default stripe failed"
25100         $LFS setstripe -c 0 $DIR/$tdir ||
25101                 error "delete $tdir default stripe failed"
25102         for i in $(seq 11 20); do
25103                 local f=$DIR/$tdir/$tfile.$i
25104                 touch $f || error "touch $f failed"
25105                 local count=$($LFS getstripe -c $f)
25106                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25107                 local offset=$($LFS getstripe -i $f)
25108                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25109                 local size=$($LFS getstripe -S $f)
25110                 [ $size -eq $def_stripe_size ] ||
25111                         error "$f stripe size $size != $def_stripe_size"
25112                 local pool=$($LFS getstripe -p $f)
25113                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25114         done
25115
25116         unlinkmany $DIR/$tdir/$tfile. 1 20
25117
25118         local f=$DIR/$tdir/$tfile
25119         pool_remove_all_targets $test_pool $f
25120         pool_remove $test_pool $f
25121 }
25122 run_test 406 "DNE support fs default striping"
25123
25124 test_407() {
25125         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25126         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25127                 skip "Need MDS version at least 2.8.55"
25128         remote_mds_nodsh && skip "remote MDS with nodsh"
25129
25130         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25131                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25132         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25133                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25134         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25135
25136         #define OBD_FAIL_DT_TXN_STOP    0x2019
25137         for idx in $(seq $MDSCOUNT); do
25138                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25139         done
25140         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25141         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25142                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25143         true
25144 }
25145 run_test 407 "transaction fail should cause operation fail"
25146
25147 test_408() {
25148         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25149
25150         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25151         lctl set_param fail_loc=0x8000040a
25152         # let ll_prepare_partial_page() fail
25153         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25154
25155         rm -f $DIR/$tfile
25156
25157         # create at least 100 unused inodes so that
25158         # shrink_icache_memory(0) should not return 0
25159         touch $DIR/$tfile-{0..100}
25160         rm -f $DIR/$tfile-{0..100}
25161         sync
25162
25163         echo 2 > /proc/sys/vm/drop_caches
25164 }
25165 run_test 408 "drop_caches should not hang due to page leaks"
25166
25167 test_409()
25168 {
25169         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25170
25171         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25172         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25173         touch $DIR/$tdir/guard || error "(2) Fail to create"
25174
25175         local PREFIX=$(str_repeat 'A' 128)
25176         echo "Create 1K hard links start at $(date)"
25177         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25178                 error "(3) Fail to hard link"
25179
25180         echo "Links count should be right although linkEA overflow"
25181         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25182         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25183         [ $linkcount -eq 1001 ] ||
25184                 error "(5) Unexpected hard links count: $linkcount"
25185
25186         echo "List all links start at $(date)"
25187         ls -l $DIR/$tdir/foo > /dev/null ||
25188                 error "(6) Fail to list $DIR/$tdir/foo"
25189
25190         echo "Unlink hard links start at $(date)"
25191         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25192                 error "(7) Fail to unlink"
25193         echo "Unlink hard links finished at $(date)"
25194 }
25195 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25196
25197 test_410()
25198 {
25199         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25200                 skip "Need client version at least 2.9.59"
25201         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25202                 skip "Need MODULES build"
25203
25204         # Create a file, and stat it from the kernel
25205         local testfile=$DIR/$tfile
25206         touch $testfile
25207
25208         local run_id=$RANDOM
25209         local my_ino=$(stat --format "%i" $testfile)
25210
25211         # Try to insert the module. This will always fail as the
25212         # module is designed to not be inserted.
25213         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25214             &> /dev/null
25215
25216         # Anything but success is a test failure
25217         dmesg | grep -q \
25218             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25219             error "no inode match"
25220 }
25221 run_test 410 "Test inode number returned from kernel thread"
25222
25223 cleanup_test411_cgroup() {
25224         trap 0
25225         rmdir "$1"
25226 }
25227
25228 test_411() {
25229         local cg_basedir=/sys/fs/cgroup/memory
25230         # LU-9966
25231         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25232                 skip "no setup for cgroup"
25233
25234         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25235                 error "test file creation failed"
25236         cancel_lru_locks osc
25237
25238         # Create a very small memory cgroup to force a slab allocation error
25239         local cgdir=$cg_basedir/osc_slab_alloc
25240         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25241         trap "cleanup_test411_cgroup $cgdir" EXIT
25242         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25243         echo 1M > $cgdir/memory.limit_in_bytes
25244
25245         # Should not LBUG, just be killed by oom-killer
25246         # dd will return 0 even allocation failure in some environment.
25247         # So don't check return value
25248         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25249         cleanup_test411_cgroup $cgdir
25250
25251         return 0
25252 }
25253 run_test 411 "Slab allocation error with cgroup does not LBUG"
25254
25255 test_412() {
25256         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25257         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25258                 skip "Need server version at least 2.10.55"
25259
25260         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25261                 error "mkdir failed"
25262         $LFS getdirstripe $DIR/$tdir
25263         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25264         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25265                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25266         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25267         [ $stripe_count -eq 2 ] ||
25268                 error "expect 2 get $stripe_count"
25269
25270         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25271
25272         local index
25273         local index2
25274
25275         # subdirs should be on the same MDT as parent
25276         for i in $(seq 0 $((MDSCOUNT - 1))); do
25277                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25278                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25279                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25280                 (( index == i )) || error "mdt$i/sub on MDT$index"
25281         done
25282
25283         # stripe offset -1, ditto
25284         for i in {1..10}; do
25285                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25286                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25287                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25288                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25289                 (( index == index2 )) ||
25290                         error "qos$i on MDT$index, sub on MDT$index2"
25291         done
25292
25293         local testdir=$DIR/$tdir/inherit
25294
25295         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25296         # inherit 2 levels
25297         for i in 1 2; do
25298                 testdir=$testdir/s$i
25299                 mkdir $testdir || error "mkdir $testdir failed"
25300                 index=$($LFS getstripe -m $testdir)
25301                 (( index == 1 )) ||
25302                         error "$testdir on MDT$index"
25303         done
25304
25305         # not inherit any more
25306         testdir=$testdir/s3
25307         mkdir $testdir || error "mkdir $testdir failed"
25308         getfattr -d -m dmv $testdir | grep dmv &&
25309                 error "default LMV set on $testdir" || true
25310 }
25311 run_test 412 "mkdir on specific MDTs"
25312
25313 generate_uneven_mdts() {
25314         local threshold=$1
25315         local lmv_qos_maxage
25316         local lod_qos_maxage
25317         local ffree
25318         local bavail
25319         local max
25320         local min
25321         local max_index
25322         local min_index
25323         local tmp
25324         local i
25325
25326         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25327         $LCTL set_param lmv.*.qos_maxage=1
25328         stack_trap "$LCTL set_param \
25329                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25330         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25331                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25332         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25333                 lod.*.mdt_qos_maxage=1
25334         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25335                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25336
25337         echo
25338         echo "Check for uneven MDTs: "
25339
25340         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25341         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25342         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25343
25344         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25345         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25346         max_index=0
25347         min_index=0
25348         for ((i = 1; i < ${#ffree[@]}; i++)); do
25349                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25350                 if [ $tmp -gt $max ]; then
25351                         max=$tmp
25352                         max_index=$i
25353                 fi
25354                 if [ $tmp -lt $min ]; then
25355                         min=$tmp
25356                         min_index=$i
25357                 fi
25358         done
25359
25360         (( ${ffree[min_index]} > 0 )) ||
25361                 skip "no free files in MDT$min_index"
25362         (( ${ffree[min_index]} < 10000000 )) ||
25363                 skip "too many free files in MDT$min_index"
25364
25365         # Check if we need to generate uneven MDTs
25366         local diff=$(((max - min) * 100 / min))
25367         local testdir=$DIR/$tdir-fillmdt
25368         local start
25369
25370         mkdir -p $testdir
25371
25372         i=0
25373         while (( diff < threshold )); do
25374                 # generate uneven MDTs, create till $threshold% diff
25375                 echo -n "weight diff=$diff% must be > $threshold% ..."
25376                 echo "Fill MDT$min_index with 1000 files: loop $i"
25377                 testdir=$DIR/$tdir-fillmdt/$i
25378                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
25379                         error "mkdir $testdir failed"
25380                 $LFS setstripe -E 1M -L mdt $testdir ||
25381                         error "setstripe $testdir failed"
25382                 start=$SECONDS
25383                 for F in f.{0..999}; do
25384                         dd if=/dev/zero of=$testdir/$F bs=64K count=1 > \
25385                                 /dev/null 2>&1 || error "dd $F failed"
25386                 done
25387
25388                 # wait for QOS to update
25389                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25390
25391                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25392                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25393                 max=$(((${ffree[max_index]} >> 8) * \
25394                         (${bavail[max_index]} * bsize >> 16)))
25395                 min=$(((${ffree[min_index]} >> 8) * \
25396                         (${bavail[min_index]} * bsize >> 16)))
25397                 diff=$(((max - min) * 100 / min))
25398                 i=$((i + 1))
25399         done
25400
25401         echo "MDT filesfree available: ${ffree[@]}"
25402         echo "MDT blocks available: ${bavail[@]}"
25403         echo "weight diff=$diff%"
25404 }
25405
25406 test_qos_mkdir() {
25407         local mkdir_cmd=$1
25408         local stripe_count=$2
25409         local mdts=$(comma_list $(mdts_nodes))
25410
25411         local testdir
25412         local lmv_qos_prio_free
25413         local lmv_qos_threshold_rr
25414         local lmv_qos_maxage
25415         local lod_qos_prio_free
25416         local lod_qos_threshold_rr
25417         local lod_qos_maxage
25418         local count
25419         local i
25420
25421         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25422         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25423         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25424                 head -n1)
25425         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25426         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25427         stack_trap "$LCTL set_param \
25428                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25429         stack_trap "$LCTL set_param \
25430                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25431         stack_trap "$LCTL set_param \
25432                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25433
25434         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25435                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25436         lod_qos_prio_free=${lod_qos_prio_free%%%}
25437         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25438                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25439         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25440         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25441                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25442         stack_trap "do_nodes $mdts $LCTL set_param \
25443                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25444         stack_trap "do_nodes $mdts $LCTL set_param \
25445                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25446         stack_trap "do_nodes $mdts $LCTL set_param \
25447                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25448
25449         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25450         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25451
25452         testdir=$DIR/$tdir-s$stripe_count/rr
25453
25454         local stripe_index=$($LFS getstripe -m $testdir)
25455         local test_mkdir_rr=true
25456
25457         getfattr -d -m dmv -e hex $testdir | grep dmv
25458         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25459                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25460                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25461                         test_mkdir_rr=false
25462         fi
25463
25464         echo
25465         $test_mkdir_rr &&
25466                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25467                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25468
25469         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25470         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25471                 eval $mkdir_cmd $testdir/subdir$i ||
25472                         error "$mkdir_cmd subdir$i failed"
25473         done
25474
25475         for (( i = 0; i < $MDSCOUNT; i++ )); do
25476                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25477                 echo "$count directories created on MDT$i"
25478                 if $test_mkdir_rr; then
25479                         (( $count == 100 )) ||
25480                                 error "subdirs are not evenly distributed"
25481                 elif (( $i == $stripe_index )); then
25482                         (( $count == 100 * MDSCOUNT )) ||
25483                                 error "$count subdirs created on MDT$i"
25484                 else
25485                         (( $count == 0 )) ||
25486                                 error "$count subdirs created on MDT$i"
25487                 fi
25488
25489                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25490                         count=$($LFS getdirstripe $testdir/* |
25491                                 grep -c -P "^\s+$i\t")
25492                         echo "$count stripes created on MDT$i"
25493                         # deviation should < 5% of average
25494                         (( $count >= 95 * stripe_count &&
25495                            $count <= 105 * stripe_count)) ||
25496                                 error "stripes are not evenly distributed"
25497                 fi
25498         done
25499
25500         echo
25501         echo "Check for uneven MDTs: "
25502
25503         local ffree
25504         local bavail
25505         local max
25506         local min
25507         local max_index
25508         local min_index
25509         local tmp
25510
25511         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25512         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25513         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25514
25515         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25516         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25517         max_index=0
25518         min_index=0
25519         for ((i = 1; i < ${#ffree[@]}; i++)); do
25520                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25521                 if [ $tmp -gt $max ]; then
25522                         max=$tmp
25523                         max_index=$i
25524                 fi
25525                 if [ $tmp -lt $min ]; then
25526                         min=$tmp
25527                         min_index=$i
25528                 fi
25529         done
25530
25531         (( ${ffree[min_index]} > 0 )) ||
25532                 skip "no free files in MDT$min_index"
25533         (( ${ffree[min_index]} < 10000000 )) ||
25534                 skip "too many free files in MDT$min_index"
25535
25536         echo "MDT filesfree available: ${ffree[@]}"
25537         echo "MDT blocks available: ${bavail[@]}"
25538         echo "weight diff=$(((max - min) * 100 / min))%"
25539         echo
25540         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25541
25542         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25543         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25544         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25545         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25546         # decrease statfs age, so that it can be updated in time
25547         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25548         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25549
25550         sleep 1
25551
25552         testdir=$DIR/$tdir-s$stripe_count/qos
25553         local num=200
25554
25555         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25556         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25557                 eval $mkdir_cmd $testdir/subdir$i ||
25558                         error "$mkdir_cmd subdir$i failed"
25559         done
25560
25561         max=0
25562         for (( i = 0; i < $MDSCOUNT; i++ )); do
25563                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25564                 (( count > max )) && max=$count
25565                 echo "$count directories created on MDT$i"
25566         done
25567
25568         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25569
25570         # D-value should > 10% of averge
25571         (( max - min > num / 10 )) ||
25572                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25573
25574         # ditto for stripes
25575         if (( stripe_count > 1 )); then
25576                 max=0
25577                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25578                         count=$($LFS getdirstripe $testdir/* |
25579                                 grep -c -P "^\s+$i\t")
25580                         (( count > max )) && max=$count
25581                         echo "$count stripes created on MDT$i"
25582                 done
25583
25584                 min=$($LFS getdirstripe $testdir/* |
25585                         grep -c -P "^\s+$min_index\t")
25586                 (( max - min > num * stripe_count / 10 )) ||
25587                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25588         fi
25589 }
25590
25591 most_full_mdt() {
25592         local ffree
25593         local bavail
25594         local bsize
25595         local min
25596         local min_index
25597         local tmp
25598
25599         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25600         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25601         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25602
25603         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25604         min_index=0
25605         for ((i = 1; i < ${#ffree[@]}; i++)); do
25606                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25607                 (( tmp < min )) && min=$tmp && min_index=$i
25608         done
25609
25610         echo -n $min_index
25611 }
25612
25613 test_413a() {
25614         [ $MDSCOUNT -lt 2 ] &&
25615                 skip "We need at least 2 MDTs for this test"
25616
25617         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25618                 skip "Need server version at least 2.12.52"
25619
25620         local stripe_count
25621
25622         generate_uneven_mdts 100
25623         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25624                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25625                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25626                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25627                         error "mkdir failed"
25628                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25629         done
25630 }
25631 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25632
25633 test_413b() {
25634         [ $MDSCOUNT -lt 2 ] &&
25635                 skip "We need at least 2 MDTs for this test"
25636
25637         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25638                 skip "Need server version at least 2.12.52"
25639
25640         local testdir
25641         local stripe_count
25642
25643         generate_uneven_mdts 100
25644         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25645                 testdir=$DIR/$tdir-s$stripe_count
25646                 mkdir $testdir || error "mkdir $testdir failed"
25647                 mkdir $testdir/rr || error "mkdir rr failed"
25648                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25649                         error "mkdir qos failed"
25650                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25651                         $testdir/rr || error "setdirstripe rr failed"
25652                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25653                         error "setdirstripe failed"
25654                 test_qos_mkdir "mkdir" $stripe_count
25655         done
25656 }
25657 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25658
25659 test_413c() {
25660         (( $MDSCOUNT >= 2 )) ||
25661                 skip "We need at least 2 MDTs for this test"
25662
25663         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25664                 skip "Need server version at least 2.14.51"
25665
25666         local testdir
25667         local inherit
25668         local inherit_rr
25669
25670         testdir=$DIR/${tdir}-s1
25671         mkdir $testdir || error "mkdir $testdir failed"
25672         mkdir $testdir/rr || error "mkdir rr failed"
25673         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25674         # default max_inherit is -1, default max_inherit_rr is 0
25675         $LFS setdirstripe -D -c 1 $testdir/rr ||
25676                 error "setdirstripe rr failed"
25677         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25678                 error "setdirstripe qos failed"
25679         test_qos_mkdir "mkdir" 1
25680
25681         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25682         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25683         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25684         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25685         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25686
25687         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25688         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25689         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25690         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25691         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25692         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25693         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25694                 error "level2 shouldn't have default LMV" || true
25695 }
25696 run_test 413c "mkdir with default LMV max inherit rr"
25697
25698 test_413d() {
25699         (( MDSCOUNT >= 2 )) ||
25700                 skip "We need at least 2 MDTs for this test"
25701
25702         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25703                 skip "Need server version at least 2.14.51"
25704
25705         local lmv_qos_threshold_rr
25706
25707         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25708                 head -n1)
25709         stack_trap "$LCTL set_param \
25710                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
25711
25712         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25713         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25714         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
25715                 error "$tdir shouldn't have default LMV"
25716         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
25717                 error "mkdir sub failed"
25718
25719         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
25720
25721         (( count == 100 )) || error "$count subdirs on MDT0"
25722 }
25723 run_test 413d "inherit ROOT default LMV"
25724
25725 test_413e() {
25726         (( MDSCOUNT >= 2 )) ||
25727                 skip "We need at least 2 MDTs for this test"
25728         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25729                 skip "Need server version at least 2.14.55"
25730
25731         local testdir=$DIR/$tdir
25732         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
25733         local max_inherit
25734         local sub_max_inherit
25735
25736         mkdir -p $testdir || error "failed to create $testdir"
25737
25738         # set default max-inherit to -1 if stripe count is 0 or 1
25739         $LFS setdirstripe -D -c 1 $testdir ||
25740                 error "failed to set default LMV"
25741         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25742         (( max_inherit == -1 )) ||
25743                 error "wrong max_inherit value $max_inherit"
25744
25745         # set default max_inherit to a fixed value if stripe count is not 0 or 1
25746         $LFS setdirstripe -D -c -1 $testdir ||
25747                 error "failed to set default LMV"
25748         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25749         (( max_inherit > 0 )) ||
25750                 error "wrong max_inherit value $max_inherit"
25751
25752         # and the subdir will decrease the max_inherit by 1
25753         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
25754         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
25755         (( sub_max_inherit == max_inherit - 1)) ||
25756                 error "wrong max-inherit of subdir $sub_max_inherit"
25757
25758         # check specified --max-inherit and warning message
25759         stack_trap "rm -f $tmpfile"
25760         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
25761                 error "failed to set default LMV"
25762         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25763         (( max_inherit == -1 )) ||
25764                 error "wrong max_inherit value $max_inherit"
25765
25766         # check the warning messages
25767         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
25768                 error "failed to detect warning string"
25769         fi
25770 }
25771 run_test 413e "check default max-inherit value"
25772
25773 test_413f() {
25774         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
25775
25776         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25777                 skip "Need server version at least 2.14.55"
25778
25779         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
25780                 error "dump $DIR default LMV failed"
25781         stack_trap "setfattr --restore=$TMP/dmv.ea"
25782
25783         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
25784                 error "set $DIR default LMV failed"
25785
25786         local testdir=$DIR/$tdir
25787
25788         local count
25789         local inherit
25790         local inherit_rr
25791
25792         for i in $(seq 3); do
25793                 mkdir $testdir || error "mkdir $testdir failed"
25794                 count=$($LFS getdirstripe -D -c $testdir)
25795                 (( count == 1 )) ||
25796                         error "$testdir default LMV count mismatch $count != 1"
25797                 inherit=$($LFS getdirstripe -D -X $testdir)
25798                 (( inherit == 3 - i )) ||
25799                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
25800                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
25801                 (( inherit_rr == 3 - i )) ||
25802                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
25803                 testdir=$testdir/sub
25804         done
25805
25806         mkdir $testdir || error "mkdir $testdir failed"
25807         count=$($LFS getdirstripe -D -c $testdir)
25808         (( count == 0 )) ||
25809                 error "$testdir default LMV count not zero: $count"
25810 }
25811 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
25812
25813 test_413z() {
25814         local pids=""
25815         local subdir
25816         local pid
25817
25818         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
25819                 unlinkmany $subdir/f. 1000 &
25820                 pids="$pids $!"
25821         done
25822
25823         for pid in $pids; do
25824                 wait $pid
25825         done
25826 }
25827 run_test 413z "413 test cleanup"
25828
25829 test_414() {
25830 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
25831         $LCTL set_param fail_loc=0x80000521
25832         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25833         rm -f $DIR/$tfile
25834 }
25835 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
25836
25837 test_415() {
25838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25839         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25840                 skip "Need server version at least 2.11.52"
25841
25842         # LU-11102
25843         local total
25844         local setattr_pid
25845         local start_time
25846         local end_time
25847         local duration
25848
25849         total=500
25850         # this test may be slow on ZFS
25851         [ "$mds1_FSTYPE" == "zfs" ] && total=100
25852
25853         # though this test is designed for striped directory, let's test normal
25854         # directory too since lock is always saved as CoS lock.
25855         test_mkdir $DIR/$tdir || error "mkdir $tdir"
25856         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
25857
25858         (
25859                 while true; do
25860                         touch $DIR/$tdir
25861                 done
25862         ) &
25863         setattr_pid=$!
25864
25865         start_time=$(date +%s)
25866         for i in $(seq $total); do
25867                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
25868                         > /dev/null
25869         done
25870         end_time=$(date +%s)
25871         duration=$((end_time - start_time))
25872
25873         kill -9 $setattr_pid
25874
25875         echo "rename $total files took $duration sec"
25876         [ $duration -lt 100 ] || error "rename took $duration sec"
25877 }
25878 run_test 415 "lock revoke is not missing"
25879
25880 test_416() {
25881         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25882                 skip "Need server version at least 2.11.55"
25883
25884         # define OBD_FAIL_OSD_TXN_START    0x19a
25885         do_facet mds1 lctl set_param fail_loc=0x19a
25886
25887         lfs mkdir -c $MDSCOUNT $DIR/$tdir
25888
25889         true
25890 }
25891 run_test 416 "transaction start failure won't cause system hung"
25892
25893 cleanup_417() {
25894         trap 0
25895         do_nodes $(comma_list $(mdts_nodes)) \
25896                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
25897         do_nodes $(comma_list $(mdts_nodes)) \
25898                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
25899         do_nodes $(comma_list $(mdts_nodes)) \
25900                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
25901 }
25902
25903 test_417() {
25904         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25905         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
25906                 skip "Need MDS version at least 2.11.56"
25907
25908         trap cleanup_417 RETURN EXIT
25909
25910         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
25911         do_nodes $(comma_list $(mdts_nodes)) \
25912                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
25913         $LFS migrate -m 0 $DIR/$tdir.1 &&
25914                 error "migrate dir $tdir.1 should fail"
25915
25916         do_nodes $(comma_list $(mdts_nodes)) \
25917                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
25918         $LFS mkdir -i 1 $DIR/$tdir.2 &&
25919                 error "create remote dir $tdir.2 should fail"
25920
25921         do_nodes $(comma_list $(mdts_nodes)) \
25922                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
25923         $LFS mkdir -c 2 $DIR/$tdir.3 &&
25924                 error "create striped dir $tdir.3 should fail"
25925         true
25926 }
25927 run_test 417 "disable remote dir, striped dir and dir migration"
25928
25929 # Checks that the outputs of df [-i] and lfs df [-i] match
25930 #
25931 # usage: check_lfs_df <blocks | inodes> <mountpoint>
25932 check_lfs_df() {
25933         local dir=$2
25934         local inodes
25935         local df_out
25936         local lfs_df_out
25937         local count
25938         local passed=false
25939
25940         # blocks or inodes
25941         [ "$1" == "blocks" ] && inodes= || inodes="-i"
25942
25943         for count in {1..100}; do
25944                 do_nodes "$CLIENTS" \
25945                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25946                 sync; sleep 0.2
25947
25948                 # read the lines of interest
25949                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
25950                         error "df $inodes $dir | tail -n +2 failed"
25951                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
25952                         error "lfs df $inodes $dir | grep summary: failed"
25953
25954                 # skip first substrings of each output as they are different
25955                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
25956                 # compare the two outputs
25957                 passed=true
25958                 #  skip "available" on MDT until LU-13997 is fixed.
25959                 #for i in {1..5}; do
25960                 for i in 1 2 4 5; do
25961                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
25962                 done
25963                 $passed && break
25964         done
25965
25966         if ! $passed; then
25967                 df -P $inodes $dir
25968                 echo
25969                 lfs df $inodes $dir
25970                 error "df and lfs df $1 output mismatch: "      \
25971                       "df ${inodes}: ${df_out[*]}, "            \
25972                       "lfs df ${inodes}: ${lfs_df_out[*]}"
25973         fi
25974 }
25975
25976 test_418() {
25977         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25978
25979         local dir=$DIR/$tdir
25980         local numfiles=$((RANDOM % 4096 + 2))
25981         local numblocks=$((RANDOM % 256 + 1))
25982
25983         wait_delete_completed
25984         test_mkdir $dir
25985
25986         # check block output
25987         check_lfs_df blocks $dir
25988         # check inode output
25989         check_lfs_df inodes $dir
25990
25991         # create a single file and retest
25992         echo "Creating a single file and testing"
25993         createmany -o $dir/$tfile- 1 &>/dev/null ||
25994                 error "creating 1 file in $dir failed"
25995         check_lfs_df blocks $dir
25996         check_lfs_df inodes $dir
25997
25998         # create a random number of files
25999         echo "Creating $((numfiles - 1)) files and testing"
26000         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
26001                 error "creating $((numfiles - 1)) files in $dir failed"
26002
26003         # write a random number of blocks to the first test file
26004         echo "Writing $numblocks 4K blocks and testing"
26005         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26006                 count=$numblocks &>/dev/null ||
26007                 error "dd to $dir/${tfile}-0 failed"
26008
26009         # retest
26010         check_lfs_df blocks $dir
26011         check_lfs_df inodes $dir
26012
26013         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
26014                 error "unlinking $numfiles files in $dir failed"
26015 }
26016 run_test 418 "df and lfs df outputs match"
26017
26018 test_419()
26019 {
26020         local dir=$DIR/$tdir
26021
26022         mkdir -p $dir
26023         touch $dir/file
26024
26025         cancel_lru_locks mdc
26026
26027         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26028         $LCTL set_param fail_loc=0x1410
26029         cat $dir/file
26030         $LCTL set_param fail_loc=0
26031         rm -rf $dir
26032 }
26033 run_test 419 "Verify open file by name doesn't crash kernel"
26034
26035 test_420()
26036 {
26037         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26038                 skip "Need MDS version at least 2.12.53"
26039
26040         local SAVE_UMASK=$(umask)
26041         local dir=$DIR/$tdir
26042         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26043
26044         mkdir -p $dir
26045         umask 0000
26046         mkdir -m03777 $dir/testdir
26047         ls -dn $dir/testdir
26048         # Need to remove trailing '.' when SELinux is enabled
26049         local dirperms=$(ls -dn $dir/testdir |
26050                          awk '{ sub(/\.$/, "", $1); print $1}')
26051         [ $dirperms == "drwxrwsrwt" ] ||
26052                 error "incorrect perms on $dir/testdir"
26053
26054         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26055                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26056         ls -n $dir/testdir/testfile
26057         local fileperms=$(ls -n $dir/testdir/testfile |
26058                           awk '{ sub(/\.$/, "", $1); print $1}')
26059         [ $fileperms == "-rwxr-xr-x" ] ||
26060                 error "incorrect perms on $dir/testdir/testfile"
26061
26062         umask $SAVE_UMASK
26063 }
26064 run_test 420 "clear SGID bit on non-directories for non-members"
26065
26066 test_421a() {
26067         local cnt
26068         local fid1
26069         local fid2
26070
26071         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26072                 skip "Need MDS version at least 2.12.54"
26073
26074         test_mkdir $DIR/$tdir
26075         createmany -o $DIR/$tdir/f 3
26076         cnt=$(ls -1 $DIR/$tdir | wc -l)
26077         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26078
26079         fid1=$(lfs path2fid $DIR/$tdir/f1)
26080         fid2=$(lfs path2fid $DIR/$tdir/f2)
26081         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26082
26083         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26084         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26085
26086         cnt=$(ls -1 $DIR/$tdir | wc -l)
26087         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26088
26089         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26090         createmany -o $DIR/$tdir/f 3
26091         cnt=$(ls -1 $DIR/$tdir | wc -l)
26092         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26093
26094         fid1=$(lfs path2fid $DIR/$tdir/f1)
26095         fid2=$(lfs path2fid $DIR/$tdir/f2)
26096         echo "remove using fsname $FSNAME"
26097         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26098
26099         cnt=$(ls -1 $DIR/$tdir | wc -l)
26100         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26101 }
26102 run_test 421a "simple rm by fid"
26103
26104 test_421b() {
26105         local cnt
26106         local FID1
26107         local FID2
26108
26109         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26110                 skip "Need MDS version at least 2.12.54"
26111
26112         test_mkdir $DIR/$tdir
26113         createmany -o $DIR/$tdir/f 3
26114         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26115         MULTIPID=$!
26116
26117         FID1=$(lfs path2fid $DIR/$tdir/f1)
26118         FID2=$(lfs path2fid $DIR/$tdir/f2)
26119         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26120
26121         kill -USR1 $MULTIPID
26122         wait
26123
26124         cnt=$(ls $DIR/$tdir | wc -l)
26125         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26126 }
26127 run_test 421b "rm by fid on open file"
26128
26129 test_421c() {
26130         local cnt
26131         local FIDS
26132
26133         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26134                 skip "Need MDS version at least 2.12.54"
26135
26136         test_mkdir $DIR/$tdir
26137         createmany -o $DIR/$tdir/f 3
26138         touch $DIR/$tdir/$tfile
26139         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26140         cnt=$(ls -1 $DIR/$tdir | wc -l)
26141         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26142
26143         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26144         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26145
26146         cnt=$(ls $DIR/$tdir | wc -l)
26147         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26148 }
26149 run_test 421c "rm by fid against hardlinked files"
26150
26151 test_421d() {
26152         local cnt
26153         local FIDS
26154
26155         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26156                 skip "Need MDS version at least 2.12.54"
26157
26158         test_mkdir $DIR/$tdir
26159         createmany -o $DIR/$tdir/f 4097
26160         cnt=$(ls -1 $DIR/$tdir | wc -l)
26161         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26162
26163         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26164         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26165
26166         cnt=$(ls $DIR/$tdir | wc -l)
26167         rm -rf $DIR/$tdir
26168         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26169 }
26170 run_test 421d "rmfid en masse"
26171
26172 test_421e() {
26173         local cnt
26174         local FID
26175
26176         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26177         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26178                 skip "Need MDS version at least 2.12.54"
26179
26180         mkdir -p $DIR/$tdir
26181         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26182         createmany -o $DIR/$tdir/striped_dir/f 512
26183         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26184         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26185
26186         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26187                 sed "s/[/][^:]*://g")
26188         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26189
26190         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26191         rm -rf $DIR/$tdir
26192         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26193 }
26194 run_test 421e "rmfid in DNE"
26195
26196 test_421f() {
26197         local cnt
26198         local FID
26199
26200         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26201                 skip "Need MDS version at least 2.12.54"
26202
26203         test_mkdir $DIR/$tdir
26204         touch $DIR/$tdir/f
26205         cnt=$(ls -1 $DIR/$tdir | wc -l)
26206         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26207
26208         FID=$(lfs path2fid $DIR/$tdir/f)
26209         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26210         # rmfid should fail
26211         cnt=$(ls -1 $DIR/$tdir | wc -l)
26212         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26213
26214         chmod a+rw $DIR/$tdir
26215         ls -la $DIR/$tdir
26216         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26217         # rmfid should fail
26218         cnt=$(ls -1 $DIR/$tdir | wc -l)
26219         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26220
26221         rm -f $DIR/$tdir/f
26222         $RUNAS touch $DIR/$tdir/f
26223         FID=$(lfs path2fid $DIR/$tdir/f)
26224         echo "rmfid as root"
26225         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26226         cnt=$(ls -1 $DIR/$tdir | wc -l)
26227         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26228
26229         rm -f $DIR/$tdir/f
26230         $RUNAS touch $DIR/$tdir/f
26231         cnt=$(ls -1 $DIR/$tdir | wc -l)
26232         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26233         FID=$(lfs path2fid $DIR/$tdir/f)
26234         # rmfid w/o user_fid2path mount option should fail
26235         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26236         cnt=$(ls -1 $DIR/$tdir | wc -l)
26237         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26238
26239         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26240         stack_trap "rmdir $tmpdir"
26241         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26242                 error "failed to mount client'"
26243         stack_trap "umount_client $tmpdir"
26244
26245         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26246         # rmfid should succeed
26247         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26248         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26249
26250         # rmfid shouldn't allow to remove files due to dir's permission
26251         chmod a+rwx $tmpdir/$tdir
26252         touch $tmpdir/$tdir/f
26253         ls -la $tmpdir/$tdir
26254         FID=$(lfs path2fid $tmpdir/$tdir/f)
26255         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26256         return 0
26257 }
26258 run_test 421f "rmfid checks permissions"
26259
26260 test_421g() {
26261         local cnt
26262         local FIDS
26263
26264         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26265         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26266                 skip "Need MDS version at least 2.12.54"
26267
26268         mkdir -p $DIR/$tdir
26269         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26270         createmany -o $DIR/$tdir/striped_dir/f 512
26271         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26272         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26273
26274         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26275                 sed "s/[/][^:]*://g")
26276
26277         rm -f $DIR/$tdir/striped_dir/f1*
26278         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26279         removed=$((512 - cnt))
26280
26281         # few files have been just removed, so we expect
26282         # rmfid to fail on their fids
26283         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26284         [ $removed != $errors ] && error "$errors != $removed"
26285
26286         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26287         rm -rf $DIR/$tdir
26288         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26289 }
26290 run_test 421g "rmfid to return errors properly"
26291
26292 test_422() {
26293         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26294         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26295         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26296         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26297         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26298
26299         local amc=$(at_max_get client)
26300         local amo=$(at_max_get mds1)
26301         local timeout=`lctl get_param -n timeout`
26302
26303         at_max_set 0 client
26304         at_max_set 0 mds1
26305
26306 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26307         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26308                         fail_val=$(((2*timeout + 10)*1000))
26309         touch $DIR/$tdir/d3/file &
26310         sleep 2
26311 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26312         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26313                         fail_val=$((2*timeout + 5))
26314         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26315         local pid=$!
26316         sleep 1
26317         kill -9 $pid
26318         sleep $((2 * timeout))
26319         echo kill $pid
26320         kill -9 $pid
26321         lctl mark touch
26322         touch $DIR/$tdir/d2/file3
26323         touch $DIR/$tdir/d2/file4
26324         touch $DIR/$tdir/d2/file5
26325
26326         wait
26327         at_max_set $amc client
26328         at_max_set $amo mds1
26329
26330         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26331         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26332                 error "Watchdog is always throttled"
26333 }
26334 run_test 422 "kill a process with RPC in progress"
26335
26336 stat_test() {
26337     df -h $MOUNT &
26338     df -h $MOUNT &
26339     df -h $MOUNT &
26340     df -h $MOUNT &
26341     df -h $MOUNT &
26342     df -h $MOUNT &
26343 }
26344
26345 test_423() {
26346     local _stats
26347     # ensure statfs cache is expired
26348     sleep 2;
26349
26350     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26351     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26352
26353     return 0
26354 }
26355 run_test 423 "statfs should return a right data"
26356
26357 test_424() {
26358 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26359         $LCTL set_param fail_loc=0x80000522
26360         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26361         rm -f $DIR/$tfile
26362 }
26363 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26364
26365 test_425() {
26366         test_mkdir -c -1 $DIR/$tdir
26367         $LFS setstripe -c -1 $DIR/$tdir
26368
26369         lru_resize_disable "" 100
26370         stack_trap "lru_resize_enable" EXIT
26371
26372         sleep 5
26373
26374         for i in $(seq $((MDSCOUNT * 125))); do
26375                 local t=$DIR/$tdir/$tfile_$i
26376
26377                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26378                         error_noexit "Create file $t"
26379         done
26380         stack_trap "rm -rf $DIR/$tdir" EXIT
26381
26382         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26383                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26384                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26385
26386                 [ $lock_count -le $lru_size ] ||
26387                         error "osc lock count $lock_count > lru size $lru_size"
26388         done
26389
26390         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26391                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26392                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26393
26394                 [ $lock_count -le $lru_size ] ||
26395                         error "mdc lock count $lock_count > lru size $lru_size"
26396         done
26397 }
26398 run_test 425 "lock count should not exceed lru size"
26399
26400 test_426() {
26401         splice-test -r $DIR/$tfile
26402         splice-test -rd $DIR/$tfile
26403         splice-test $DIR/$tfile
26404         splice-test -d $DIR/$tfile
26405 }
26406 run_test 426 "splice test on Lustre"
26407
26408 test_427() {
26409         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26410         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26411                 skip "Need MDS version at least 2.12.4"
26412         local log
26413
26414         mkdir $DIR/$tdir
26415         mkdir $DIR/$tdir/1
26416         mkdir $DIR/$tdir/2
26417         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26418         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26419
26420         $LFS getdirstripe $DIR/$tdir/1/dir
26421
26422         #first setfattr for creating updatelog
26423         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26424
26425 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26426         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26427         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26428         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26429
26430         sleep 2
26431         fail mds2
26432         wait_recovery_complete mds2 $((2*TIMEOUT))
26433
26434         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26435         echo $log | grep "get update log failed" &&
26436                 error "update log corruption is detected" || true
26437 }
26438 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26439
26440 test_428() {
26441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26442         local cache_limit=$CACHE_MAX
26443
26444         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26445         $LCTL set_param -n llite.*.max_cached_mb=64
26446
26447         mkdir $DIR/$tdir
26448         $LFS setstripe -c 1 $DIR/$tdir
26449         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26450         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26451         #test write
26452         for f in $(seq 4); do
26453                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26454         done
26455         wait
26456
26457         cancel_lru_locks osc
26458         # Test read
26459         for f in $(seq 4); do
26460                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26461         done
26462         wait
26463 }
26464 run_test 428 "large block size IO should not hang"
26465
26466 test_429() { # LU-7915 / LU-10948
26467         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26468         local testfile=$DIR/$tfile
26469         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26470         local new_flag=1
26471         local first_rpc
26472         local second_rpc
26473         local third_rpc
26474
26475         $LCTL get_param $ll_opencache_threshold_count ||
26476                 skip "client does not have opencache parameter"
26477
26478         set_opencache $new_flag
26479         stack_trap "restore_opencache"
26480         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26481                 error "enable opencache failed"
26482         touch $testfile
26483         # drop MDC DLM locks
26484         cancel_lru_locks mdc
26485         # clear MDC RPC stats counters
26486         $LCTL set_param $mdc_rpcstats=clear
26487
26488         # According to the current implementation, we need to run 3 times
26489         # open & close file to verify if opencache is enabled correctly.
26490         # 1st, RPCs are sent for lookup/open and open handle is released on
26491         #      close finally.
26492         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26493         #      so open handle won't be released thereafter.
26494         # 3rd, No RPC is sent out.
26495         $MULTIOP $testfile oc || error "multiop failed"
26496         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26497         echo "1st: $first_rpc RPCs in flight"
26498
26499         $MULTIOP $testfile oc || error "multiop failed"
26500         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26501         echo "2nd: $second_rpc RPCs in flight"
26502
26503         $MULTIOP $testfile oc || error "multiop failed"
26504         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26505         echo "3rd: $third_rpc RPCs in flight"
26506
26507         #verify no MDC RPC is sent
26508         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26509 }
26510 run_test 429 "verify if opencache flag on client side does work"
26511
26512 lseek_test_430() {
26513         local offset
26514         local file=$1
26515
26516         # data at [200K, 400K)
26517         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26518                 error "256K->512K dd fails"
26519         # data at [2M, 3M)
26520         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26521                 error "2M->3M dd fails"
26522         # data at [4M, 5M)
26523         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26524                 error "4M->5M dd fails"
26525         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26526         # start at first component hole #1
26527         printf "Seeking hole from 1000 ... "
26528         offset=$(lseek_test -l 1000 $file)
26529         echo $offset
26530         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26531         printf "Seeking data from 1000 ... "
26532         offset=$(lseek_test -d 1000 $file)
26533         echo $offset
26534         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26535
26536         # start at first component data block
26537         printf "Seeking hole from 300000 ... "
26538         offset=$(lseek_test -l 300000 $file)
26539         echo $offset
26540         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26541         printf "Seeking data from 300000 ... "
26542         offset=$(lseek_test -d 300000 $file)
26543         echo $offset
26544         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26545
26546         # start at the first component but beyond end of object size
26547         printf "Seeking hole from 1000000 ... "
26548         offset=$(lseek_test -l 1000000 $file)
26549         echo $offset
26550         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26551         printf "Seeking data from 1000000 ... "
26552         offset=$(lseek_test -d 1000000 $file)
26553         echo $offset
26554         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26555
26556         # start at second component stripe 2 (empty file)
26557         printf "Seeking hole from 1500000 ... "
26558         offset=$(lseek_test -l 1500000 $file)
26559         echo $offset
26560         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26561         printf "Seeking data from 1500000 ... "
26562         offset=$(lseek_test -d 1500000 $file)
26563         echo $offset
26564         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26565
26566         # start at second component stripe 1 (all data)
26567         printf "Seeking hole from 3000000 ... "
26568         offset=$(lseek_test -l 3000000 $file)
26569         echo $offset
26570         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26571         printf "Seeking data from 3000000 ... "
26572         offset=$(lseek_test -d 3000000 $file)
26573         echo $offset
26574         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26575
26576         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26577                 error "2nd dd fails"
26578         echo "Add data block at 640K...1280K"
26579
26580         # start at before new data block, in hole
26581         printf "Seeking hole from 600000 ... "
26582         offset=$(lseek_test -l 600000 $file)
26583         echo $offset
26584         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26585         printf "Seeking data from 600000 ... "
26586         offset=$(lseek_test -d 600000 $file)
26587         echo $offset
26588         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26589
26590         # start at the first component new data block
26591         printf "Seeking hole from 1000000 ... "
26592         offset=$(lseek_test -l 1000000 $file)
26593         echo $offset
26594         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26595         printf "Seeking data from 1000000 ... "
26596         offset=$(lseek_test -d 1000000 $file)
26597         echo $offset
26598         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26599
26600         # start at second component stripe 2, new data
26601         printf "Seeking hole from 1200000 ... "
26602         offset=$(lseek_test -l 1200000 $file)
26603         echo $offset
26604         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26605         printf "Seeking data from 1200000 ... "
26606         offset=$(lseek_test -d 1200000 $file)
26607         echo $offset
26608         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
26609
26610         # start beyond file end
26611         printf "Using offset > filesize ... "
26612         lseek_test -l 4000000 $file && error "lseek should fail"
26613         printf "Using offset > filesize ... "
26614         lseek_test -d 4000000 $file && error "lseek should fail"
26615
26616         printf "Done\n\n"
26617 }
26618
26619 test_430a() {
26620         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
26621                 skip "MDT does not support SEEK_HOLE"
26622
26623         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26624                 skip "OST does not support SEEK_HOLE"
26625
26626         local file=$DIR/$tdir/$tfile
26627
26628         mkdir -p $DIR/$tdir
26629
26630         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
26631         # OST stripe #1 will have continuous data at [1M, 3M)
26632         # OST stripe #2 is empty
26633         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
26634         lseek_test_430 $file
26635         rm $file
26636         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
26637         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
26638         lseek_test_430 $file
26639         rm $file
26640         $LFS setstripe -c2 -S 512K $file
26641         echo "Two stripes, stripe size 512K"
26642         lseek_test_430 $file
26643         rm $file
26644         # FLR with stale mirror
26645         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
26646                        -N -c2 -S 1M $file
26647         echo "Mirrored file:"
26648         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
26649         echo "Plain 2 stripes 1M"
26650         lseek_test_430 $file
26651         rm $file
26652 }
26653 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
26654
26655 test_430b() {
26656         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26657                 skip "OST does not support SEEK_HOLE"
26658
26659         local offset
26660         local file=$DIR/$tdir/$tfile
26661
26662         mkdir -p $DIR/$tdir
26663         # Empty layout lseek should fail
26664         $MCREATE $file
26665         # seek from 0
26666         printf "Seeking hole from 0 ... "
26667         lseek_test -l 0 $file && error "lseek should fail"
26668         printf "Seeking data from 0 ... "
26669         lseek_test -d 0 $file && error "lseek should fail"
26670         rm $file
26671
26672         # 1M-hole file
26673         $LFS setstripe -E 1M -c2 -E eof $file
26674         $TRUNCATE $file 1048576
26675         printf "Seeking hole from 1000000 ... "
26676         offset=$(lseek_test -l 1000000 $file)
26677         echo $offset
26678         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26679         printf "Seeking data from 1000000 ... "
26680         lseek_test -d 1000000 $file && error "lseek should fail"
26681         rm $file
26682
26683         # full component followed by non-inited one
26684         $LFS setstripe -E 1M -c2 -E eof $file
26685         dd if=/dev/urandom of=$file bs=1M count=1
26686         printf "Seeking hole from 1000000 ... "
26687         offset=$(lseek_test -l 1000000 $file)
26688         echo $offset
26689         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26690         printf "Seeking hole from 1048576 ... "
26691         lseek_test -l 1048576 $file && error "lseek should fail"
26692         # init second component and truncate back
26693         echo "123" >> $file
26694         $TRUNCATE $file 1048576
26695         printf "Seeking hole from 1000000 ... "
26696         offset=$(lseek_test -l 1000000 $file)
26697         echo $offset
26698         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26699         printf "Seeking hole from 1048576 ... "
26700         lseek_test -l 1048576 $file && error "lseek should fail"
26701         # boundary checks for big values
26702         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
26703         offset=$(lseek_test -d 0 $file.10g)
26704         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
26705         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
26706         offset=$(lseek_test -d 0 $file.100g)
26707         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
26708         return 0
26709 }
26710 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
26711
26712 test_430c() {
26713         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26714                 skip "OST does not support SEEK_HOLE"
26715
26716         local file=$DIR/$tdir/$tfile
26717         local start
26718
26719         mkdir -p $DIR/$tdir
26720         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
26721
26722         # cp version 8.33+ prefers lseek over fiemap
26723         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
26724                 start=$SECONDS
26725                 time cp $file /dev/null
26726                 (( SECONDS - start < 5 )) ||
26727                         error "cp: too long runtime $((SECONDS - start))"
26728
26729         fi
26730         # tar version 1.29+ supports SEEK_HOLE/DATA
26731         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
26732                 start=$SECONDS
26733                 time tar cS $file - | cat > /dev/null
26734                 (( SECONDS - start < 5 )) ||
26735                         error "tar: too long runtime $((SECONDS - start))"
26736         fi
26737 }
26738 run_test 430c "lseek: external tools check"
26739
26740 test_431() { # LU-14187
26741         local file=$DIR/$tdir/$tfile
26742
26743         mkdir -p $DIR/$tdir
26744         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
26745         dd if=/dev/urandom of=$file bs=4k count=1
26746         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
26747         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
26748         #define OBD_FAIL_OST_RESTART_IO 0x251
26749         do_facet ost1 "$LCTL set_param fail_loc=0x251"
26750         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
26751         cp $file $file.0
26752         cancel_lru_locks
26753         sync_all_data
26754         echo 3 > /proc/sys/vm/drop_caches
26755         diff  $file $file.0 || error "data diff"
26756 }
26757 run_test 431 "Restart transaction for IO"
26758
26759 cleanup_test_432() {
26760         do_facet mgs $LCTL nodemap_activate 0
26761         wait_nm_sync active
26762 }
26763
26764 test_432() {
26765         local tmpdir=$TMP/dir432
26766
26767         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
26768                 skip "Need MDS version at least 2.14.52"
26769
26770         stack_trap cleanup_test_432 EXIT
26771         mkdir $DIR/$tdir
26772         mkdir $tmpdir
26773
26774         do_facet mgs $LCTL nodemap_activate 1
26775         wait_nm_sync active
26776         do_facet mgs $LCTL nodemap_modify --name default \
26777                 --property admin --value 1
26778         do_facet mgs $LCTL nodemap_modify --name default \
26779                 --property trusted --value 1
26780         cancel_lru_locks mdc
26781         wait_nm_sync default admin_nodemap
26782         wait_nm_sync default trusted_nodemap
26783
26784         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
26785                grep -ci "Operation not permitted") -ne 0 ]; then
26786                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
26787         fi
26788 }
26789 run_test 432 "mv dir from outside Lustre"
26790
26791 prep_801() {
26792         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26793         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26794                 skip "Need server version at least 2.9.55"
26795
26796         start_full_debug_logging
26797 }
26798
26799 post_801() {
26800         stop_full_debug_logging
26801 }
26802
26803 barrier_stat() {
26804         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26805                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26806                            awk '/The barrier for/ { print $7 }')
26807                 echo $st
26808         else
26809                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
26810                 echo \'$st\'
26811         fi
26812 }
26813
26814 barrier_expired() {
26815         local expired
26816
26817         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26818                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26819                           awk '/will be expired/ { print $7 }')
26820         else
26821                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
26822         fi
26823
26824         echo $expired
26825 }
26826
26827 test_801a() {
26828         prep_801
26829
26830         echo "Start barrier_freeze at: $(date)"
26831         #define OBD_FAIL_BARRIER_DELAY          0x2202
26832         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26833         # Do not reduce barrier time - See LU-11873
26834         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
26835
26836         sleep 2
26837         local b_status=$(barrier_stat)
26838         echo "Got barrier status at: $(date)"
26839         [ "$b_status" = "'freezing_p1'" ] ||
26840                 error "(1) unexpected barrier status $b_status"
26841
26842         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26843         wait
26844         b_status=$(barrier_stat)
26845         [ "$b_status" = "'frozen'" ] ||
26846                 error "(2) unexpected barrier status $b_status"
26847
26848         local expired=$(barrier_expired)
26849         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
26850         sleep $((expired + 3))
26851
26852         b_status=$(barrier_stat)
26853         [ "$b_status" = "'expired'" ] ||
26854                 error "(3) unexpected barrier status $b_status"
26855
26856         # Do not reduce barrier time - See LU-11873
26857         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
26858                 error "(4) fail to freeze barrier"
26859
26860         b_status=$(barrier_stat)
26861         [ "$b_status" = "'frozen'" ] ||
26862                 error "(5) unexpected barrier status $b_status"
26863
26864         echo "Start barrier_thaw at: $(date)"
26865         #define OBD_FAIL_BARRIER_DELAY          0x2202
26866         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26867         do_facet mgs $LCTL barrier_thaw $FSNAME &
26868
26869         sleep 2
26870         b_status=$(barrier_stat)
26871         echo "Got barrier status at: $(date)"
26872         [ "$b_status" = "'thawing'" ] ||
26873                 error "(6) unexpected barrier status $b_status"
26874
26875         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26876         wait
26877         b_status=$(barrier_stat)
26878         [ "$b_status" = "'thawed'" ] ||
26879                 error "(7) unexpected barrier status $b_status"
26880
26881         #define OBD_FAIL_BARRIER_FAILURE        0x2203
26882         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
26883         do_facet mgs $LCTL barrier_freeze $FSNAME
26884
26885         b_status=$(barrier_stat)
26886         [ "$b_status" = "'failed'" ] ||
26887                 error "(8) unexpected barrier status $b_status"
26888
26889         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
26890         do_facet mgs $LCTL barrier_thaw $FSNAME
26891
26892         post_801
26893 }
26894 run_test 801a "write barrier user interfaces and stat machine"
26895
26896 test_801b() {
26897         prep_801
26898
26899         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26900         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
26901         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
26902         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
26903         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
26904
26905         cancel_lru_locks mdc
26906
26907         # 180 seconds should be long enough
26908         do_facet mgs $LCTL barrier_freeze $FSNAME 180
26909
26910         local b_status=$(barrier_stat)
26911         [ "$b_status" = "'frozen'" ] ||
26912                 error "(6) unexpected barrier status $b_status"
26913
26914         mkdir $DIR/$tdir/d0/d10 &
26915         mkdir_pid=$!
26916
26917         touch $DIR/$tdir/d1/f13 &
26918         touch_pid=$!
26919
26920         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
26921         ln_pid=$!
26922
26923         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
26924         mv_pid=$!
26925
26926         rm -f $DIR/$tdir/d4/f12 &
26927         rm_pid=$!
26928
26929         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
26930
26931         # To guarantee taht the 'stat' is not blocked
26932         b_status=$(barrier_stat)
26933         [ "$b_status" = "'frozen'" ] ||
26934                 error "(8) unexpected barrier status $b_status"
26935
26936         # let above commands to run at background
26937         sleep 5
26938
26939         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
26940         ps -p $touch_pid || error "(10) touch should be blocked"
26941         ps -p $ln_pid || error "(11) link should be blocked"
26942         ps -p $mv_pid || error "(12) rename should be blocked"
26943         ps -p $rm_pid || error "(13) unlink should be blocked"
26944
26945         b_status=$(barrier_stat)
26946         [ "$b_status" = "'frozen'" ] ||
26947                 error "(14) unexpected barrier status $b_status"
26948
26949         do_facet mgs $LCTL barrier_thaw $FSNAME
26950         b_status=$(barrier_stat)
26951         [ "$b_status" = "'thawed'" ] ||
26952                 error "(15) unexpected barrier status $b_status"
26953
26954         wait $mkdir_pid || error "(16) mkdir should succeed"
26955         wait $touch_pid || error "(17) touch should succeed"
26956         wait $ln_pid || error "(18) link should succeed"
26957         wait $mv_pid || error "(19) rename should succeed"
26958         wait $rm_pid || error "(20) unlink should succeed"
26959
26960         post_801
26961 }
26962 run_test 801b "modification will be blocked by write barrier"
26963
26964 test_801c() {
26965         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26966
26967         prep_801
26968
26969         stop mds2 || error "(1) Fail to stop mds2"
26970
26971         do_facet mgs $LCTL barrier_freeze $FSNAME 30
26972
26973         local b_status=$(barrier_stat)
26974         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
26975                 do_facet mgs $LCTL barrier_thaw $FSNAME
26976                 error "(2) unexpected barrier status $b_status"
26977         }
26978
26979         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26980                 error "(3) Fail to rescan barrier bitmap"
26981
26982         # Do not reduce barrier time - See LU-11873
26983         do_facet mgs $LCTL barrier_freeze $FSNAME 20
26984
26985         b_status=$(barrier_stat)
26986         [ "$b_status" = "'frozen'" ] ||
26987                 error "(4) unexpected barrier status $b_status"
26988
26989         do_facet mgs $LCTL barrier_thaw $FSNAME
26990         b_status=$(barrier_stat)
26991         [ "$b_status" = "'thawed'" ] ||
26992                 error "(5) unexpected barrier status $b_status"
26993
26994         local devname=$(mdsdevname 2)
26995
26996         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
26997
26998         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26999                 error "(7) Fail to rescan barrier bitmap"
27000
27001         post_801
27002 }
27003 run_test 801c "rescan barrier bitmap"
27004
27005 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
27006 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
27007 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
27008 saved_MOUNT_OPTS=$MOUNT_OPTS
27009
27010 cleanup_802a() {
27011         trap 0
27012
27013         stopall
27014         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
27015         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
27016         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
27017         MOUNT_OPTS=$saved_MOUNT_OPTS
27018         setupall
27019 }
27020
27021 test_802a() {
27022         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
27023         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27024         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27025                 skip "Need server version at least 2.9.55"
27026
27027         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
27028
27029         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27030
27031         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27032                 error "(2) Fail to copy"
27033
27034         trap cleanup_802a EXIT
27035
27036         # sync by force before remount as readonly
27037         sync; sync_all_data; sleep 3; sync_all_data
27038
27039         stopall
27040
27041         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
27042         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
27043         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
27044
27045         echo "Mount the server as read only"
27046         setupall server_only || error "(3) Fail to start servers"
27047
27048         echo "Mount client without ro should fail"
27049         mount_client $MOUNT &&
27050                 error "(4) Mount client without 'ro' should fail"
27051
27052         echo "Mount client with ro should succeed"
27053         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
27054         mount_client $MOUNT ||
27055                 error "(5) Mount client with 'ro' should succeed"
27056
27057         echo "Modify should be refused"
27058         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27059
27060         echo "Read should be allowed"
27061         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27062                 error "(7) Read should succeed under ro mode"
27063
27064         cleanup_802a
27065 }
27066 run_test 802a "simulate readonly device"
27067
27068 test_802b() {
27069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27070         remote_mds_nodsh && skip "remote MDS with nodsh"
27071
27072         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27073                 skip "readonly option not available"
27074
27075         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27076
27077         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27078                 error "(2) Fail to copy"
27079
27080         # write back all cached data before setting MDT to readonly
27081         cancel_lru_locks
27082         sync_all_data
27083
27084         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27085         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27086
27087         echo "Modify should be refused"
27088         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27089
27090         echo "Read should be allowed"
27091         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27092                 error "(7) Read should succeed under ro mode"
27093
27094         # disable readonly
27095         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27096 }
27097 run_test 802b "be able to set MDTs to readonly"
27098
27099 test_803a() {
27100         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27101         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27102                 skip "MDS needs to be newer than 2.10.54"
27103
27104         mkdir_on_mdt0 $DIR/$tdir
27105         # Create some objects on all MDTs to trigger related logs objects
27106         for idx in $(seq $MDSCOUNT); do
27107                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27108                         $DIR/$tdir/dir${idx} ||
27109                         error "Fail to create $DIR/$tdir/dir${idx}"
27110         done
27111
27112         sync; sleep 3
27113         wait_delete_completed # ensure old test cleanups are finished
27114         echo "before create:"
27115         $LFS df -i $MOUNT
27116         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27117
27118         for i in {1..10}; do
27119                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27120                         error "Fail to create $DIR/$tdir/foo$i"
27121         done
27122
27123         sync; sleep 3
27124         echo "after create:"
27125         $LFS df -i $MOUNT
27126         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27127
27128         # allow for an llog to be cleaned up during the test
27129         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27130                 error "before ($before_used) + 10 > after ($after_used)"
27131
27132         for i in {1..10}; do
27133                 rm -rf $DIR/$tdir/foo$i ||
27134                         error "Fail to remove $DIR/$tdir/foo$i"
27135         done
27136
27137         sleep 3 # avoid MDT return cached statfs
27138         wait_delete_completed
27139         echo "after unlink:"
27140         $LFS df -i $MOUNT
27141         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27142
27143         # allow for an llog to be created during the test
27144         [ $after_used -le $((before_used + 1)) ] ||
27145                 error "after ($after_used) > before ($before_used) + 1"
27146 }
27147 run_test 803a "verify agent object for remote object"
27148
27149 test_803b() {
27150         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27151         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27152                 skip "MDS needs to be newer than 2.13.56"
27153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27154
27155         for i in $(seq 0 $((MDSCOUNT - 1))); do
27156                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27157         done
27158
27159         local before=0
27160         local after=0
27161
27162         local tmp
27163
27164         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27165         for i in $(seq 0 $((MDSCOUNT - 1))); do
27166                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27167                         awk '/getattr/ { print $2 }')
27168                 before=$((before + tmp))
27169         done
27170         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27171         for i in $(seq 0 $((MDSCOUNT - 1))); do
27172                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27173                         awk '/getattr/ { print $2 }')
27174                 after=$((after + tmp))
27175         done
27176
27177         [ $before -eq $after ] || error "getattr count $before != $after"
27178 }
27179 run_test 803b "remote object can getattr from cache"
27180
27181 test_804() {
27182         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27183         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27184                 skip "MDS needs to be newer than 2.10.54"
27185         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27186
27187         mkdir -p $DIR/$tdir
27188         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27189                 error "Fail to create $DIR/$tdir/dir0"
27190
27191         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27192         local dev=$(mdsdevname 2)
27193
27194         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27195                 grep ${fid} || error "NOT found agent entry for dir0"
27196
27197         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27198                 error "Fail to create $DIR/$tdir/dir1"
27199
27200         touch $DIR/$tdir/dir1/foo0 ||
27201                 error "Fail to create $DIR/$tdir/dir1/foo0"
27202         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27203         local rc=0
27204
27205         for idx in $(seq $MDSCOUNT); do
27206                 dev=$(mdsdevname $idx)
27207                 do_facet mds${idx} \
27208                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27209                         grep ${fid} && rc=$idx
27210         done
27211
27212         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27213                 error "Fail to rename foo0 to foo1"
27214         if [ $rc -eq 0 ]; then
27215                 for idx in $(seq $MDSCOUNT); do
27216                         dev=$(mdsdevname $idx)
27217                         do_facet mds${idx} \
27218                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27219                         grep ${fid} && rc=$idx
27220                 done
27221         fi
27222
27223         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27224                 error "Fail to rename foo1 to foo2"
27225         if [ $rc -eq 0 ]; then
27226                 for idx in $(seq $MDSCOUNT); do
27227                         dev=$(mdsdevname $idx)
27228                         do_facet mds${idx} \
27229                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27230                         grep ${fid} && rc=$idx
27231                 done
27232         fi
27233
27234         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27235
27236         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27237                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27238         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27239                 error "Fail to rename foo2 to foo0"
27240         unlink $DIR/$tdir/dir1/foo0 ||
27241                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27242         rm -rf $DIR/$tdir/dir0 ||
27243                 error "Fail to rm $DIR/$tdir/dir0"
27244
27245         for idx in $(seq $MDSCOUNT); do
27246                 rc=0
27247
27248                 stop mds${idx}
27249                 dev=$(mdsdevname $idx)
27250                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27251                         rc=$?
27252                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27253                         error "mount mds$idx failed"
27254                 df $MOUNT > /dev/null 2>&1
27255
27256                 # e2fsck should not return error
27257                 [ $rc -eq 0 ] ||
27258                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27259         done
27260 }
27261 run_test 804 "verify agent entry for remote entry"
27262
27263 cleanup_805() {
27264         do_facet $SINGLEMDS zfs set quota=$old $fsset
27265         unlinkmany $DIR/$tdir/f- 1000000
27266         trap 0
27267 }
27268
27269 test_805() {
27270         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
27271         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
27272         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
27273                 skip "netfree not implemented before 0.7"
27274         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
27275                 skip "Need MDS version at least 2.10.57"
27276
27277         local fsset
27278         local freekb
27279         local usedkb
27280         local old
27281         local quota
27282         local pref="osd-zfs.$FSNAME-MDT0000."
27283
27284         # limit available space on MDS dataset to meet nospace issue
27285         # quickly. then ZFS 0.7.2 can use reserved space if asked
27286         # properly (using netfree flag in osd_declare_destroy()
27287         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
27288         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
27289                 gawk '{print $3}')
27290         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
27291         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
27292         let "usedkb=usedkb-freekb"
27293         let "freekb=freekb/2"
27294         if let "freekb > 5000"; then
27295                 let "freekb=5000"
27296         fi
27297         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
27298         trap cleanup_805 EXIT
27299         mkdir_on_mdt0 $DIR/$tdir
27300         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
27301                 error "Can't set PFL layout"
27302         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27303         rm -rf $DIR/$tdir || error "not able to remove"
27304         do_facet $SINGLEMDS zfs set quota=$old $fsset
27305         trap 0
27306 }
27307 run_test 805 "ZFS can remove from full fs"
27308
27309 # Size-on-MDS test
27310 check_lsom_data()
27311 {
27312         local file=$1
27313         local expect=$(stat -c %s $file)
27314
27315         check_lsom_size $1 $expect
27316
27317         local blocks=$($LFS getsom -b $file)
27318         expect=$(stat -c %b $file)
27319         [[ $blocks == $expect ]] ||
27320                 error "$file expected blocks: $expect, got: $blocks"
27321 }
27322
27323 check_lsom_size()
27324 {
27325         local size
27326         local expect=$2
27327
27328         cancel_lru_locks mdc
27329
27330         size=$($LFS getsom -s $1)
27331         [[ $size == $expect ]] ||
27332                 error "$file expected size: $expect, got: $size"
27333 }
27334
27335 test_806() {
27336         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27337                 skip "Need MDS version at least 2.11.52"
27338
27339         local bs=1048576
27340
27341         touch $DIR/$tfile || error "touch $tfile failed"
27342
27343         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27344         save_lustre_params client "llite.*.xattr_cache" > $save
27345         lctl set_param llite.*.xattr_cache=0
27346         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27347
27348         # single-threaded write
27349         echo "Test SOM for single-threaded write"
27350         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27351                 error "write $tfile failed"
27352         check_lsom_size $DIR/$tfile $bs
27353
27354         local num=32
27355         local size=$(($num * $bs))
27356         local offset=0
27357         local i
27358
27359         echo "Test SOM for single client multi-threaded($num) write"
27360         $TRUNCATE $DIR/$tfile 0
27361         for ((i = 0; i < $num; i++)); do
27362                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27363                 local pids[$i]=$!
27364                 offset=$((offset + $bs))
27365         done
27366         for (( i=0; i < $num; i++ )); do
27367                 wait ${pids[$i]}
27368         done
27369         check_lsom_size $DIR/$tfile $size
27370
27371         $TRUNCATE $DIR/$tfile 0
27372         for ((i = 0; i < $num; i++)); do
27373                 offset=$((offset - $bs))
27374                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27375                 local pids[$i]=$!
27376         done
27377         for (( i=0; i < $num; i++ )); do
27378                 wait ${pids[$i]}
27379         done
27380         check_lsom_size $DIR/$tfile $size
27381
27382         # multi-client writes
27383         num=$(get_node_count ${CLIENTS//,/ })
27384         size=$(($num * $bs))
27385         offset=0
27386         i=0
27387
27388         echo "Test SOM for multi-client ($num) writes"
27389         $TRUNCATE $DIR/$tfile 0
27390         for client in ${CLIENTS//,/ }; do
27391                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27392                 local pids[$i]=$!
27393                 i=$((i + 1))
27394                 offset=$((offset + $bs))
27395         done
27396         for (( i=0; i < $num; i++ )); do
27397                 wait ${pids[$i]}
27398         done
27399         check_lsom_size $DIR/$tfile $offset
27400
27401         i=0
27402         $TRUNCATE $DIR/$tfile 0
27403         for client in ${CLIENTS//,/ }; do
27404                 offset=$((offset - $bs))
27405                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27406                 local pids[$i]=$!
27407                 i=$((i + 1))
27408         done
27409         for (( i=0; i < $num; i++ )); do
27410                 wait ${pids[$i]}
27411         done
27412         check_lsom_size $DIR/$tfile $size
27413
27414         # verify truncate
27415         echo "Test SOM for truncate"
27416         $TRUNCATE $DIR/$tfile 1048576
27417         check_lsom_size $DIR/$tfile 1048576
27418         $TRUNCATE $DIR/$tfile 1234
27419         check_lsom_size $DIR/$tfile 1234
27420
27421         # verify SOM blocks count
27422         echo "Verify SOM block count"
27423         $TRUNCATE $DIR/$tfile 0
27424         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27425                 error "failed to write file $tfile"
27426         check_lsom_data $DIR/$tfile
27427 }
27428 run_test 806 "Verify Lazy Size on MDS"
27429
27430 test_807() {
27431         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27432         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27433                 skip "Need MDS version at least 2.11.52"
27434
27435         # Registration step
27436         changelog_register || error "changelog_register failed"
27437         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27438         changelog_users $SINGLEMDS | grep -q $cl_user ||
27439                 error "User $cl_user not found in changelog_users"
27440
27441         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27442         save_lustre_params client "llite.*.xattr_cache" > $save
27443         lctl set_param llite.*.xattr_cache=0
27444         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27445
27446         rm -rf $DIR/$tdir || error "rm $tdir failed"
27447         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27448         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27449         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27450         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27451                 error "truncate $tdir/trunc failed"
27452
27453         local bs=1048576
27454         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27455                 error "write $tfile failed"
27456
27457         # multi-client wirtes
27458         local num=$(get_node_count ${CLIENTS//,/ })
27459         local offset=0
27460         local i=0
27461
27462         echo "Test SOM for multi-client ($num) writes"
27463         touch $DIR/$tfile || error "touch $tfile failed"
27464         $TRUNCATE $DIR/$tfile 0
27465         for client in ${CLIENTS//,/ }; do
27466                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27467                 local pids[$i]=$!
27468                 i=$((i + 1))
27469                 offset=$((offset + $bs))
27470         done
27471         for (( i=0; i < $num; i++ )); do
27472                 wait ${pids[$i]}
27473         done
27474
27475         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27476         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27477         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27478         check_lsom_data $DIR/$tdir/trunc
27479         check_lsom_data $DIR/$tdir/single_dd
27480         check_lsom_data $DIR/$tfile
27481
27482         rm -rf $DIR/$tdir
27483         # Deregistration step
27484         changelog_deregister || error "changelog_deregister failed"
27485 }
27486 run_test 807 "verify LSOM syncing tool"
27487
27488 check_som_nologged()
27489 {
27490         local lines=$($LFS changelog $FSNAME-MDT0000 |
27491                 grep 'x=trusted.som' | wc -l)
27492         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27493 }
27494
27495 test_808() {
27496         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27497                 skip "Need MDS version at least 2.11.55"
27498
27499         # Registration step
27500         changelog_register || error "changelog_register failed"
27501
27502         touch $DIR/$tfile || error "touch $tfile failed"
27503         check_som_nologged
27504
27505         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27506                 error "write $tfile failed"
27507         check_som_nologged
27508
27509         $TRUNCATE $DIR/$tfile 1234
27510         check_som_nologged
27511
27512         $TRUNCATE $DIR/$tfile 1048576
27513         check_som_nologged
27514
27515         # Deregistration step
27516         changelog_deregister || error "changelog_deregister failed"
27517 }
27518 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27519
27520 check_som_nodata()
27521 {
27522         $LFS getsom $1
27523         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27524 }
27525
27526 test_809() {
27527         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27528                 skip "Need MDS version at least 2.11.56"
27529
27530         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27531                 error "failed to create DoM-only file $DIR/$tfile"
27532         touch $DIR/$tfile || error "touch $tfile failed"
27533         check_som_nodata $DIR/$tfile
27534
27535         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27536                 error "write $tfile failed"
27537         check_som_nodata $DIR/$tfile
27538
27539         $TRUNCATE $DIR/$tfile 1234
27540         check_som_nodata $DIR/$tfile
27541
27542         $TRUNCATE $DIR/$tfile 4097
27543         check_som_nodata $DIR/$file
27544 }
27545 run_test 809 "Verify no SOM xattr store for DoM-only files"
27546
27547 test_810() {
27548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27549         $GSS && skip_env "could not run with gss"
27550         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27551                 skip "OST < 2.12.58 doesn't align checksum"
27552
27553         set_checksums 1
27554         stack_trap "set_checksums $ORIG_CSUM" EXIT
27555         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27556
27557         local csum
27558         local before
27559         local after
27560         for csum in $CKSUM_TYPES; do
27561                 #define OBD_FAIL_OSC_NO_GRANT   0x411
27562                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
27563                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
27564                         eval set -- $i
27565                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
27566                         before=$(md5sum $DIR/$tfile)
27567                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
27568                         after=$(md5sum $DIR/$tfile)
27569                         [ "$before" == "$after" ] ||
27570                                 error "$csum: $before != $after bs=$1 seek=$2"
27571                 done
27572         done
27573 }
27574 run_test 810 "partial page writes on ZFS (LU-11663)"
27575
27576 test_812a() {
27577         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27578                 skip "OST < 2.12.51 doesn't support this fail_loc"
27579
27580         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27581         # ensure ost1 is connected
27582         stat $DIR/$tfile >/dev/null || error "can't stat"
27583         wait_osc_import_state client ost1 FULL
27584         # no locks, no reqs to let the connection idle
27585         cancel_lru_locks osc
27586
27587         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27588 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27589         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27590         wait_osc_import_state client ost1 CONNECTING
27591         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27592
27593         stat $DIR/$tfile >/dev/null || error "can't stat file"
27594 }
27595 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
27596
27597 test_812b() { # LU-12378
27598         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27599                 skip "OST < 2.12.51 doesn't support this fail_loc"
27600
27601         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
27602         # ensure ost1 is connected
27603         stat $DIR/$tfile >/dev/null || error "can't stat"
27604         wait_osc_import_state client ost1 FULL
27605         # no locks, no reqs to let the connection idle
27606         cancel_lru_locks osc
27607
27608         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27609 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27610         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27611         wait_osc_import_state client ost1 CONNECTING
27612         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27613
27614         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
27615         wait_osc_import_state client ost1 IDLE
27616 }
27617 run_test 812b "do not drop no resend request for idle connect"
27618
27619 test_812c() {
27620         local old
27621
27622         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
27623
27624         $LFS setstripe -c 1 -o 0 $DIR/$tfile
27625         $LFS getstripe $DIR/$tfile
27626         $LCTL set_param osc.*.idle_timeout=10
27627         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
27628         # ensure ost1 is connected
27629         stat $DIR/$tfile >/dev/null || error "can't stat"
27630         wait_osc_import_state client ost1 FULL
27631         # no locks, no reqs to let the connection idle
27632         cancel_lru_locks osc
27633
27634 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
27635         $LCTL set_param fail_loc=0x80000533
27636         sleep 15
27637         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
27638 }
27639 run_test 812c "idle import vs lock enqueue race"
27640
27641 test_813() {
27642         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
27643         [ -z "$file_heat_sav" ] && skip "no file heat support"
27644
27645         local readsample
27646         local writesample
27647         local readbyte
27648         local writebyte
27649         local readsample1
27650         local writesample1
27651         local readbyte1
27652         local writebyte1
27653
27654         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
27655         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
27656
27657         $LCTL set_param -n llite.*.file_heat=1
27658         echo "Turn on file heat"
27659         echo "Period second: $period_second, Decay percentage: $decay_pct"
27660
27661         echo "QQQQ" > $DIR/$tfile
27662         echo "QQQQ" > $DIR/$tfile
27663         echo "QQQQ" > $DIR/$tfile
27664         cat $DIR/$tfile > /dev/null
27665         cat $DIR/$tfile > /dev/null
27666         cat $DIR/$tfile > /dev/null
27667         cat $DIR/$tfile > /dev/null
27668
27669         local out=$($LFS heat_get $DIR/$tfile)
27670
27671         $LFS heat_get $DIR/$tfile
27672         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27673         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27674         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27675         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27676
27677         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
27678         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
27679         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
27680         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
27681
27682         sleep $((period_second + 3))
27683         echo "Sleep $((period_second + 3)) seconds..."
27684         # The recursion formula to calculate the heat of the file f is as
27685         # follow:
27686         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
27687         # Where Hi is the heat value in the period between time points i*I and
27688         # (i+1)*I; Ci is the access count in the period; the symbol P refers
27689         # to the weight of Ci.
27690         out=$($LFS heat_get $DIR/$tfile)
27691         $LFS heat_get $DIR/$tfile
27692         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27693         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27694         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27695         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27696
27697         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
27698                 error "read sample ($readsample) is wrong"
27699         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
27700                 error "write sample ($writesample) is wrong"
27701         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
27702                 error "read bytes ($readbyte) is wrong"
27703         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
27704                 error "write bytes ($writebyte) is wrong"
27705
27706         echo "QQQQ" > $DIR/$tfile
27707         echo "QQQQ" > $DIR/$tfile
27708         echo "QQQQ" > $DIR/$tfile
27709         cat $DIR/$tfile > /dev/null
27710         cat $DIR/$tfile > /dev/null
27711         cat $DIR/$tfile > /dev/null
27712         cat $DIR/$tfile > /dev/null
27713
27714         sleep $((period_second + 3))
27715         echo "Sleep $((period_second + 3)) seconds..."
27716
27717         out=$($LFS heat_get $DIR/$tfile)
27718         $LFS heat_get $DIR/$tfile
27719         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27720         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27721         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27722         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27723
27724         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
27725                 4 * $decay_pct) / 100") -eq 1 ] ||
27726                 error "read sample ($readsample1) is wrong"
27727         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
27728                 3 * $decay_pct) / 100") -eq 1 ] ||
27729                 error "write sample ($writesample1) is wrong"
27730         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
27731                 20 * $decay_pct) / 100") -eq 1 ] ||
27732                 error "read bytes ($readbyte1) is wrong"
27733         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
27734                 15 * $decay_pct) / 100") -eq 1 ] ||
27735                 error "write bytes ($writebyte1) is wrong"
27736
27737         echo "Turn off file heat for the file $DIR/$tfile"
27738         $LFS heat_set -o $DIR/$tfile
27739
27740         echo "QQQQ" > $DIR/$tfile
27741         echo "QQQQ" > $DIR/$tfile
27742         echo "QQQQ" > $DIR/$tfile
27743         cat $DIR/$tfile > /dev/null
27744         cat $DIR/$tfile > /dev/null
27745         cat $DIR/$tfile > /dev/null
27746         cat $DIR/$tfile > /dev/null
27747
27748         out=$($LFS heat_get $DIR/$tfile)
27749         $LFS heat_get $DIR/$tfile
27750         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27751         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27752         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27753         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27754
27755         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27756         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27757         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27758         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27759
27760         echo "Trun on file heat for the file $DIR/$tfile"
27761         $LFS heat_set -O $DIR/$tfile
27762
27763         echo "QQQQ" > $DIR/$tfile
27764         echo "QQQQ" > $DIR/$tfile
27765         echo "QQQQ" > $DIR/$tfile
27766         cat $DIR/$tfile > /dev/null
27767         cat $DIR/$tfile > /dev/null
27768         cat $DIR/$tfile > /dev/null
27769         cat $DIR/$tfile > /dev/null
27770
27771         out=$($LFS heat_get $DIR/$tfile)
27772         $LFS heat_get $DIR/$tfile
27773         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27774         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27775         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27776         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27777
27778         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
27779         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
27780         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
27781         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
27782
27783         $LFS heat_set -c $DIR/$tfile
27784         $LCTL set_param -n llite.*.file_heat=0
27785         echo "Turn off file heat support for the Lustre filesystem"
27786
27787         echo "QQQQ" > $DIR/$tfile
27788         echo "QQQQ" > $DIR/$tfile
27789         echo "QQQQ" > $DIR/$tfile
27790         cat $DIR/$tfile > /dev/null
27791         cat $DIR/$tfile > /dev/null
27792         cat $DIR/$tfile > /dev/null
27793         cat $DIR/$tfile > /dev/null
27794
27795         out=$($LFS heat_get $DIR/$tfile)
27796         $LFS heat_get $DIR/$tfile
27797         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27798         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27799         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27800         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27801
27802         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27803         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27804         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27805         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27806
27807         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
27808         rm -f $DIR/$tfile
27809 }
27810 run_test 813 "File heat verfication"
27811
27812 test_814()
27813 {
27814         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
27815         echo -n y >> $DIR/$tfile
27816         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
27817         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
27818 }
27819 run_test 814 "sparse cp works as expected (LU-12361)"
27820
27821 test_815()
27822 {
27823         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
27824         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
27825 }
27826 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
27827
27828 test_816() {
27829         local ost1_imp=$(get_osc_import_name client ost1)
27830         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27831                          cut -d'.' -f2)
27832
27833         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27834         # ensure ost1 is connected
27835
27836         stat $DIR/$tfile >/dev/null || error "can't stat"
27837         wait_osc_import_state client ost1 FULL
27838         # no locks, no reqs to let the connection idle
27839         cancel_lru_locks osc
27840         lru_resize_disable osc
27841         local before
27842         local now
27843         before=$($LCTL get_param -n \
27844                  ldlm.namespaces.$imp_name.lru_size)
27845
27846         wait_osc_import_state client ost1 IDLE
27847         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
27848         now=$($LCTL get_param -n \
27849               ldlm.namespaces.$imp_name.lru_size)
27850         [ $before == $now ] || error "lru_size changed $before != $now"
27851 }
27852 run_test 816 "do not reset lru_resize on idle reconnect"
27853
27854 cleanup_817() {
27855         umount $tmpdir
27856         exportfs -u localhost:$DIR/nfsexp
27857         rm -rf $DIR/nfsexp
27858 }
27859
27860 test_817() {
27861         systemctl restart nfs-server.service || skip "failed to restart nfsd"
27862
27863         mkdir -p $DIR/nfsexp
27864         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
27865                 error "failed to export nfs"
27866
27867         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
27868         stack_trap cleanup_817 EXIT
27869
27870         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
27871                 error "failed to mount nfs to $tmpdir"
27872
27873         cp /bin/true $tmpdir
27874         $DIR/nfsexp/true || error "failed to execute 'true' command"
27875 }
27876 run_test 817 "nfsd won't cache write lock for exec file"
27877
27878 test_818() {
27879         test_mkdir -i0 -c1 $DIR/$tdir
27880         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
27881         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
27882         stop $SINGLEMDS
27883
27884         # restore osp-syn threads
27885         stack_trap "fail $SINGLEMDS"
27886
27887         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
27888         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
27889         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
27890                 error "start $SINGLEMDS failed"
27891         rm -rf $DIR/$tdir
27892
27893         local testid=$(echo $TESTNAME | tr '_' ' ')
27894
27895         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
27896                 grep "run LFSCK" || error "run LFSCK is not suggested"
27897 }
27898 run_test 818 "unlink with failed llog"
27899
27900 test_819a() {
27901         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27902         cancel_lru_locks osc
27903         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27904         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27905         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
27906         rm -f $TDIR/$tfile
27907 }
27908 run_test 819a "too big niobuf in read"
27909
27910 test_819b() {
27911         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27912         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27913         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27914         cancel_lru_locks osc
27915         sleep 1
27916         rm -f $TDIR/$tfile
27917 }
27918 run_test 819b "too big niobuf in write"
27919
27920
27921 function test_820_start_ost() {
27922         sleep 5
27923
27924         for num in $(seq $OSTCOUNT); do
27925                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
27926         done
27927 }
27928
27929 test_820() {
27930         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27931
27932         mkdir $DIR/$tdir
27933         umount_client $MOUNT || error "umount failed"
27934         for num in $(seq $OSTCOUNT); do
27935                 stop ost$num
27936         done
27937
27938         # mount client with no active OSTs
27939         # so that the client can't initialize max LOV EA size
27940         # from OSC notifications
27941         mount_client $MOUNT || error "mount failed"
27942         # delay OST starting to keep this 0 max EA size for a while
27943         test_820_start_ost &
27944
27945         # create a directory on MDS2
27946         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
27947                 error "Failed to create directory"
27948         # open intent should update default EA size
27949         # see mdc_update_max_ea_from_body()
27950         # notice this is the very first RPC to MDS2
27951         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
27952         ret=$?
27953         echo $out
27954         # With SSK, this situation can lead to -EPERM being returned.
27955         # In that case, simply retry.
27956         if [ $ret -ne 0 ] && $SHARED_KEY; then
27957                 if echo "$out" | grep -q "not permitted"; then
27958                         cp /etc/services $DIR/$tdir/mds2
27959                         ret=$?
27960                 fi
27961         fi
27962         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
27963 }
27964 run_test 820 "update max EA from open intent"
27965
27966 test_822() {
27967         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27968
27969         save_lustre_params mds1 \
27970                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27971         do_facet $SINGLEMDS "$LCTL set_param -n \
27972                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
27973         do_facet $SINGLEMDS "$LCTL set_param -n \
27974                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
27975
27976         # wait for statfs update to clear OS_STATFS_NOPRECREATE
27977         local maxage=$(do_facet mds1 $LCTL get_param -n \
27978                        osp.$FSNAME-OST0000*MDT0000.maxage)
27979         sleep $((maxage + 1))
27980
27981         #define OBD_FAIL_NET_ERROR_RPC          0x532
27982         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
27983
27984         stack_trap "restore_lustre_params < $p; rm $p"
27985
27986         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
27987                       osp.$FSNAME-OST0000*MDT0000.create_count")
27988         for i in $(seq 1 $count); do
27989                 touch $DIR/$tfile.${i} || error "touch failed"
27990         done
27991 }
27992 run_test 822 "test precreate failure"
27993
27994 test_823() {
27995         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27996         local OST_MAX_PRECREATE=20000
27997
27998         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
27999                 skip "Need MDS version at least 2.14.56"
28000
28001         save_lustre_params mds1 \
28002                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28003         do_facet $SINGLEMDS "$LCTL set_param -n \
28004                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
28005         do_facet $SINGLEMDS "$LCTL set_param -n \
28006                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
28007
28008         stack_trap "restore_lustre_params < $p; rm $p"
28009
28010         do_facet $SINGLEMDS "$LCTL set_param -n \
28011                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
28012
28013         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28014                       osp.$FSNAME-OST0000*MDT0000.create_count")
28015         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28016                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
28017         local expect_count=$(((($max/2)/256) * 256))
28018
28019         log "setting create_count to 100200:"
28020         log " -result- count: $count with max: $max, expecting: $expect_count"
28021
28022         [[ $count -eq expect_count ]] ||
28023                 error "Create count not set to max precreate."
28024 }
28025 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28026
28027 test_831() {
28028         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
28029                 skip "Need MDS version 2.14.56"
28030
28031         local sync_changes=$(do_facet $SINGLEMDS \
28032                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28033
28034         [ "$sync_changes" -gt 100 ] &&
28035                 skip "Sync changes $sync_changes > 100 already"
28036
28037         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28038
28039         $LFS mkdir -i 0 $DIR/$tdir
28040         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28041
28042         save_lustre_params mds1 \
28043                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28044         save_lustre_params mds1 \
28045                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28046
28047         do_facet mds1 "$LCTL set_param -n \
28048                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28049                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28050         stack_trap "restore_lustre_params < $p" EXIT
28051
28052         createmany -o $DIR/$tdir/f- 1000
28053         unlinkmany $DIR/$tdir/f- 1000 &
28054         local UNLINK_PID=$!
28055
28056         while sleep 1; do
28057                 sync_changes=$(do_facet mds1 \
28058                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28059                 # the check in the code is racy, fail the test
28060                 # if the value above the limit by 10.
28061                 [ $sync_changes -gt 110 ] && {
28062                         kill -2 $UNLINK_PID
28063                         wait
28064                         error "osp changes throttling failed, $sync_changes>110"
28065                 }
28066                 kill -0 $UNLINK_PID 2> /dev/null || break
28067         done
28068         wait
28069 }
28070 run_test 831 "throttling unlink/setattr queuing on OSP"
28071
28072 #
28073 # tests that do cleanup/setup should be run at the end
28074 #
28075
28076 test_900() {
28077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28078         local ls
28079
28080         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28081         $LCTL set_param fail_loc=0x903
28082
28083         cancel_lru_locks MGC
28084
28085         FAIL_ON_ERROR=true cleanup
28086         FAIL_ON_ERROR=true setup
28087 }
28088 run_test 900 "umount should not race with any mgc requeue thread"
28089
28090 # LUS-6253/LU-11185
28091 test_901() {
28092         local old
28093         local count
28094         local oldc
28095         local newc
28096         local olds
28097         local news
28098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28099
28100         # some get_param have a bug to handle dot in param name
28101         cancel_lru_locks MGC
28102         old=$(mount -t lustre | wc -l)
28103         # 1 config+sptlrpc
28104         # 2 params
28105         # 3 nodemap
28106         # 4 IR
28107         old=$((old * 4))
28108         oldc=0
28109         count=0
28110         while [ $old -ne $oldc ]; do
28111                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28112                 sleep 1
28113                 ((count++))
28114                 if [ $count -ge $TIMEOUT ]; then
28115                         error "too large timeout"
28116                 fi
28117         done
28118         umount_client $MOUNT || error "umount failed"
28119         mount_client $MOUNT || error "mount failed"
28120         cancel_lru_locks MGC
28121         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28122
28123         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28124
28125         return 0
28126 }
28127 run_test 901 "don't leak a mgc lock on client umount"
28128
28129 # LU-13377
28130 test_902() {
28131         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28132                 skip "client does not have LU-13377 fix"
28133         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28134         $LCTL set_param fail_loc=0x1415
28135         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28136         cancel_lru_locks osc
28137         rm -f $DIR/$tfile
28138 }
28139 run_test 902 "test short write doesn't hang lustre"
28140
28141 # LU-14711
28142 test_903() {
28143         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28144         echo "blah" > $DIR/${tfile}-2
28145         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28146         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28147         $LCTL set_param fail_loc=0x417 fail_val=20
28148
28149         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28150         sleep 1 # To start the destroy
28151         wait_destroy_complete 150 || error "Destroy taking too long"
28152         cat $DIR/$tfile > /dev/null || error "Evicted"
28153 }
28154 run_test 903 "Test long page discard does not cause evictions"
28155
28156 test_904() {
28157         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28158         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28159                 grep -q project || skip "skip project quota not supported"
28160
28161         local testfile="$DIR/$tdir/$tfile"
28162         local xattr="trusted.projid"
28163         local projid
28164
28165         mkdir -p $DIR/$tdir
28166         touch $testfile
28167         #should be hidden when projid is 0
28168         $LFS project -p 0 $testfile ||
28169                 error "set $testfile project id failed"
28170         getfattr -m - $testfile | grep $xattr &&
28171                 error "do not show trusted.projid with project ID 0"
28172
28173         #still can getxattr explicitly
28174         projid=$(getfattr -n $xattr $testfile |
28175                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28176         [ $projid == "0" ] ||
28177                 error "projid expected 0 not $projid"
28178
28179         #set the projid via setxattr
28180         setfattr -n $xattr -v "1000" $testfile ||
28181                 error "setattr failed with $?"
28182         projid=($($LFS project $testfile))
28183         [ ${projid[0]} == "1000" ] ||
28184                 error "projid expected 1000 not $projid"
28185
28186         #check the new projid via getxattr
28187         $LFS project -p 1001 $testfile ||
28188                 error "set $testfile project id failed"
28189         projid=$(getfattr -n $xattr $testfile |
28190                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28191         [ $projid == "1001" ] ||
28192                 error "projid expected 1001 not $projid"
28193
28194         #try to set invalid projid
28195         setfattr -n $xattr -v "4294967295" $testfile &&
28196                 error "set invalid projid should fail"
28197
28198         #remove the xattr means setting projid to 0
28199         setfattr -x $xattr $testfile ||
28200                 error "setfattr failed with $?"
28201         projid=($($LFS project $testfile))
28202         [ ${projid[0]} == "0" ] ||
28203                 error "projid expected 0 not $projid"
28204
28205         #should be hidden when parent has inherit flag and same projid
28206         $LFS project -srp 1002 $DIR/$tdir ||
28207                 error "set $tdir project id failed"
28208         getfattr -m - $testfile | grep $xattr &&
28209                 error "do not show trusted.projid with inherit flag"
28210
28211         #still can getxattr explicitly
28212         projid=$(getfattr -n $xattr $testfile |
28213                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28214         [ $projid == "1002" ] ||
28215                 error "projid expected 1002 not $projid"
28216 }
28217 run_test 904 "virtual project ID xattr"
28218
28219 complete $SECONDS
28220 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28221 check_and_cleanup_lustre
28222 if [ "$I_MOUNTED" != "yes" ]; then
28223         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28224 fi
28225 exit_status