Whamcloud - gitweb
a3ffd8cbecded0020ef8760cbcac9b5d2bc995e9
[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         local devname=$(mdsdevname $mds_index)
723
724         echo "stop and checking mds${mds_index}:"
725         # e2fsck should not return error
726         stop mds${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                 local devname=$(mdsdevname $mdt_index)
747                 # e2fsck should not return error
748                 stop mds${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 # createtest also checks that device nodes are created and
3418 # then visible correctly (#2091)
3419 test_28() { # bug 2091
3420         test_mkdir $DIR/d28
3421         $CREATETEST $DIR/d28/ct || error "createtest failed"
3422 }
3423 run_test 28 "create/mknod/mkdir with bad file types ============"
3424
3425 test_29() {
3426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3427
3428         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3429                 disable_opencache
3430                 stack_trap "restore_opencache"
3431         }
3432
3433         sync; sleep 1; sync # flush out any dirty pages from previous tests
3434         cancel_lru_locks
3435         test_mkdir $DIR/d29
3436         touch $DIR/d29/foo
3437         log 'first d29'
3438         ls -l $DIR/d29
3439
3440         declare -i LOCKCOUNTORIG=0
3441         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3442                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3443         done
3444         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3445
3446         declare -i LOCKUNUSEDCOUNTORIG=0
3447         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3448                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3449         done
3450
3451         log 'second d29'
3452         ls -l $DIR/d29
3453         log 'done'
3454
3455         declare -i LOCKCOUNTCURRENT=0
3456         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3457                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3458         done
3459
3460         declare -i LOCKUNUSEDCOUNTCURRENT=0
3461         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3462                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3463         done
3464
3465         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3466                 $LCTL set_param -n ldlm.dump_namespaces ""
3467                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3468                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3469                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3470                 return 2
3471         fi
3472         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3473                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3474                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3475                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3476                 return 3
3477         fi
3478 }
3479 run_test 29 "IT_GETATTR regression  ============================"
3480
3481 test_30a() { # was test_30
3482         cp $(which ls) $DIR || cp /bin/ls $DIR
3483         $DIR/ls / || error "Can't execute binary from lustre"
3484         rm $DIR/ls
3485 }
3486 run_test 30a "execute binary from Lustre (execve) =============="
3487
3488 test_30b() {
3489         cp `which ls` $DIR || cp /bin/ls $DIR
3490         chmod go+rx $DIR/ls
3491         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3492         rm $DIR/ls
3493 }
3494 run_test 30b "execute binary from Lustre as non-root ==========="
3495
3496 test_30c() { # b=22376
3497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3498
3499         cp $(which ls) $DIR || cp /bin/ls $DIR
3500         chmod a-rw $DIR/ls
3501         cancel_lru_locks mdc
3502         cancel_lru_locks osc
3503         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3504         rm -f $DIR/ls
3505 }
3506 run_test 30c "execute binary from Lustre without read perms ===="
3507
3508 test_30d() {
3509         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3510
3511         for i in {1..10}; do
3512                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3513                 local PID=$!
3514                 sleep 1
3515                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3516                 wait $PID || error "executing dd from Lustre failed"
3517                 rm -f $DIR/$tfile
3518         done
3519
3520         rm -f $DIR/dd
3521 }
3522 run_test 30d "execute binary from Lustre while clear locks"
3523
3524 test_31a() {
3525         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3526         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3527 }
3528 run_test 31a "open-unlink file =================================="
3529
3530 test_31b() {
3531         touch $DIR/f31 || error "touch $DIR/f31 failed"
3532         ln $DIR/f31 $DIR/f31b || error "ln failed"
3533         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3534         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3535 }
3536 run_test 31b "unlink file with multiple links while open ======="
3537
3538 test_31c() {
3539         touch $DIR/f31 || error "touch $DIR/f31 failed"
3540         ln $DIR/f31 $DIR/f31c || error "ln failed"
3541         multiop_bg_pause $DIR/f31 O_uc ||
3542                 error "multiop_bg_pause for $DIR/f31 failed"
3543         MULTIPID=$!
3544         $MULTIOP $DIR/f31c Ouc
3545         kill -USR1 $MULTIPID
3546         wait $MULTIPID
3547 }
3548 run_test 31c "open-unlink file with multiple links ============="
3549
3550 test_31d() {
3551         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3552         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3553 }
3554 run_test 31d "remove of open directory ========================="
3555
3556 test_31e() { # bug 2904
3557         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3558 }
3559 run_test 31e "remove of open non-empty directory ==============="
3560
3561 test_31f() { # bug 4554
3562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3563
3564         set -vx
3565         test_mkdir $DIR/d31f
3566         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3567         cp /etc/hosts $DIR/d31f
3568         ls -l $DIR/d31f
3569         $LFS getstripe $DIR/d31f/hosts
3570         multiop_bg_pause $DIR/d31f D_c || return 1
3571         MULTIPID=$!
3572
3573         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3574         test_mkdir $DIR/d31f
3575         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3576         cp /etc/hosts $DIR/d31f
3577         ls -l $DIR/d31f
3578         $LFS getstripe $DIR/d31f/hosts
3579         multiop_bg_pause $DIR/d31f D_c || return 1
3580         MULTIPID2=$!
3581
3582         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3583         wait $MULTIPID || error "first opendir $MULTIPID failed"
3584
3585         sleep 6
3586
3587         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3588         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3589         set +vx
3590 }
3591 run_test 31f "remove of open directory with open-unlink file ==="
3592
3593 test_31g() {
3594         echo "-- cross directory link --"
3595         test_mkdir -c1 $DIR/${tdir}ga
3596         test_mkdir -c1 $DIR/${tdir}gb
3597         touch $DIR/${tdir}ga/f
3598         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3599         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3600         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3601         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3602         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3603 }
3604 run_test 31g "cross directory link==============="
3605
3606 test_31h() {
3607         echo "-- cross directory link --"
3608         test_mkdir -c1 $DIR/${tdir}
3609         test_mkdir -c1 $DIR/${tdir}/dir
3610         touch $DIR/${tdir}/f
3611         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3612         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3613         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3614         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3615         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3616 }
3617 run_test 31h "cross directory link under child==============="
3618
3619 test_31i() {
3620         echo "-- cross directory link --"
3621         test_mkdir -c1 $DIR/$tdir
3622         test_mkdir -c1 $DIR/$tdir/dir
3623         touch $DIR/$tdir/dir/f
3624         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3625         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3626         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3627         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3628         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3629 }
3630 run_test 31i "cross directory link under parent==============="
3631
3632 test_31j() {
3633         test_mkdir -c1 -p $DIR/$tdir
3634         test_mkdir -c1 -p $DIR/$tdir/dir1
3635         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3636         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3637         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3638         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3639         return 0
3640 }
3641 run_test 31j "link for directory==============="
3642
3643 test_31k() {
3644         test_mkdir -c1 -p $DIR/$tdir
3645         touch $DIR/$tdir/s
3646         touch $DIR/$tdir/exist
3647         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3648         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3649         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3650         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3651         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3652         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3653         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3654         return 0
3655 }
3656 run_test 31k "link to file: the same, non-existing, dir==============="
3657
3658 test_31m() {
3659         mkdir $DIR/d31m
3660         touch $DIR/d31m/s
3661         mkdir $DIR/d31m2
3662         touch $DIR/d31m2/exist
3663         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3664         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3665         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3666         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3667         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3668         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3669         return 0
3670 }
3671 run_test 31m "link to file: the same, non-existing, dir==============="
3672
3673 test_31n() {
3674         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3675         nlink=$(stat --format=%h $DIR/$tfile)
3676         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3677         local fd=$(free_fd)
3678         local cmd="exec $fd<$DIR/$tfile"
3679         eval $cmd
3680         cmd="exec $fd<&-"
3681         trap "eval $cmd" EXIT
3682         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3683         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3684         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3685         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3686         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3687         eval $cmd
3688 }
3689 run_test 31n "check link count of unlinked file"
3690
3691 link_one() {
3692         local tempfile=$(mktemp $1_XXXXXX)
3693         mlink $tempfile $1 2> /dev/null &&
3694                 echo "$BASHPID: link $tempfile to $1 succeeded"
3695         munlink $tempfile
3696 }
3697
3698 test_31o() { # LU-2901
3699         test_mkdir $DIR/$tdir
3700         for LOOP in $(seq 100); do
3701                 rm -f $DIR/$tdir/$tfile*
3702                 for THREAD in $(seq 8); do
3703                         link_one $DIR/$tdir/$tfile.$LOOP &
3704                 done
3705                 wait
3706                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3707                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3708                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3709                         break || true
3710         done
3711 }
3712 run_test 31o "duplicate hard links with same filename"
3713
3714 test_31p() {
3715         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3716
3717         test_mkdir $DIR/$tdir
3718         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3719         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3720
3721         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3722                 error "open unlink test1 failed"
3723         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3724                 error "open unlink test2 failed"
3725
3726         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3727                 error "test1 still exists"
3728         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3729                 error "test2 still exists"
3730 }
3731 run_test 31p "remove of open striped directory"
3732
3733 test_31q() {
3734         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3735
3736         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3737         index=$($LFS getdirstripe -i $DIR/$tdir)
3738         [ $index -eq 3 ] || error "first stripe index $index != 3"
3739         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3740         [ $index -eq 1 ] || error "second stripe index $index != 1"
3741
3742         # when "-c <stripe_count>" is set, the number of MDTs specified after
3743         # "-i" should equal to the stripe count
3744         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3745 }
3746 run_test 31q "create striped directory on specific MDTs"
3747
3748 #LU-14949
3749 test_31r() {
3750         touch $DIR/$tfile.target
3751         touch $DIR/$tfile.source
3752
3753         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3754         $LCTL set_param fail_loc=0x1419 fail_val=3
3755         cat $DIR/$tfile.target &
3756         CATPID=$!
3757
3758         # Guarantee open is waiting before we get here
3759         sleep 1
3760         mv $DIR/$tfile.source $DIR/$tfile.target
3761
3762         wait $CATPID
3763         RC=$?
3764         if [[ $RC -ne 0 ]]; then
3765                 error "open with cat failed, rc=$RC"
3766         fi
3767 }
3768 run_test 31r "open-rename(replace) race"
3769
3770 cleanup_test32_mount() {
3771         local rc=0
3772         trap 0
3773         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3774         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3775         losetup -d $loopdev || true
3776         rm -rf $DIR/$tdir
3777         return $rc
3778 }
3779
3780 test_32a() {
3781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3782
3783         echo "== more mountpoints and symlinks ================="
3784         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3785         trap cleanup_test32_mount EXIT
3786         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3787         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3788                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3789         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3790                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3791         cleanup_test32_mount
3792 }
3793 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3794
3795 test_32b() {
3796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3797
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         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3804                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3805         cleanup_test32_mount
3806 }
3807 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3808
3809 test_32c() {
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         test_mkdir -p $DIR/$tdir/d2/test_dir
3818         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3819                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3820         cleanup_test32_mount
3821 }
3822 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3823
3824 test_32d() {
3825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3826
3827         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3828         trap cleanup_test32_mount EXIT
3829         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3830         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3831                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3832         test_mkdir -p $DIR/$tdir/d2/test_dir
3833         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3834                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3835         cleanup_test32_mount
3836 }
3837 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3838
3839 test_32e() {
3840         rm -fr $DIR/$tdir
3841         test_mkdir -p $DIR/$tdir/tmp
3842         local tmp_dir=$DIR/$tdir/tmp
3843         ln -s $DIR/$tdir $tmp_dir/symlink11
3844         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3845         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3846         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3847 }
3848 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3849
3850 test_32f() {
3851         rm -fr $DIR/$tdir
3852         test_mkdir -p $DIR/$tdir/tmp
3853         local tmp_dir=$DIR/$tdir/tmp
3854         ln -s $DIR/$tdir $tmp_dir/symlink11
3855         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3856         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3857         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3858 }
3859 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3860
3861 test_32g() {
3862         local tmp_dir=$DIR/$tdir/tmp
3863         test_mkdir -p $tmp_dir
3864         test_mkdir $DIR/${tdir}2
3865         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3866         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3867         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3868         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3869         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3870         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3871 }
3872 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3873
3874 test_32h() {
3875         rm -fr $DIR/$tdir $DIR/${tdir}2
3876         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         ls $tmp_dir/symlink12 || error "listing symlink12"
3882         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3883 }
3884 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3885
3886 test_32i() {
3887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3888
3889         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3890         trap cleanup_test32_mount EXIT
3891         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3892         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3893                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3894         touch $DIR/$tdir/test_file
3895         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3896                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3897         cleanup_test32_mount
3898 }
3899 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3900
3901 test_32j() {
3902         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3903
3904         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3905         trap cleanup_test32_mount EXIT
3906         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3907         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3908                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3909         touch $DIR/$tdir/test_file
3910         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3911                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3912         cleanup_test32_mount
3913 }
3914 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3915
3916 test_32k() {
3917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3918
3919         rm -fr $DIR/$tdir
3920         trap cleanup_test32_mount EXIT
3921         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3922         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3923                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3924         test_mkdir -p $DIR/$tdir/d2
3925         touch $DIR/$tdir/d2/test_file || error "touch failed"
3926         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3927                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3928         cleanup_test32_mount
3929 }
3930 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3931
3932 test_32l() {
3933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3934
3935         rm -fr $DIR/$tdir
3936         trap cleanup_test32_mount EXIT
3937         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3938         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3939                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3940         test_mkdir -p $DIR/$tdir/d2
3941         touch $DIR/$tdir/d2/test_file || error "touch failed"
3942         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3943                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3944         cleanup_test32_mount
3945 }
3946 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3947
3948 test_32m() {
3949         rm -fr $DIR/d32m
3950         test_mkdir -p $DIR/d32m/tmp
3951         TMP_DIR=$DIR/d32m/tmp
3952         ln -s $DIR $TMP_DIR/symlink11
3953         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3954         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3955                 error "symlink11 not a link"
3956         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3957                 error "symlink01 not a link"
3958 }
3959 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3960
3961 test_32n() {
3962         rm -fr $DIR/d32n
3963         test_mkdir -p $DIR/d32n/tmp
3964         TMP_DIR=$DIR/d32n/tmp
3965         ln -s $DIR $TMP_DIR/symlink11
3966         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3967         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3968         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3969 }
3970 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3971
3972 test_32o() {
3973         touch $DIR/$tfile
3974         test_mkdir -p $DIR/d32o/tmp
3975         TMP_DIR=$DIR/d32o/tmp
3976         ln -s $DIR/$tfile $TMP_DIR/symlink12
3977         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3978         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3979                 error "symlink12 not a link"
3980         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3981         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3982                 error "$DIR/d32o/tmp/symlink12 not file type"
3983         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3984                 error "$DIR/d32o/symlink02 not file type"
3985 }
3986 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3987
3988 test_32p() {
3989         log 32p_1
3990         rm -fr $DIR/d32p
3991         log 32p_2
3992         rm -f $DIR/$tfile
3993         log 32p_3
3994         touch $DIR/$tfile
3995         log 32p_4
3996         test_mkdir -p $DIR/d32p/tmp
3997         log 32p_5
3998         TMP_DIR=$DIR/d32p/tmp
3999         log 32p_6
4000         ln -s $DIR/$tfile $TMP_DIR/symlink12
4001         log 32p_7
4002         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4003         log 32p_8
4004         cat $DIR/d32p/tmp/symlink12 ||
4005                 error "Can't open $DIR/d32p/tmp/symlink12"
4006         log 32p_9
4007         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4008         log 32p_10
4009 }
4010 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4011
4012 test_32q() {
4013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4014
4015         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4016         trap cleanup_test32_mount EXIT
4017         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4018         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4019         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4020                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4021         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4022         cleanup_test32_mount
4023 }
4024 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4025
4026 test_32r() {
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 -q under_the_mount && error || true
4036         cleanup_test32_mount
4037 }
4038 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4039
4040 test_33aa() {
4041         rm -f $DIR/$tfile
4042         touch $DIR/$tfile
4043         chmod 444 $DIR/$tfile
4044         chown $RUNAS_ID $DIR/$tfile
4045         log 33_1
4046         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4047         log 33_2
4048 }
4049 run_test 33aa "write file with mode 444 (should return error)"
4050
4051 test_33a() {
4052         rm -fr $DIR/$tdir
4053         test_mkdir $DIR/$tdir
4054         chown $RUNAS_ID $DIR/$tdir
4055         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4056                 error "$RUNAS create $tdir/$tfile failed"
4057         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4058                 error "open RDWR" || true
4059 }
4060 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4061
4062 test_33b() {
4063         rm -fr $DIR/$tdir
4064         test_mkdir $DIR/$tdir
4065         chown $RUNAS_ID $DIR/$tdir
4066         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4067 }
4068 run_test 33b "test open file with malformed flags (No panic)"
4069
4070 test_33c() {
4071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4072         remote_ost_nodsh && skip "remote OST with nodsh"
4073
4074         local ostnum
4075         local ostname
4076         local write_bytes
4077         local all_zeros
4078
4079         all_zeros=true
4080         test_mkdir $DIR/$tdir
4081         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4082
4083         sync
4084         for ostnum in $(seq $OSTCOUNT); do
4085                 # test-framework's OST numbering is one-based, while Lustre's
4086                 # is zero-based
4087                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4088                 # check if at least some write_bytes stats are counted
4089                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4090                               obdfilter.$ostname.stats |
4091                               awk '/^write_bytes/ {print $7}' )
4092                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4093                 if (( ${write_bytes:-0} > 0 )); then
4094                         all_zeros=false
4095                         break
4096                 fi
4097         done
4098
4099         $all_zeros || return 0
4100
4101         # Write four bytes
4102         echo foo > $DIR/$tdir/bar
4103         # Really write them
4104         sync
4105
4106         # Total up write_bytes after writing.  We'd better find non-zeros.
4107         for ostnum in $(seq $OSTCOUNT); do
4108                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4109                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4110                               obdfilter/$ostname/stats |
4111                               awk '/^write_bytes/ {print $7}' )
4112                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4113                 if (( ${write_bytes:-0} > 0 )); then
4114                         all_zeros=false
4115                         break
4116                 fi
4117         done
4118
4119         if $all_zeros; then
4120                 for ostnum in $(seq $OSTCOUNT); do
4121                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4122                         echo "Check write_bytes is in obdfilter.*.stats:"
4123                         do_facet ost$ostnum lctl get_param -n \
4124                                 obdfilter.$ostname.stats
4125                 done
4126                 error "OST not keeping write_bytes stats (b=22312)"
4127         fi
4128 }
4129 run_test 33c "test write_bytes stats"
4130
4131 test_33d() {
4132         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4134
4135         local MDTIDX=1
4136         local remote_dir=$DIR/$tdir/remote_dir
4137
4138         test_mkdir $DIR/$tdir
4139         $LFS mkdir -i $MDTIDX $remote_dir ||
4140                 error "create remote directory failed"
4141
4142         touch $remote_dir/$tfile
4143         chmod 444 $remote_dir/$tfile
4144         chown $RUNAS_ID $remote_dir/$tfile
4145
4146         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4147
4148         chown $RUNAS_ID $remote_dir
4149         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4150                                         error "create" || true
4151         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4152                                     error "open RDWR" || true
4153         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4154 }
4155 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4156
4157 test_33e() {
4158         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4159
4160         mkdir $DIR/$tdir
4161
4162         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4163         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4164         mkdir $DIR/$tdir/local_dir
4165
4166         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4167         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4168         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4169
4170         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4171                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4172
4173         rmdir $DIR/$tdir/* || error "rmdir failed"
4174
4175         umask 777
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         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4181         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4182         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 777"
4186
4187         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4188
4189         umask 000
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 0"
4200 }
4201 run_test 33e "mkdir and striped directory should have same mode"
4202
4203 cleanup_33f() {
4204         trap 0
4205         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4206 }
4207
4208 test_33f() {
4209         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4210         remote_mds_nodsh && skip "remote MDS with nodsh"
4211
4212         mkdir $DIR/$tdir
4213         chmod go+rwx $DIR/$tdir
4214         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4215         trap cleanup_33f EXIT
4216
4217         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4218                 error "cannot create striped directory"
4219
4220         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4221                 error "cannot create files in striped directory"
4222
4223         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4224                 error "cannot remove files in striped directory"
4225
4226         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4227                 error "cannot remove striped directory"
4228
4229         cleanup_33f
4230 }
4231 run_test 33f "nonroot user can create, access, and remove a striped directory"
4232
4233 test_33g() {
4234         mkdir -p $DIR/$tdir/dir2
4235
4236         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4237         echo $err
4238         [[ $err =~ "exists" ]] || error "Not exists error"
4239 }
4240 run_test 33g "nonroot user create already existing root created file"
4241
4242 test_33h() {
4243         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4244         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4245                 skip "Need MDS version at least 2.13.50"
4246
4247         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4248                 error "mkdir $tdir failed"
4249         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4250
4251         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4252         local index2
4253
4254         for fname in $DIR/$tdir/$tfile.bak \
4255                      $DIR/$tdir/$tfile.SAV \
4256                      $DIR/$tdir/$tfile.orig \
4257                      $DIR/$tdir/$tfile~; do
4258                 touch $fname  || error "touch $fname failed"
4259                 index2=$($LFS getstripe -m $fname)
4260                 [ $index -eq $index2 ] ||
4261                         error "$fname MDT index mismatch $index != $index2"
4262         done
4263
4264         local failed=0
4265         for i in {1..250}; do
4266                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4267                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4268                         touch $fname  || error "touch $fname failed"
4269                         index2=$($LFS getstripe -m $fname)
4270                         if [[ $index != $index2 ]]; then
4271                                 failed=$((failed + 1))
4272                                 echo "$fname MDT index mismatch $index != $index2"
4273                         fi
4274                 done
4275         done
4276         echo "$failed MDT index mismatches"
4277         (( failed < 20 )) || error "MDT index mismatch $failed times"
4278
4279 }
4280 run_test 33h "temp file is located on the same MDT as target"
4281
4282 test_33i()
4283 {
4284         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4285
4286         local FNAME=$(str_repeat 'f' 250)
4287
4288         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4289         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4290
4291         local count
4292         local total
4293
4294         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4295
4296         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4297
4298         lctl --device %$MDC deactivate
4299         stack_trap "lctl --device %$MDC activate"
4300         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4301         total=$(\ls -l $DIR/$tdir | wc -l)
4302         # "ls -l" will list total in the first line
4303         total=$((total - 1))
4304         (( total + count == 1000 )) ||
4305                 error "ls list $total files, $count files on MDT1"
4306 }
4307 run_test 33i "striped directory can be accessed when one MDT is down"
4308
4309 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4310 test_34a() {
4311         rm -f $DIR/f34
4312         $MCREATE $DIR/f34 || error "mcreate failed"
4313         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4314                 error "getstripe failed"
4315         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4316         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4317                 error "getstripe failed"
4318         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4319                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4320 }
4321 run_test 34a "truncate file that has not been opened ==========="
4322
4323 test_34b() {
4324         [ ! -f $DIR/f34 ] && test_34a
4325         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4326                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4327         $OPENFILE -f O_RDONLY $DIR/f34
4328         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4329                 error "getstripe failed"
4330         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4331                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4332 }
4333 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4334
4335 test_34c() {
4336         [ ! -f $DIR/f34 ] && test_34a
4337         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4338                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4339         $OPENFILE -f O_RDWR $DIR/f34
4340         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4341                 error "$LFS getstripe failed"
4342         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4343                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4344 }
4345 run_test 34c "O_RDWR opening file-with-size works =============="
4346
4347 test_34d() {
4348         [ ! -f $DIR/f34 ] && test_34a
4349         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4350                 error "dd failed"
4351         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4352                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4353         rm $DIR/f34
4354 }
4355 run_test 34d "write to sparse file ============================="
4356
4357 test_34e() {
4358         rm -f $DIR/f34e
4359         $MCREATE $DIR/f34e || error "mcreate failed"
4360         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4361         $CHECKSTAT -s 1000 $DIR/f34e ||
4362                 error "Size of $DIR/f34e not equal to 1000 bytes"
4363         $OPENFILE -f O_RDWR $DIR/f34e
4364         $CHECKSTAT -s 1000 $DIR/f34e ||
4365                 error "Size of $DIR/f34e not equal to 1000 bytes"
4366 }
4367 run_test 34e "create objects, some with size and some without =="
4368
4369 test_34f() { # bug 6242, 6243
4370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4371
4372         SIZE34F=48000
4373         rm -f $DIR/f34f
4374         $MCREATE $DIR/f34f || error "mcreate failed"
4375         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4376         dd if=$DIR/f34f of=$TMP/f34f
4377         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4378         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4379         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4380         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4381         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4382 }
4383 run_test 34f "read from a file with no objects until EOF ======="
4384
4385 test_34g() {
4386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4387
4388         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4389                 error "dd failed"
4390         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4391         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4392                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4393         cancel_lru_locks osc
4394         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4395                 error "wrong size after lock cancel"
4396
4397         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4398         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4399                 error "expanding truncate failed"
4400         cancel_lru_locks osc
4401         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4402                 error "wrong expanded size after lock cancel"
4403 }
4404 run_test 34g "truncate long file ==============================="
4405
4406 test_34h() {
4407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4408
4409         local gid=10
4410         local sz=1000
4411
4412         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4413         sync # Flush the cache so that multiop below does not block on cache
4414              # flush when getting the group lock
4415         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4416         MULTIPID=$!
4417
4418         # Since just timed wait is not good enough, let's do a sync write
4419         # that way we are sure enough time for a roundtrip + processing
4420         # passed + 2 seconds of extra margin.
4421         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4422         rm $DIR/${tfile}-1
4423         sleep 2
4424
4425         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4426                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4427                 kill -9 $MULTIPID
4428         fi
4429         wait $MULTIPID
4430         local nsz=`stat -c %s $DIR/$tfile`
4431         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4432 }
4433 run_test 34h "ftruncate file under grouplock should not block"
4434
4435 test_35a() {
4436         cp /bin/sh $DIR/f35a
4437         chmod 444 $DIR/f35a
4438         chown $RUNAS_ID $DIR/f35a
4439         $RUNAS $DIR/f35a && error || true
4440         rm $DIR/f35a
4441 }
4442 run_test 35a "exec file with mode 444 (should return and not leak)"
4443
4444 test_36a() {
4445         rm -f $DIR/f36
4446         utime $DIR/f36 || error "utime failed for MDS"
4447 }
4448 run_test 36a "MDS utime check (mknod, utime)"
4449
4450 test_36b() {
4451         echo "" > $DIR/f36
4452         utime $DIR/f36 || error "utime failed for OST"
4453 }
4454 run_test 36b "OST utime check (open, utime)"
4455
4456 test_36c() {
4457         rm -f $DIR/d36/f36
4458         test_mkdir $DIR/d36
4459         chown $RUNAS_ID $DIR/d36
4460         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4461 }
4462 run_test 36c "non-root MDS utime check (mknod, utime)"
4463
4464 test_36d() {
4465         [ ! -d $DIR/d36 ] && test_36c
4466         echo "" > $DIR/d36/f36
4467         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4468 }
4469 run_test 36d "non-root OST utime check (open, utime)"
4470
4471 test_36e() {
4472         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4473
4474         test_mkdir $DIR/$tdir
4475         touch $DIR/$tdir/$tfile
4476         $RUNAS utime $DIR/$tdir/$tfile &&
4477                 error "utime worked, expected failure" || true
4478 }
4479 run_test 36e "utime on non-owned file (should return error)"
4480
4481 subr_36fh() {
4482         local fl="$1"
4483         local LANG_SAVE=$LANG
4484         local LC_LANG_SAVE=$LC_LANG
4485         export LANG=C LC_LANG=C # for date language
4486
4487         DATESTR="Dec 20  2000"
4488         test_mkdir $DIR/$tdir
4489         lctl set_param fail_loc=$fl
4490         date; date +%s
4491         cp /etc/hosts $DIR/$tdir/$tfile
4492         sync & # write RPC generated with "current" inode timestamp, but delayed
4493         sleep 1
4494         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4495         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4496         cancel_lru_locks $OSC
4497         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4498         date; date +%s
4499         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4500                 echo "BEFORE: $LS_BEFORE" && \
4501                 echo "AFTER : $LS_AFTER" && \
4502                 echo "WANT  : $DATESTR" && \
4503                 error "$DIR/$tdir/$tfile timestamps changed" || true
4504
4505         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4506 }
4507
4508 test_36f() {
4509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4510
4511         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4512         subr_36fh "0x80000214"
4513 }
4514 run_test 36f "utime on file racing with OST BRW write =========="
4515
4516 test_36g() {
4517         remote_ost_nodsh && skip "remote OST with nodsh"
4518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4519         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4520                 skip "Need MDS version at least 2.12.51"
4521
4522         local fmd_max_age
4523         local fmd
4524         local facet="ost1"
4525         local tgt="obdfilter"
4526
4527         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4528
4529         test_mkdir $DIR/$tdir
4530         fmd_max_age=$(do_facet $facet \
4531                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4532                 head -n 1")
4533
4534         echo "FMD max age: ${fmd_max_age}s"
4535         touch $DIR/$tdir/$tfile
4536         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4537                 gawk '{cnt=cnt+$1}  END{print cnt}')
4538         echo "FMD before: $fmd"
4539         [[ $fmd == 0 ]] &&
4540                 error "FMD wasn't create by touch"
4541         sleep $((fmd_max_age + 12))
4542         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4543                 gawk '{cnt=cnt+$1}  END{print cnt}')
4544         echo "FMD after: $fmd"
4545         [[ $fmd == 0 ]] ||
4546                 error "FMD wasn't expired by ping"
4547 }
4548 run_test 36g "FMD cache expiry ====================="
4549
4550 test_36h() {
4551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4552
4553         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4554         subr_36fh "0x80000227"
4555 }
4556 run_test 36h "utime on file racing with OST BRW write =========="
4557
4558 test_36i() {
4559         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4560
4561         test_mkdir $DIR/$tdir
4562         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4563
4564         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4565         local new_mtime=$((mtime + 200))
4566
4567         #change Modify time of striped dir
4568         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4569                         error "change mtime failed"
4570
4571         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4572
4573         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4574 }
4575 run_test 36i "change mtime on striped directory"
4576
4577 # test_37 - duplicate with tests 32q 32r
4578
4579 test_38() {
4580         local file=$DIR/$tfile
4581         touch $file
4582         openfile -f O_DIRECTORY $file
4583         local RC=$?
4584         local ENOTDIR=20
4585         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4586         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4587 }
4588 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4589
4590 test_39a() { # was test_39
4591         touch $DIR/$tfile
4592         touch $DIR/${tfile}2
4593 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4594 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4595 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4596         sleep 2
4597         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4598         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4599                 echo "mtime"
4600                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4601                 echo "atime"
4602                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4603                 echo "ctime"
4604                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4605                 error "O_TRUNC didn't change timestamps"
4606         fi
4607 }
4608 run_test 39a "mtime changed on create"
4609
4610 test_39b() {
4611         test_mkdir -c1 $DIR/$tdir
4612         cp -p /etc/passwd $DIR/$tdir/fopen
4613         cp -p /etc/passwd $DIR/$tdir/flink
4614         cp -p /etc/passwd $DIR/$tdir/funlink
4615         cp -p /etc/passwd $DIR/$tdir/frename
4616         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4617
4618         sleep 1
4619         echo "aaaaaa" >> $DIR/$tdir/fopen
4620         echo "aaaaaa" >> $DIR/$tdir/flink
4621         echo "aaaaaa" >> $DIR/$tdir/funlink
4622         echo "aaaaaa" >> $DIR/$tdir/frename
4623
4624         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4625         local link_new=`stat -c %Y $DIR/$tdir/flink`
4626         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4627         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4628
4629         cat $DIR/$tdir/fopen > /dev/null
4630         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4631         rm -f $DIR/$tdir/funlink2
4632         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4633
4634         for (( i=0; i < 2; i++ )) ; do
4635                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4636                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4637                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4638                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4639
4640                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4641                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4642                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4643                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4644
4645                 cancel_lru_locks $OSC
4646                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4647         done
4648 }
4649 run_test 39b "mtime change on open, link, unlink, rename  ======"
4650
4651 # this should be set to past
4652 TEST_39_MTIME=`date -d "1 year ago" +%s`
4653
4654 # bug 11063
4655 test_39c() {
4656         touch $DIR1/$tfile
4657         sleep 2
4658         local mtime0=`stat -c %Y $DIR1/$tfile`
4659
4660         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4661         local mtime1=`stat -c %Y $DIR1/$tfile`
4662         [ "$mtime1" = $TEST_39_MTIME ] || \
4663                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4664
4665         local d1=`date +%s`
4666         echo hello >> $DIR1/$tfile
4667         local d2=`date +%s`
4668         local mtime2=`stat -c %Y $DIR1/$tfile`
4669         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4670                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4671
4672         mv $DIR1/$tfile $DIR1/$tfile-1
4673
4674         for (( i=0; i < 2; i++ )) ; do
4675                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4676                 [ "$mtime2" = "$mtime3" ] || \
4677                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4678
4679                 cancel_lru_locks $OSC
4680                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4681         done
4682 }
4683 run_test 39c "mtime change on rename ==========================="
4684
4685 # bug 21114
4686 test_39d() {
4687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4688
4689         touch $DIR1/$tfile
4690         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4691
4692         for (( i=0; i < 2; i++ )) ; do
4693                 local mtime=`stat -c %Y $DIR1/$tfile`
4694                 [ $mtime = $TEST_39_MTIME ] || \
4695                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4696
4697                 cancel_lru_locks $OSC
4698                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4699         done
4700 }
4701 run_test 39d "create, utime, stat =============================="
4702
4703 # bug 21114
4704 test_39e() {
4705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4706
4707         touch $DIR1/$tfile
4708         local mtime1=`stat -c %Y $DIR1/$tfile`
4709
4710         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4711
4712         for (( i=0; i < 2; i++ )) ; do
4713                 local mtime2=`stat -c %Y $DIR1/$tfile`
4714                 [ $mtime2 = $TEST_39_MTIME ] || \
4715                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4716
4717                 cancel_lru_locks $OSC
4718                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4719         done
4720 }
4721 run_test 39e "create, stat, utime, stat ========================"
4722
4723 # bug 21114
4724 test_39f() {
4725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4726
4727         touch $DIR1/$tfile
4728         mtime1=`stat -c %Y $DIR1/$tfile`
4729
4730         sleep 2
4731         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4732
4733         for (( i=0; i < 2; i++ )) ; do
4734                 local mtime2=`stat -c %Y $DIR1/$tfile`
4735                 [ $mtime2 = $TEST_39_MTIME ] || \
4736                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4737
4738                 cancel_lru_locks $OSC
4739                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4740         done
4741 }
4742 run_test 39f "create, stat, sleep, utime, stat ================="
4743
4744 # bug 11063
4745 test_39g() {
4746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4747
4748         echo hello >> $DIR1/$tfile
4749         local mtime1=`stat -c %Y $DIR1/$tfile`
4750
4751         sleep 2
4752         chmod o+r $DIR1/$tfile
4753
4754         for (( i=0; i < 2; i++ )) ; do
4755                 local mtime2=`stat -c %Y $DIR1/$tfile`
4756                 [ "$mtime1" = "$mtime2" ] || \
4757                         error "lost mtime: $mtime2, should be $mtime1"
4758
4759                 cancel_lru_locks $OSC
4760                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4761         done
4762 }
4763 run_test 39g "write, chmod, stat ==============================="
4764
4765 # bug 11063
4766 test_39h() {
4767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4768
4769         touch $DIR1/$tfile
4770         sleep 1
4771
4772         local d1=`date`
4773         echo hello >> $DIR1/$tfile
4774         local mtime1=`stat -c %Y $DIR1/$tfile`
4775
4776         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4777         local d2=`date`
4778         if [ "$d1" != "$d2" ]; then
4779                 echo "write and touch not within one second"
4780         else
4781                 for (( i=0; i < 2; i++ )) ; do
4782                         local mtime2=`stat -c %Y $DIR1/$tfile`
4783                         [ "$mtime2" = $TEST_39_MTIME ] || \
4784                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4785
4786                         cancel_lru_locks $OSC
4787                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4788                 done
4789         fi
4790 }
4791 run_test 39h "write, utime within one second, stat ============="
4792
4793 test_39i() {
4794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4795
4796         touch $DIR1/$tfile
4797         sleep 1
4798
4799         echo hello >> $DIR1/$tfile
4800         local mtime1=`stat -c %Y $DIR1/$tfile`
4801
4802         mv $DIR1/$tfile $DIR1/$tfile-1
4803
4804         for (( i=0; i < 2; i++ )) ; do
4805                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4806
4807                 [ "$mtime1" = "$mtime2" ] || \
4808                         error "lost mtime: $mtime2, should be $mtime1"
4809
4810                 cancel_lru_locks $OSC
4811                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4812         done
4813 }
4814 run_test 39i "write, rename, stat =============================="
4815
4816 test_39j() {
4817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4818
4819         start_full_debug_logging
4820         touch $DIR1/$tfile
4821         sleep 1
4822
4823         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4824         lctl set_param fail_loc=0x80000412
4825         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4826                 error "multiop failed"
4827         local multipid=$!
4828         local mtime1=`stat -c %Y $DIR1/$tfile`
4829
4830         mv $DIR1/$tfile $DIR1/$tfile-1
4831
4832         kill -USR1 $multipid
4833         wait $multipid || error "multiop close failed"
4834
4835         for (( i=0; i < 2; i++ )) ; do
4836                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4837                 [ "$mtime1" = "$mtime2" ] ||
4838                         error "mtime is lost on close: $mtime2, " \
4839                               "should be $mtime1"
4840
4841                 cancel_lru_locks
4842                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4843         done
4844         lctl set_param fail_loc=0
4845         stop_full_debug_logging
4846 }
4847 run_test 39j "write, rename, close, stat ======================="
4848
4849 test_39k() {
4850         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4851
4852         touch $DIR1/$tfile
4853         sleep 1
4854
4855         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4856         local multipid=$!
4857         local mtime1=`stat -c %Y $DIR1/$tfile`
4858
4859         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4860
4861         kill -USR1 $multipid
4862         wait $multipid || error "multiop close failed"
4863
4864         for (( i=0; i < 2; i++ )) ; do
4865                 local mtime2=`stat -c %Y $DIR1/$tfile`
4866
4867                 [ "$mtime2" = $TEST_39_MTIME ] || \
4868                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4869
4870                 cancel_lru_locks
4871                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4872         done
4873 }
4874 run_test 39k "write, utime, close, stat ========================"
4875
4876 # this should be set to future
4877 TEST_39_ATIME=`date -d "1 year" +%s`
4878
4879 test_39l() {
4880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4881         remote_mds_nodsh && skip "remote MDS with nodsh"
4882
4883         local atime_diff=$(do_facet $SINGLEMDS \
4884                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4885         rm -rf $DIR/$tdir
4886         mkdir_on_mdt0 $DIR/$tdir
4887
4888         # test setting directory atime to future
4889         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4890         local atime=$(stat -c %X $DIR/$tdir)
4891         [ "$atime" = $TEST_39_ATIME ] ||
4892                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4893
4894         # test setting directory atime from future to now
4895         local now=$(date +%s)
4896         touch -a -d @$now $DIR/$tdir
4897
4898         atime=$(stat -c %X $DIR/$tdir)
4899         [ "$atime" -eq "$now"  ] ||
4900                 error "atime is not updated from future: $atime, $now"
4901
4902         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4903         sleep 3
4904
4905         # test setting directory atime when now > dir atime + atime_diff
4906         local d1=$(date +%s)
4907         ls $DIR/$tdir
4908         local d2=$(date +%s)
4909         cancel_lru_locks mdc
4910         atime=$(stat -c %X $DIR/$tdir)
4911         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4912                 error "atime is not updated  : $atime, should be $d2"
4913
4914         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4915         sleep 3
4916
4917         # test not setting directory atime when now < dir atime + atime_diff
4918         ls $DIR/$tdir
4919         cancel_lru_locks mdc
4920         atime=$(stat -c %X $DIR/$tdir)
4921         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4922                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4923
4924         do_facet $SINGLEMDS \
4925                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4926 }
4927 run_test 39l "directory atime update ==========================="
4928
4929 test_39m() {
4930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4931
4932         touch $DIR1/$tfile
4933         sleep 2
4934         local far_past_mtime=$(date -d "May 29 1953" +%s)
4935         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4936
4937         touch -m -d @$far_past_mtime $DIR1/$tfile
4938         touch -a -d @$far_past_atime $DIR1/$tfile
4939
4940         for (( i=0; i < 2; i++ )) ; do
4941                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4942                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4943                         error "atime or mtime set incorrectly"
4944
4945                 cancel_lru_locks $OSC
4946                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4947         done
4948 }
4949 run_test 39m "test atime and mtime before 1970"
4950
4951 test_39n() { # LU-3832
4952         remote_mds_nodsh && skip "remote MDS with nodsh"
4953
4954         local atime_diff=$(do_facet $SINGLEMDS \
4955                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4956         local atime0
4957         local atime1
4958         local atime2
4959
4960         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4961
4962         rm -rf $DIR/$tfile
4963         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4964         atime0=$(stat -c %X $DIR/$tfile)
4965
4966         sleep 5
4967         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4968         atime1=$(stat -c %X $DIR/$tfile)
4969
4970         sleep 5
4971         cancel_lru_locks mdc
4972         cancel_lru_locks osc
4973         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4974         atime2=$(stat -c %X $DIR/$tfile)
4975
4976         do_facet $SINGLEMDS \
4977                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4978
4979         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4980         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4981 }
4982 run_test 39n "check that O_NOATIME is honored"
4983
4984 test_39o() {
4985         TESTDIR=$DIR/$tdir/$tfile
4986         [ -e $TESTDIR ] && rm -rf $TESTDIR
4987         mkdir -p $TESTDIR
4988         cd $TESTDIR
4989         links1=2
4990         ls
4991         mkdir a b
4992         ls
4993         links2=$(stat -c %h .)
4994         [ $(($links1 + 2)) != $links2 ] &&
4995                 error "wrong links count $(($links1 + 2)) != $links2"
4996         rmdir b
4997         links3=$(stat -c %h .)
4998         [ $(($links1 + 1)) != $links3 ] &&
4999                 error "wrong links count $links1 != $links3"
5000         return 0
5001 }
5002 run_test 39o "directory cached attributes updated after create"
5003
5004 test_39p() {
5005         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5006
5007         local MDTIDX=1
5008         TESTDIR=$DIR/$tdir/$tdir
5009         [ -e $TESTDIR ] && rm -rf $TESTDIR
5010         test_mkdir -p $TESTDIR
5011         cd $TESTDIR
5012         links1=2
5013         ls
5014         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5015         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5016         ls
5017         links2=$(stat -c %h .)
5018         [ $(($links1 + 2)) != $links2 ] &&
5019                 error "wrong links count $(($links1 + 2)) != $links2"
5020         rmdir remote_dir2
5021         links3=$(stat -c %h .)
5022         [ $(($links1 + 1)) != $links3 ] &&
5023                 error "wrong links count $links1 != $links3"
5024         return 0
5025 }
5026 run_test 39p "remote directory cached attributes updated after create ========"
5027
5028 test_39r() {
5029         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5030                 skip "no atime update on old OST"
5031         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5032                 skip_env "ldiskfs only test"
5033         fi
5034
5035         local saved_adiff
5036         saved_adiff=$(do_facet ost1 \
5037                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5038         stack_trap "do_facet ost1 \
5039                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5040
5041         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5042
5043         $LFS setstripe -i 0 $DIR/$tfile
5044         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5045                 error "can't write initial file"
5046         cancel_lru_locks osc
5047
5048         # exceed atime_diff and access file
5049         sleep 6
5050         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5051                 error "can't udpate atime"
5052
5053         local atime_cli=$(stat -c %X $DIR/$tfile)
5054         echo "client atime: $atime_cli"
5055         # allow atime update to be written to device
5056         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5057         sleep 5
5058
5059         local ostdev=$(ostdevname 1)
5060         local fid=($(lfs getstripe -y $DIR/$tfile |
5061                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
5062         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
5063         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5064
5065         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5066         local atime_ost=$(do_facet ost1 "$cmd" |&
5067                           awk -F'[: ]' '/atime:/ { print $4 }')
5068         (( atime_cli == atime_ost )) ||
5069                 error "atime on client $atime_cli != ost $atime_ost"
5070 }
5071 run_test 39r "lazy atime update on OST"
5072
5073 test_39q() { # LU-8041
5074         local testdir=$DIR/$tdir
5075         mkdir -p $testdir
5076         multiop_bg_pause $testdir D_c || error "multiop failed"
5077         local multipid=$!
5078         cancel_lru_locks mdc
5079         kill -USR1 $multipid
5080         local atime=$(stat -c %X $testdir)
5081         [ "$atime" -ne 0 ] || error "atime is zero"
5082 }
5083 run_test 39q "close won't zero out atime"
5084
5085 test_40() {
5086         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5087         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5088                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5089         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5090                 error "$tfile is not 4096 bytes in size"
5091 }
5092 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5093
5094 test_41() {
5095         # bug 1553
5096         small_write $DIR/f41 18
5097 }
5098 run_test 41 "test small file write + fstat ====================="
5099
5100 count_ost_writes() {
5101         lctl get_param -n ${OSC}.*.stats |
5102                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5103                         END { printf("%0.0f", writes) }'
5104 }
5105
5106 # decent default
5107 WRITEBACK_SAVE=500
5108 DIRTY_RATIO_SAVE=40
5109 MAX_DIRTY_RATIO=50
5110 BG_DIRTY_RATIO_SAVE=10
5111 MAX_BG_DIRTY_RATIO=25
5112
5113 start_writeback() {
5114         trap 0
5115         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5116         # dirty_ratio, dirty_background_ratio
5117         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5118                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5119                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5120                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5121         else
5122                 # if file not here, we are a 2.4 kernel
5123                 kill -CONT `pidof kupdated`
5124         fi
5125 }
5126
5127 stop_writeback() {
5128         # setup the trap first, so someone cannot exit the test at the
5129         # exact wrong time and mess up a machine
5130         trap start_writeback EXIT
5131         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5132         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5133                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5134                 sysctl -w vm.dirty_writeback_centisecs=0
5135                 sysctl -w vm.dirty_writeback_centisecs=0
5136                 # save and increase /proc/sys/vm/dirty_ratio
5137                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5138                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5139                 # save and increase /proc/sys/vm/dirty_background_ratio
5140                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5141                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5142         else
5143                 # if file not here, we are a 2.4 kernel
5144                 kill -STOP `pidof kupdated`
5145         fi
5146 }
5147
5148 # ensure that all stripes have some grant before we test client-side cache
5149 setup_test42() {
5150         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5151                 dd if=/dev/zero of=$i bs=4k count=1
5152                 rm $i
5153         done
5154 }
5155
5156 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5157 # file truncation, and file removal.
5158 test_42a() {
5159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5160
5161         setup_test42
5162         cancel_lru_locks $OSC
5163         stop_writeback
5164         sync; sleep 1; sync # just to be safe
5165         BEFOREWRITES=`count_ost_writes`
5166         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5167         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5168         AFTERWRITES=`count_ost_writes`
5169         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5170                 error "$BEFOREWRITES < $AFTERWRITES"
5171         start_writeback
5172 }
5173 run_test 42a "ensure that we don't flush on close"
5174
5175 test_42b() {
5176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5177
5178         setup_test42
5179         cancel_lru_locks $OSC
5180         stop_writeback
5181         sync
5182         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5183         BEFOREWRITES=$(count_ost_writes)
5184         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5185         AFTERWRITES=$(count_ost_writes)
5186         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5187                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5188         fi
5189         BEFOREWRITES=$(count_ost_writes)
5190         sync || error "sync: $?"
5191         AFTERWRITES=$(count_ost_writes)
5192         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5193                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5194         fi
5195         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5196         start_writeback
5197         return 0
5198 }
5199 run_test 42b "test destroy of file with cached dirty data ======"
5200
5201 # if these tests just want to test the effect of truncation,
5202 # they have to be very careful.  consider:
5203 # - the first open gets a {0,EOF}PR lock
5204 # - the first write conflicts and gets a {0, count-1}PW
5205 # - the rest of the writes are under {count,EOF}PW
5206 # - the open for truncate tries to match a {0,EOF}PR
5207 #   for the filesize and cancels the PWs.
5208 # any number of fixes (don't get {0,EOF} on open, match
5209 # composite locks, do smarter file size management) fix
5210 # this, but for now we want these tests to verify that
5211 # the cancellation with truncate intent works, so we
5212 # start the file with a full-file pw lock to match against
5213 # until the truncate.
5214 trunc_test() {
5215         test=$1
5216         file=$DIR/$test
5217         offset=$2
5218         cancel_lru_locks $OSC
5219         stop_writeback
5220         # prime the file with 0,EOF PW to match
5221         touch $file
5222         $TRUNCATE $file 0
5223         sync; sync
5224         # now the real test..
5225         dd if=/dev/zero of=$file bs=1024 count=100
5226         BEFOREWRITES=`count_ost_writes`
5227         $TRUNCATE $file $offset
5228         cancel_lru_locks $OSC
5229         AFTERWRITES=`count_ost_writes`
5230         start_writeback
5231 }
5232
5233 test_42c() {
5234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5235
5236         trunc_test 42c 1024
5237         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5238                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5239         rm $file
5240 }
5241 run_test 42c "test partial truncate of file with cached dirty data"
5242
5243 test_42d() {
5244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5245
5246         trunc_test 42d 0
5247         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5248                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5249         rm $file
5250 }
5251 run_test 42d "test complete truncate of file with cached dirty data"
5252
5253 test_42e() { # bug22074
5254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5255
5256         local TDIR=$DIR/${tdir}e
5257         local pages=16 # hardcoded 16 pages, don't change it.
5258         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5259         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5260         local max_dirty_mb
5261         local warmup_files
5262
5263         test_mkdir $DIR/${tdir}e
5264         $LFS setstripe -c 1 $TDIR
5265         createmany -o $TDIR/f $files
5266
5267         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5268
5269         # we assume that with $OSTCOUNT files, at least one of them will
5270         # be allocated on OST0.
5271         warmup_files=$((OSTCOUNT * max_dirty_mb))
5272         createmany -o $TDIR/w $warmup_files
5273
5274         # write a large amount of data into one file and sync, to get good
5275         # avail_grant number from OST.
5276         for ((i=0; i<$warmup_files; i++)); do
5277                 idx=$($LFS getstripe -i $TDIR/w$i)
5278                 [ $idx -ne 0 ] && continue
5279                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5280                 break
5281         done
5282         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5283         sync
5284         $LCTL get_param $proc_osc0/cur_dirty_bytes
5285         $LCTL get_param $proc_osc0/cur_grant_bytes
5286
5287         # create as much dirty pages as we can while not to trigger the actual
5288         # RPCs directly. but depends on the env, VFS may trigger flush during this
5289         # period, hopefully we are good.
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=1M count=1 2>/dev/null
5294         done
5295         $LCTL get_param $proc_osc0/cur_dirty_bytes
5296         $LCTL get_param $proc_osc0/cur_grant_bytes
5297
5298         # perform the real test
5299         $LCTL set_param $proc_osc0/rpc_stats 0
5300         for ((;i<$files; i++)); do
5301                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5302                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5303         done
5304         sync
5305         $LCTL get_param $proc_osc0/rpc_stats
5306
5307         local percent=0
5308         local have_ppr=false
5309         $LCTL get_param $proc_osc0/rpc_stats |
5310                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5311                         # skip lines until we are at the RPC histogram data
5312                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5313                         $have_ppr || continue
5314
5315                         # we only want the percent stat for < 16 pages
5316                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5317
5318                         percent=$((percent + WPCT))
5319                         if [[ $percent -gt 15 ]]; then
5320                                 error "less than 16-pages write RPCs" \
5321                                       "$percent% > 15%"
5322                                 break
5323                         fi
5324                 done
5325         rm -rf $TDIR
5326 }
5327 run_test 42e "verify sub-RPC writes are not done synchronously"
5328
5329 test_43A() { # was test_43
5330         test_mkdir $DIR/$tdir
5331         cp -p /bin/ls $DIR/$tdir/$tfile
5332         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5333         pid=$!
5334         # give multiop a chance to open
5335         sleep 1
5336
5337         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5338         kill -USR1 $pid
5339         # Wait for multiop to exit
5340         wait $pid
5341 }
5342 run_test 43A "execution of file opened for write should return -ETXTBSY"
5343
5344 test_43a() {
5345         test_mkdir $DIR/$tdir
5346         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5347         $DIR/$tdir/sleep 60 &
5348         SLEEP_PID=$!
5349         # Make sure exec of $tdir/sleep wins race with truncate
5350         sleep 1
5351         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5352         kill $SLEEP_PID
5353 }
5354 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5355
5356 test_43b() {
5357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5358
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         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5366         kill $SLEEP_PID
5367 }
5368 run_test 43b "truncate of file being executed should return -ETXTBSY"
5369
5370 test_43c() {
5371         local testdir="$DIR/$tdir"
5372         test_mkdir $testdir
5373         cp $SHELL $testdir/
5374         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5375                 ( cd $testdir && md5sum -c )
5376 }
5377 run_test 43c "md5sum of copy into lustre"
5378
5379 test_44A() { # was test_44
5380         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5381
5382         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5383         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5384 }
5385 run_test 44A "zero length read from a sparse stripe"
5386
5387 test_44a() {
5388         local nstripe=$($LFS getstripe -c -d $DIR)
5389         [ -z "$nstripe" ] && skip "can't get stripe info"
5390         [[ $nstripe -gt $OSTCOUNT ]] &&
5391                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5392
5393         local stride=$($LFS getstripe -S -d $DIR)
5394         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5395                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5396         fi
5397
5398         OFFSETS="0 $((stride/2)) $((stride-1))"
5399         for offset in $OFFSETS; do
5400                 for i in $(seq 0 $((nstripe-1))); do
5401                         local GLOBALOFFSETS=""
5402                         # size in Bytes
5403                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5404                         local myfn=$DIR/d44a-$size
5405                         echo "--------writing $myfn at $size"
5406                         ll_sparseness_write $myfn $size ||
5407                                 error "ll_sparseness_write"
5408                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5409                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5410                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5411
5412                         for j in $(seq 0 $((nstripe-1))); do
5413                                 # size in Bytes
5414                                 size=$((((j + $nstripe )*$stride + $offset)))
5415                                 ll_sparseness_write $myfn $size ||
5416                                         error "ll_sparseness_write"
5417                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5418                         done
5419                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5420                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5421                         rm -f $myfn
5422                 done
5423         done
5424 }
5425 run_test 44a "test sparse pwrite ==============================="
5426
5427 dirty_osc_total() {
5428         tot=0
5429         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5430                 tot=$(($tot + $d))
5431         done
5432         echo $tot
5433 }
5434 do_dirty_record() {
5435         before=`dirty_osc_total`
5436         echo executing "\"$*\""
5437         eval $*
5438         after=`dirty_osc_total`
5439         echo before $before, after $after
5440 }
5441 test_45() {
5442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5443
5444         f="$DIR/f45"
5445         # Obtain grants from OST if it supports it
5446         echo blah > ${f}_grant
5447         stop_writeback
5448         sync
5449         do_dirty_record "echo blah > $f"
5450         [[ $before -eq $after ]] && error "write wasn't cached"
5451         do_dirty_record "> $f"
5452         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5453         do_dirty_record "echo blah > $f"
5454         [[ $before -eq $after ]] && error "write wasn't cached"
5455         do_dirty_record "sync"
5456         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5457         do_dirty_record "echo blah > $f"
5458         [[ $before -eq $after ]] && error "write wasn't cached"
5459         do_dirty_record "cancel_lru_locks osc"
5460         [[ $before -gt $after ]] ||
5461                 error "lock cancellation didn't lower dirty count"
5462         start_writeback
5463 }
5464 run_test 45 "osc io page accounting ============================"
5465
5466 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5467 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5468 # objects offset and an assert hit when an rpc was built with 1023's mapped
5469 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5470 test_46() {
5471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5472
5473         f="$DIR/f46"
5474         stop_writeback
5475         sync
5476         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5477         sync
5478         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5479         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5480         sync
5481         start_writeback
5482 }
5483 run_test 46 "dirtying a previously written page ================"
5484
5485 # test_47 is removed "Device nodes check" is moved to test_28
5486
5487 test_48a() { # bug 2399
5488         [ "$mds1_FSTYPE" = "zfs" ] &&
5489         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5490                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5491
5492         test_mkdir $DIR/$tdir
5493         cd $DIR/$tdir
5494         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5495         test_mkdir $DIR/$tdir
5496         touch foo || error "'touch foo' failed after recreating cwd"
5497         test_mkdir bar
5498         touch .foo || error "'touch .foo' failed after recreating cwd"
5499         test_mkdir .bar
5500         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5501         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5502         cd . || error "'cd .' failed after recreating cwd"
5503         mkdir . && error "'mkdir .' worked after recreating cwd"
5504         rmdir . && error "'rmdir .' worked after recreating cwd"
5505         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5506         cd .. || error "'cd ..' failed after recreating cwd"
5507 }
5508 run_test 48a "Access renamed working dir (should return errors)="
5509
5510 test_48b() { # bug 2399
5511         rm -rf $DIR/$tdir
5512         test_mkdir $DIR/$tdir
5513         cd $DIR/$tdir
5514         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5515         touch foo && error "'touch foo' worked after removing cwd"
5516         mkdir foo && error "'mkdir foo' worked after removing cwd"
5517         touch .foo && error "'touch .foo' worked after removing cwd"
5518         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5519         ls . > /dev/null && error "'ls .' worked after removing cwd"
5520         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5521         mkdir . && error "'mkdir .' worked after removing cwd"
5522         rmdir . && error "'rmdir .' worked after removing cwd"
5523         ln -s . foo && error "'ln -s .' worked after removing cwd"
5524         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5525 }
5526 run_test 48b "Access removed working dir (should return errors)="
5527
5528 test_48c() { # bug 2350
5529         #lctl set_param debug=-1
5530         #set -vx
5531         rm -rf $DIR/$tdir
5532         test_mkdir -p $DIR/$tdir/dir
5533         cd $DIR/$tdir/dir
5534         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5535         $TRACE touch foo && error "touch foo worked after removing cwd"
5536         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5537         touch .foo && error "touch .foo worked after removing cwd"
5538         mkdir .foo && error "mkdir .foo worked after removing cwd"
5539         $TRACE ls . && error "'ls .' worked after removing cwd"
5540         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5541         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5542         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5543         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5544         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5545 }
5546 run_test 48c "Access removed working subdir (should return errors)"
5547
5548 test_48d() { # bug 2350
5549         #lctl set_param debug=-1
5550         #set -vx
5551         rm -rf $DIR/$tdir
5552         test_mkdir -p $DIR/$tdir/dir
5553         cd $DIR/$tdir/dir
5554         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5555         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5556         $TRACE touch foo && error "'touch foo' worked after removing parent"
5557         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5558         touch .foo && error "'touch .foo' worked after removing parent"
5559         mkdir .foo && error "mkdir .foo worked after removing parent"
5560         $TRACE ls . && error "'ls .' worked after removing parent"
5561         $TRACE ls .. && error "'ls ..' worked after removing parent"
5562         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5563         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5564         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5565         true
5566 }
5567 run_test 48d "Access removed parent subdir (should return errors)"
5568
5569 test_48e() { # bug 4134
5570         #lctl set_param debug=-1
5571         #set -vx
5572         rm -rf $DIR/$tdir
5573         test_mkdir -p $DIR/$tdir/dir
5574         cd $DIR/$tdir/dir
5575         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5576         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5577         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5578         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5579         # On a buggy kernel addition of "touch foo" after cd .. will
5580         # produce kernel oops in lookup_hash_it
5581         touch ../foo && error "'cd ..' worked after recreate parent"
5582         cd $DIR
5583         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5584 }
5585 run_test 48e "Access to recreated parent subdir (should return errors)"
5586
5587 test_48f() {
5588         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5589                 skip "need MDS >= 2.13.55"
5590         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5591         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5592                 skip "needs different host for mdt1 mdt2"
5593         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5594
5595         $LFS mkdir -i0 $DIR/$tdir
5596         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5597
5598         for d in sub1 sub2 sub3; do
5599                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5600                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5601                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5602         done
5603
5604         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5605 }
5606 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5607
5608 test_49() { # LU-1030
5609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5610         remote_ost_nodsh && skip "remote OST with nodsh"
5611
5612         # get ost1 size - $FSNAME-OST0000
5613         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5614                 awk '{ print $4 }')
5615         # write 800M at maximum
5616         [[ $ost1_size -lt 2 ]] && ost1_size=2
5617         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5618
5619         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5620         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5621         local dd_pid=$!
5622
5623         # change max_pages_per_rpc while writing the file
5624         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5625         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5626         # loop until dd process exits
5627         while ps ax -opid | grep -wq $dd_pid; do
5628                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5629                 sleep $((RANDOM % 5 + 1))
5630         done
5631         # restore original max_pages_per_rpc
5632         $LCTL set_param $osc1_mppc=$orig_mppc
5633         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5634 }
5635 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5636
5637 test_50() {
5638         # bug 1485
5639         test_mkdir $DIR/$tdir
5640         cd $DIR/$tdir
5641         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5642 }
5643 run_test 50 "special situations: /proc symlinks  ==============="
5644
5645 test_51a() {    # was test_51
5646         # bug 1516 - create an empty entry right after ".." then split dir
5647         test_mkdir -c1 $DIR/$tdir
5648         touch $DIR/$tdir/foo
5649         $MCREATE $DIR/$tdir/bar
5650         rm $DIR/$tdir/foo
5651         createmany -m $DIR/$tdir/longfile 201
5652         FNUM=202
5653         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5654                 $MCREATE $DIR/$tdir/longfile$FNUM
5655                 FNUM=$(($FNUM + 1))
5656                 echo -n "+"
5657         done
5658         echo
5659         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5660 }
5661 run_test 51a "special situations: split htree with empty entry =="
5662
5663 cleanup_print_lfs_df () {
5664         trap 0
5665         $LFS df
5666         $LFS df -i
5667 }
5668
5669 test_51b() {
5670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5671
5672         local dir=$DIR/$tdir
5673         local nrdirs=$((65536 + 100))
5674
5675         # cleanup the directory
5676         rm -fr $dir
5677
5678         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5679
5680         $LFS df
5681         $LFS df -i
5682         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5683         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5684         [[ $numfree -lt $nrdirs ]] &&
5685                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5686
5687         # need to check free space for the directories as well
5688         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5689         numfree=$(( blkfree / $(fs_inode_ksize) ))
5690         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5691
5692         trap cleanup_print_lfs_df EXIT
5693
5694         # create files
5695         createmany -d $dir/d $nrdirs || {
5696                 unlinkmany $dir/d $nrdirs
5697                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5698         }
5699
5700         # really created :
5701         nrdirs=$(ls -U $dir | wc -l)
5702
5703         # unlink all but 100 subdirectories, then check it still works
5704         local left=100
5705         local delete=$((nrdirs - left))
5706
5707         $LFS df
5708         $LFS df -i
5709
5710         # for ldiskfs the nlink count should be 1, but this is OSD specific
5711         # and so this is listed for informational purposes only
5712         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5713         unlinkmany -d $dir/d $delete ||
5714                 error "unlink of first $delete subdirs failed"
5715
5716         echo "nlink between: $(stat -c %h $dir)"
5717         local found=$(ls -U $dir | wc -l)
5718         [ $found -ne $left ] &&
5719                 error "can't find subdirs: found only $found, expected $left"
5720
5721         unlinkmany -d $dir/d $delete $left ||
5722                 error "unlink of second $left subdirs failed"
5723         # regardless of whether the backing filesystem tracks nlink accurately
5724         # or not, the nlink count shouldn't be more than "." and ".." here
5725         local after=$(stat -c %h $dir)
5726         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5727                 echo "nlink after: $after"
5728
5729         cleanup_print_lfs_df
5730 }
5731 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5732
5733 test_51d() {
5734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5735         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5736         local qos_old
5737
5738         test_mkdir $DIR/$tdir
5739         $LFS setstripe -c $OSTCOUNT $DIR/$tdir
5740
5741         qos_old=$(do_facet mds1 \
5742                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5743         do_nodes $(comma_list $(mdts_nodes)) \
5744                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5745         stack_trap "do_nodes $(comma_list $(mdts_nodes)) \
5746                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5747
5748         createmany -o $DIR/$tdir/t- 1000
5749         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5750         for ((n = 0; n < $OSTCOUNT; n++)); do
5751                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5752                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5753                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5754                             '($1 == '$n') { objs += 1 } \
5755                             END { printf("%0.0f", objs) }')
5756                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5757         done
5758         unlinkmany $DIR/$tdir/t- 1000
5759
5760         nlast=0
5761         for ((n = 0; n < $OSTCOUNT; n++)); do
5762                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5763                         { $LFS df && $LFS df -i &&
5764                         error "OST $n has fewer objects vs. OST $nlast" \
5765                               " (${objs[$n]} < ${objs[$nlast]}"; }
5766                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5767                         { $LFS df && $LFS df -i &&
5768                         error "OST $n has fewer objects vs. OST $nlast" \
5769                               " (${objs[$n]} < ${objs[$nlast]}"; }
5770
5771                 (( ${objs0[$n]} > ${objs0[$nlast]} * 4 / 5 )) ||
5772                         { $LFS df && $LFS df -i &&
5773                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5774                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5775                 (( ${objs0[$n]} < ${objs0[$nlast]} * 5 / 4 )) ||
5776                         { $LFS df && $LFS df -i &&
5777                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5778                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5779                 nlast=$n
5780         done
5781 }
5782 run_test 51d "check object distribution"
5783
5784 test_51e() {
5785         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5786                 skip_env "ldiskfs only test"
5787         fi
5788
5789         test_mkdir -c1 $DIR/$tdir
5790         test_mkdir -c1 $DIR/$tdir/d0
5791
5792         touch $DIR/$tdir/d0/foo
5793         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5794                 error "file exceed 65000 nlink limit!"
5795         unlinkmany $DIR/$tdir/d0/f- 65001
5796         return 0
5797 }
5798 run_test 51e "check file nlink limit"
5799
5800 test_51f() {
5801         test_mkdir $DIR/$tdir
5802
5803         local max=100000
5804         local ulimit_old=$(ulimit -n)
5805         local spare=20 # number of spare fd's for scripts/libraries, etc.
5806         local mdt=$($LFS getstripe -m $DIR/$tdir)
5807         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5808
5809         echo "MDT$mdt numfree=$numfree, max=$max"
5810         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5811         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5812                 while ! ulimit -n $((numfree + spare)); do
5813                         numfree=$((numfree * 3 / 4))
5814                 done
5815                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5816         else
5817                 echo "left ulimit at $ulimit_old"
5818         fi
5819
5820         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5821                 unlinkmany $DIR/$tdir/f $numfree
5822                 error "create+open $numfree files in $DIR/$tdir failed"
5823         }
5824         ulimit -n $ulimit_old
5825
5826         # if createmany exits at 120s there will be fewer than $numfree files
5827         unlinkmany $DIR/$tdir/f $numfree || true
5828 }
5829 run_test 51f "check many open files limit"
5830
5831 test_52a() {
5832         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5833         test_mkdir $DIR/$tdir
5834         touch $DIR/$tdir/foo
5835         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5836         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5837         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5838         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5839         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5840                                         error "link worked"
5841         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5842         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5843         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5844                                                      error "lsattr"
5845         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5846         cp -r $DIR/$tdir $TMP/
5847         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5848 }
5849 run_test 52a "append-only flag test (should return errors)"
5850
5851 test_52b() {
5852         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5853         test_mkdir $DIR/$tdir
5854         touch $DIR/$tdir/foo
5855         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5856         cat test > $DIR/$tdir/foo && error "cat test worked"
5857         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5858         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5859         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5860                                         error "link worked"
5861         echo foo >> $DIR/$tdir/foo && error "echo worked"
5862         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5863         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5864         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5865         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5866                                                         error "lsattr"
5867         chattr -i $DIR/$tdir/foo || error "chattr failed"
5868
5869         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5870 }
5871 run_test 52b "immutable flag test (should return errors) ======="
5872
5873 test_53() {
5874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5875         remote_mds_nodsh && skip "remote MDS with nodsh"
5876         remote_ost_nodsh && skip "remote OST with nodsh"
5877
5878         local param
5879         local param_seq
5880         local ostname
5881         local mds_last
5882         local mds_last_seq
5883         local ost_last
5884         local ost_last_seq
5885         local ost_last_id
5886         local ostnum
5887         local node
5888         local found=false
5889         local support_last_seq=true
5890
5891         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5892                 support_last_seq=false
5893
5894         # only test MDT0000
5895         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5896         local value
5897         for value in $(do_facet $SINGLEMDS \
5898                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5899                 param=$(echo ${value[0]} | cut -d "=" -f1)
5900                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5901
5902                 if $support_last_seq; then
5903                         param_seq=$(echo $param |
5904                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5905                         mds_last_seq=$(do_facet $SINGLEMDS \
5906                                        $LCTL get_param -n $param_seq)
5907                 fi
5908                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5909
5910                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5911                 node=$(facet_active_host ost$((ostnum+1)))
5912                 param="obdfilter.$ostname.last_id"
5913                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5914                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5915                         ost_last_id=$ost_last
5916
5917                         if $support_last_seq; then
5918                                 ost_last_id=$(echo $ost_last |
5919                                               awk -F':' '{print $2}' |
5920                                               sed -e "s/^0x//g")
5921                                 ost_last_seq=$(echo $ost_last |
5922                                                awk -F':' '{print $1}')
5923                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5924                         fi
5925
5926                         if [[ $ost_last_id != $mds_last ]]; then
5927                                 error "$ost_last_id != $mds_last"
5928                         else
5929                                 found=true
5930                                 break
5931                         fi
5932                 done
5933         done
5934         $found || error "can not match last_seq/last_id for $mdtosc"
5935         return 0
5936 }
5937 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5938
5939 test_54a() {
5940         perl -MSocket -e ';' || skip "no Socket perl module installed"
5941
5942         $SOCKETSERVER $DIR/socket ||
5943                 error "$SOCKETSERVER $DIR/socket failed: $?"
5944         $SOCKETCLIENT $DIR/socket ||
5945                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5946         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5947 }
5948 run_test 54a "unix domain socket test =========================="
5949
5950 test_54b() {
5951         f="$DIR/f54b"
5952         mknod $f c 1 3
5953         chmod 0666 $f
5954         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5955 }
5956 run_test 54b "char device works in lustre ======================"
5957
5958 find_loop_dev() {
5959         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5960         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5961         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5962
5963         for i in $(seq 3 7); do
5964                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5965                 LOOPDEV=$LOOPBASE$i
5966                 LOOPNUM=$i
5967                 break
5968         done
5969 }
5970
5971 cleanup_54c() {
5972         local rc=0
5973         loopdev="$DIR/loop54c"
5974
5975         trap 0
5976         $UMOUNT $DIR/$tdir || rc=$?
5977         losetup -d $loopdev || true
5978         losetup -d $LOOPDEV || true
5979         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5980         return $rc
5981 }
5982
5983 test_54c() {
5984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5985
5986         loopdev="$DIR/loop54c"
5987
5988         find_loop_dev
5989         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5990         trap cleanup_54c EXIT
5991         mknod $loopdev b 7 $LOOPNUM
5992         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5993         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5994         losetup $loopdev $DIR/$tfile ||
5995                 error "can't set up $loopdev for $DIR/$tfile"
5996         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5997         test_mkdir $DIR/$tdir
5998         mount -t ext2 $loopdev $DIR/$tdir ||
5999                 error "error mounting $loopdev on $DIR/$tdir"
6000         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6001                 error "dd write"
6002         df $DIR/$tdir
6003         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6004                 error "dd read"
6005         cleanup_54c
6006 }
6007 run_test 54c "block device works in lustre ====================="
6008
6009 test_54d() {
6010         f="$DIR/f54d"
6011         string="aaaaaa"
6012         mknod $f p
6013         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
6014 }
6015 run_test 54d "fifo device works in lustre ======================"
6016
6017 test_54e() {
6018         f="$DIR/f54e"
6019         string="aaaaaa"
6020         cp -aL /dev/console $f
6021         echo $string > $f || error "echo $string to $f failed"
6022 }
6023 run_test 54e "console/tty device works in lustre ======================"
6024
6025 test_56a() {
6026         local numfiles=3
6027         local numdirs=2
6028         local dir=$DIR/$tdir
6029
6030         rm -rf $dir
6031         test_mkdir -p $dir/dir
6032         for i in $(seq $numfiles); do
6033                 touch $dir/file$i
6034                 touch $dir/dir/file$i
6035         done
6036
6037         local numcomp=$($LFS getstripe --component-count $dir)
6038
6039         [[ $numcomp == 0 ]] && numcomp=1
6040
6041         # test lfs getstripe with --recursive
6042         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6043
6044         [[ $filenum -eq $((numfiles * 2)) ]] ||
6045                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6046         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6047         [[ $filenum -eq $numfiles ]] ||
6048                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6049         echo "$LFS getstripe showed obdidx or l_ost_idx"
6050
6051         # test lfs getstripe with file instead of dir
6052         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6053         [[ $filenum -eq 1 ]] ||
6054                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6055         echo "$LFS getstripe file1 passed"
6056
6057         #test lfs getstripe with --verbose
6058         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6059         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6060                 error "$LFS getstripe --verbose $dir: "\
6061                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6062         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6063                 error "$LFS getstripe $dir: showed lmm_magic"
6064
6065         #test lfs getstripe with -v prints lmm_fid
6066         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6067         local countfids=$((numdirs + numfiles * numcomp))
6068         [[ $filenum -eq $countfids ]] ||
6069                 error "$LFS getstripe -v $dir: "\
6070                       "got $filenum want $countfids lmm_fid"
6071         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6072                 error "$LFS getstripe $dir: showed lmm_fid by default"
6073         echo "$LFS getstripe --verbose passed"
6074
6075         #check for FID information
6076         local fid1=$($LFS getstripe --fid $dir/file1)
6077         local fid2=$($LFS getstripe --verbose $dir/file1 |
6078                      awk '/lmm_fid: / { print $2; exit; }')
6079         local fid3=$($LFS path2fid $dir/file1)
6080
6081         [ "$fid1" != "$fid2" ] &&
6082                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6083         [ "$fid1" != "$fid3" ] &&
6084                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6085         echo "$LFS getstripe --fid passed"
6086
6087         #test lfs getstripe with --obd
6088         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6089                 error "$LFS getstripe --obd wrong_uuid: should return error"
6090
6091         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6092
6093         local ostidx=1
6094         local obduuid=$(ostuuid_from_index $ostidx)
6095         local found=$($LFS getstripe -r --obd $obduuid $dir |
6096                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6097
6098         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6099         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6100                 ((filenum--))
6101         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6102                 ((filenum--))
6103
6104         [[ $found -eq $filenum ]] ||
6105                 error "$LFS getstripe --obd: found $found expect $filenum"
6106         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6107                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6108                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6109                 error "$LFS getstripe --obd: should not show file on other obd"
6110         echo "$LFS getstripe --obd passed"
6111 }
6112 run_test 56a "check $LFS getstripe"
6113
6114 test_56b() {
6115         local dir=$DIR/$tdir
6116         local numdirs=3
6117
6118         test_mkdir $dir
6119         for i in $(seq $numdirs); do
6120                 test_mkdir $dir/dir$i
6121         done
6122
6123         # test lfs getdirstripe default mode is non-recursion, which is
6124         # different from lfs getstripe
6125         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6126
6127         [[ $dircnt -eq 1 ]] ||
6128                 error "$LFS getdirstripe: found $dircnt, not 1"
6129         dircnt=$($LFS getdirstripe --recursive $dir |
6130                 grep -c lmv_stripe_count)
6131         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6132                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6133 }
6134 run_test 56b "check $LFS getdirstripe"
6135
6136 test_56c() {
6137         remote_ost_nodsh && skip "remote OST with nodsh"
6138
6139         local ost_idx=0
6140         local ost_name=$(ostname_from_index $ost_idx)
6141         local old_status=$(ost_dev_status $ost_idx)
6142         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6143
6144         [[ -z "$old_status" ]] ||
6145                 skip_env "OST $ost_name is in $old_status status"
6146
6147         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6148         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6149                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6150         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6151                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6152                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6153         fi
6154
6155         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6156                 error "$LFS df -v showing inactive devices"
6157         sleep_maxage
6158
6159         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6160
6161         [[ "$new_status" =~ "D" ]] ||
6162                 error "$ost_name status is '$new_status', missing 'D'"
6163         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6164                 [[ "$new_status" =~ "N" ]] ||
6165                         error "$ost_name status is '$new_status', missing 'N'"
6166         fi
6167         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6168                 [[ "$new_status" =~ "f" ]] ||
6169                         error "$ost_name status is '$new_status', missing 'f'"
6170         fi
6171
6172         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6173         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6174                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6175         [[ -z "$p" ]] && restore_lustre_params < $p || true
6176         sleep_maxage
6177
6178         new_status=$(ost_dev_status $ost_idx)
6179         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6180                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6181         # can't check 'f' as devices may actually be on flash
6182 }
6183 run_test 56c "check 'lfs df' showing device status"
6184
6185 test_56d() {
6186         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6187         local osts=$($LFS df -v $MOUNT | grep -c OST)
6188
6189         $LFS df $MOUNT
6190
6191         (( mdts == MDSCOUNT )) ||
6192                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6193         (( osts == OSTCOUNT )) ||
6194                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6195 }
6196 run_test 56d "'lfs df -v' prints only configured devices"
6197
6198 test_56e() {
6199         err_enoent=2 # No such file or directory
6200         err_eopnotsupp=95 # Operation not supported
6201
6202         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6203         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6204
6205         # Check for handling of path not exists
6206         output=$($LFS df $enoent_mnt 2>&1)
6207         ret=$?
6208
6209         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6210         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6211                 error "expect failure $err_enoent, not $ret"
6212
6213         # Check for handling of non-Lustre FS
6214         output=$($LFS df $notsup_mnt)
6215         ret=$?
6216
6217         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6218         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6219                 error "expect success $err_eopnotsupp, not $ret"
6220
6221         # Check for multiple LustreFS argument
6222         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6223         ret=$?
6224
6225         [[ $output -eq 3 && $ret -eq 0 ]] ||
6226                 error "expect success 3, not $output, rc = $ret"
6227
6228         # Check for correct non-Lustre FS handling among multiple
6229         # LustreFS argument
6230         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6231                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6232         ret=$?
6233
6234         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6235                 error "expect success 2, not $output, rc = $ret"
6236 }
6237 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6238
6239 NUMFILES=3
6240 NUMDIRS=3
6241 setup_56() {
6242         local local_tdir="$1"
6243         local local_numfiles="$2"
6244         local local_numdirs="$3"
6245         local dir_params="$4"
6246         local dir_stripe_params="$5"
6247
6248         if [ ! -d "$local_tdir" ] ; then
6249                 test_mkdir -p $dir_stripe_params $local_tdir
6250                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6251                 for i in $(seq $local_numfiles) ; do
6252                         touch $local_tdir/file$i
6253                 done
6254                 for i in $(seq $local_numdirs) ; do
6255                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6256                         for j in $(seq $local_numfiles) ; do
6257                                 touch $local_tdir/dir$i/file$j
6258                         done
6259                 done
6260         fi
6261 }
6262
6263 setup_56_special() {
6264         local local_tdir=$1
6265         local local_numfiles=$2
6266         local local_numdirs=$3
6267
6268         setup_56 $local_tdir $local_numfiles $local_numdirs
6269
6270         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6271                 for i in $(seq $local_numfiles) ; do
6272                         mknod $local_tdir/loop${i}b b 7 $i
6273                         mknod $local_tdir/null${i}c c 1 3
6274                         ln -s $local_tdir/file1 $local_tdir/link${i}
6275                 done
6276                 for i in $(seq $local_numdirs) ; do
6277                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6278                         mknod $local_tdir/dir$i/null${i}c c 1 3
6279                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6280                 done
6281         fi
6282 }
6283
6284 test_56g() {
6285         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6286         local expected=$(($NUMDIRS + 2))
6287
6288         setup_56 $dir $NUMFILES $NUMDIRS
6289
6290         # test lfs find with -name
6291         for i in $(seq $NUMFILES) ; do
6292                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6293
6294                 [ $nums -eq $expected ] ||
6295                         error "lfs find -name '*$i' $dir wrong: "\
6296                               "found $nums, expected $expected"
6297         done
6298 }
6299 run_test 56g "check lfs find -name"
6300
6301 test_56h() {
6302         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6303         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6304
6305         setup_56 $dir $NUMFILES $NUMDIRS
6306
6307         # test lfs find with ! -name
6308         for i in $(seq $NUMFILES) ; do
6309                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6310
6311                 [ $nums -eq $expected ] ||
6312                         error "lfs find ! -name '*$i' $dir wrong: "\
6313                               "found $nums, expected $expected"
6314         done
6315 }
6316 run_test 56h "check lfs find ! -name"
6317
6318 test_56i() {
6319         local dir=$DIR/$tdir
6320
6321         test_mkdir $dir
6322
6323         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6324         local out=$($cmd)
6325
6326         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6327 }
6328 run_test 56i "check 'lfs find -ost UUID' skips directories"
6329
6330 test_56j() {
6331         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6332
6333         setup_56_special $dir $NUMFILES $NUMDIRS
6334
6335         local expected=$((NUMDIRS + 1))
6336         local cmd="$LFS find -type d $dir"
6337         local nums=$($cmd | wc -l)
6338
6339         [ $nums -eq $expected ] ||
6340                 error "'$cmd' wrong: found $nums, expected $expected"
6341 }
6342 run_test 56j "check lfs find -type d"
6343
6344 test_56k() {
6345         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6346
6347         setup_56_special $dir $NUMFILES $NUMDIRS
6348
6349         local expected=$(((NUMDIRS + 1) * NUMFILES))
6350         local cmd="$LFS find -type f $dir"
6351         local nums=$($cmd | wc -l)
6352
6353         [ $nums -eq $expected ] ||
6354                 error "'$cmd' wrong: found $nums, expected $expected"
6355 }
6356 run_test 56k "check lfs find -type f"
6357
6358 test_56l() {
6359         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6360
6361         setup_56_special $dir $NUMFILES $NUMDIRS
6362
6363         local expected=$((NUMDIRS + NUMFILES))
6364         local cmd="$LFS find -type b $dir"
6365         local nums=$($cmd | wc -l)
6366
6367         [ $nums -eq $expected ] ||
6368                 error "'$cmd' wrong: found $nums, expected $expected"
6369 }
6370 run_test 56l "check lfs find -type b"
6371
6372 test_56m() {
6373         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6374
6375         setup_56_special $dir $NUMFILES $NUMDIRS
6376
6377         local expected=$((NUMDIRS + NUMFILES))
6378         local cmd="$LFS find -type c $dir"
6379         local nums=$($cmd | wc -l)
6380         [ $nums -eq $expected ] ||
6381                 error "'$cmd' wrong: found $nums, expected $expected"
6382 }
6383 run_test 56m "check lfs find -type c"
6384
6385 test_56n() {
6386         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6387         setup_56_special $dir $NUMFILES $NUMDIRS
6388
6389         local expected=$((NUMDIRS + NUMFILES))
6390         local cmd="$LFS find -type l $dir"
6391         local nums=$($cmd | wc -l)
6392
6393         [ $nums -eq $expected ] ||
6394                 error "'$cmd' wrong: found $nums, expected $expected"
6395 }
6396 run_test 56n "check lfs find -type l"
6397
6398 test_56o() {
6399         local dir=$DIR/$tdir
6400
6401         setup_56 $dir $NUMFILES $NUMDIRS
6402         utime $dir/file1 > /dev/null || error "utime (1)"
6403         utime $dir/file2 > /dev/null || error "utime (2)"
6404         utime $dir/dir1 > /dev/null || error "utime (3)"
6405         utime $dir/dir2 > /dev/null || error "utime (4)"
6406         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6407         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6408
6409         local expected=4
6410         local nums=$($LFS find -mtime +0 $dir | wc -l)
6411
6412         [ $nums -eq $expected ] ||
6413                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6414
6415         expected=12
6416         cmd="$LFS find -mtime 0 $dir"
6417         nums=$($cmd | wc -l)
6418         [ $nums -eq $expected ] ||
6419                 error "'$cmd' wrong: found $nums, expected $expected"
6420 }
6421 run_test 56o "check lfs find -mtime for old files"
6422
6423 test_56ob() {
6424         local dir=$DIR/$tdir
6425         local expected=1
6426         local count=0
6427
6428         # just to make sure there is something that won't be found
6429         test_mkdir $dir
6430         touch $dir/$tfile.now
6431
6432         for age in year week day hour min; do
6433                 count=$((count + 1))
6434
6435                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6436                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6437                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6438
6439                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6440                 local nums=$($cmd | wc -l)
6441                 [ $nums -eq $expected ] ||
6442                         error "'$cmd' wrong: found $nums, expected $expected"
6443
6444                 cmd="$LFS find $dir -atime $count${age:0:1}"
6445                 nums=$($cmd | wc -l)
6446                 [ $nums -eq $expected ] ||
6447                         error "'$cmd' wrong: found $nums, expected $expected"
6448         done
6449
6450         sleep 2
6451         cmd="$LFS find $dir -ctime +1s -type f"
6452         nums=$($cmd | wc -l)
6453         (( $nums == $count * 2 + 1)) ||
6454                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6455 }
6456 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6457
6458 test_newerXY_base() {
6459         local x=$1
6460         local y=$2
6461         local dir=$DIR/$tdir
6462         local ref
6463         local negref
6464
6465         if [ $y == "t" ]; then
6466                 if [ $x == "b" ]; then
6467                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6468                 else
6469                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6470                 fi
6471         else
6472                 ref=$DIR/$tfile.newer.$x$y
6473                 touch $ref || error "touch $ref failed"
6474         fi
6475
6476         echo "before = $ref"
6477         sleep 2
6478         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6479         sleep 2
6480         if [ $y == "t" ]; then
6481                 if [ $x == "b" ]; then
6482                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6483                 else
6484                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6485                 fi
6486         else
6487                 negref=$DIR/$tfile.negnewer.$x$y
6488                 touch $negref || error "touch $negref failed"
6489         fi
6490
6491         echo "after = $negref"
6492         local cmd="$LFS find $dir -newer$x$y $ref"
6493         local nums=$(eval $cmd | wc -l)
6494         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6495
6496         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6497                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6498
6499         cmd="$LFS find $dir ! -newer$x$y $negref"
6500         nums=$(eval $cmd | wc -l)
6501         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6502                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6503
6504         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6505         nums=$(eval $cmd | wc -l)
6506         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6507                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6508
6509         rm -rf $DIR/*
6510 }
6511
6512 test_56oc() {
6513         test_newerXY_base "a" "a"
6514         test_newerXY_base "a" "m"
6515         test_newerXY_base "a" "c"
6516         test_newerXY_base "m" "a"
6517         test_newerXY_base "m" "m"
6518         test_newerXY_base "m" "c"
6519         test_newerXY_base "c" "a"
6520         test_newerXY_base "c" "m"
6521         test_newerXY_base "c" "c"
6522
6523         [[ -n "$sles_version" ]] &&
6524                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6525
6526         test_newerXY_base "a" "t"
6527         test_newerXY_base "m" "t"
6528         test_newerXY_base "c" "t"
6529
6530         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6531            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6532                 ! btime_supported && echo "btime unsupported" && return 0
6533
6534         test_newerXY_base "b" "b"
6535         test_newerXY_base "b" "t"
6536 }
6537 run_test 56oc "check lfs find -newerXY work"
6538
6539 btime_supported() {
6540         local dir=$DIR/$tdir
6541         local rc
6542
6543         mkdir -p $dir
6544         touch $dir/$tfile
6545         $LFS find $dir -btime -1d -type f
6546         rc=$?
6547         rm -rf $dir
6548         return $rc
6549 }
6550
6551 test_56od() {
6552         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6553                 ! btime_supported && skip "btime unsupported on MDS"
6554
6555         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6556                 ! btime_supported && skip "btime unsupported on clients"
6557
6558         local dir=$DIR/$tdir
6559         local ref=$DIR/$tfile.ref
6560         local negref=$DIR/$tfile.negref
6561
6562         mkdir $dir || error "mkdir $dir failed"
6563         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6564         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6565         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6566         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6567         touch $ref || error "touch $ref failed"
6568         # sleep 3 seconds at least
6569         sleep 3
6570
6571         local before=$(do_facet mds1 date +%s)
6572         local skew=$(($(date +%s) - before + 1))
6573
6574         if (( skew < 0 && skew > -5 )); then
6575                 sleep $((0 - skew + 1))
6576                 skew=0
6577         fi
6578
6579         # Set the dir stripe params to limit files all on MDT0,
6580         # otherwise we need to calc the max clock skew between
6581         # the client and MDTs.
6582         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6583         sleep 2
6584         touch $negref || error "touch $negref failed"
6585
6586         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6587         local nums=$($cmd | wc -l)
6588         local expected=$(((NUMFILES + 1) * NUMDIRS))
6589
6590         [ $nums -eq $expected ] ||
6591                 error "'$cmd' wrong: found $nums, expected $expected"
6592
6593         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6594         nums=$($cmd | wc -l)
6595         expected=$((NUMFILES + 1))
6596         [ $nums -eq $expected ] ||
6597                 error "'$cmd' wrong: found $nums, expected $expected"
6598
6599         [ $skew -lt 0 ] && return
6600
6601         local after=$(do_facet mds1 date +%s)
6602         local age=$((after - before + 1 + skew))
6603
6604         cmd="$LFS find $dir -btime -${age}s -type f"
6605         nums=$($cmd | wc -l)
6606         expected=$(((NUMFILES + 1) * NUMDIRS))
6607
6608         echo "Clock skew between client and server: $skew, age:$age"
6609         [ $nums -eq $expected ] ||
6610                 error "'$cmd' wrong: found $nums, expected $expected"
6611
6612         expected=$(($NUMDIRS + 1))
6613         cmd="$LFS find $dir -btime -${age}s -type d"
6614         nums=$($cmd | wc -l)
6615         [ $nums -eq $expected ] ||
6616                 error "'$cmd' wrong: found $nums, expected $expected"
6617         rm -f $ref $negref || error "Failed to remove $ref $negref"
6618 }
6619 run_test 56od "check lfs find -btime with units"
6620
6621 test_56p() {
6622         [ $RUNAS_ID -eq $UID ] &&
6623                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6624
6625         local dir=$DIR/$tdir
6626
6627         setup_56 $dir $NUMFILES $NUMDIRS
6628         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6629
6630         local expected=$NUMFILES
6631         local cmd="$LFS find -uid $RUNAS_ID $dir"
6632         local nums=$($cmd | wc -l)
6633
6634         [ $nums -eq $expected ] ||
6635                 error "'$cmd' wrong: found $nums, expected $expected"
6636
6637         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6638         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6639         nums=$($cmd | wc -l)
6640         [ $nums -eq $expected ] ||
6641                 error "'$cmd' wrong: found $nums, expected $expected"
6642 }
6643 run_test 56p "check lfs find -uid and ! -uid"
6644
6645 test_56q() {
6646         [ $RUNAS_ID -eq $UID ] &&
6647                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6648
6649         local dir=$DIR/$tdir
6650
6651         setup_56 $dir $NUMFILES $NUMDIRS
6652         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6653
6654         local expected=$NUMFILES
6655         local cmd="$LFS find -gid $RUNAS_GID $dir"
6656         local nums=$($cmd | wc -l)
6657
6658         [ $nums -eq $expected ] ||
6659                 error "'$cmd' wrong: found $nums, expected $expected"
6660
6661         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6662         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6663         nums=$($cmd | wc -l)
6664         [ $nums -eq $expected ] ||
6665                 error "'$cmd' wrong: found $nums, expected $expected"
6666 }
6667 run_test 56q "check lfs find -gid and ! -gid"
6668
6669 test_56r() {
6670         local dir=$DIR/$tdir
6671
6672         setup_56 $dir $NUMFILES $NUMDIRS
6673
6674         local expected=12
6675         local cmd="$LFS find -size 0 -type f -lazy $dir"
6676         local nums=$($cmd | wc -l)
6677
6678         [ $nums -eq $expected ] ||
6679                 error "'$cmd' wrong: found $nums, expected $expected"
6680         cmd="$LFS find -size 0 -type f $dir"
6681         nums=$($cmd | wc -l)
6682         [ $nums -eq $expected ] ||
6683                 error "'$cmd' wrong: found $nums, expected $expected"
6684
6685         expected=0
6686         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6687         nums=$($cmd | wc -l)
6688         [ $nums -eq $expected ] ||
6689                 error "'$cmd' wrong: found $nums, expected $expected"
6690         cmd="$LFS find ! -size 0 -type f $dir"
6691         nums=$($cmd | wc -l)
6692         [ $nums -eq $expected ] ||
6693                 error "'$cmd' wrong: found $nums, expected $expected"
6694
6695         echo "test" > $dir/$tfile
6696         echo "test2" > $dir/$tfile.2 && sync
6697         expected=1
6698         cmd="$LFS find -size 5 -type f -lazy $dir"
6699         nums=$($cmd | wc -l)
6700         [ $nums -eq $expected ] ||
6701                 error "'$cmd' wrong: found $nums, expected $expected"
6702         cmd="$LFS find -size 5 -type f $dir"
6703         nums=$($cmd | wc -l)
6704         [ $nums -eq $expected ] ||
6705                 error "'$cmd' wrong: found $nums, expected $expected"
6706
6707         expected=1
6708         cmd="$LFS find -size +5 -type f -lazy $dir"
6709         nums=$($cmd | wc -l)
6710         [ $nums -eq $expected ] ||
6711                 error "'$cmd' wrong: found $nums, expected $expected"
6712         cmd="$LFS find -size +5 -type f $dir"
6713         nums=$($cmd | wc -l)
6714         [ $nums -eq $expected ] ||
6715                 error "'$cmd' wrong: found $nums, expected $expected"
6716
6717         expected=2
6718         cmd="$LFS find -size +0 -type f -lazy $dir"
6719         nums=$($cmd | wc -l)
6720         [ $nums -eq $expected ] ||
6721                 error "'$cmd' wrong: found $nums, expected $expected"
6722         cmd="$LFS find -size +0 -type f $dir"
6723         nums=$($cmd | wc -l)
6724         [ $nums -eq $expected ] ||
6725                 error "'$cmd' wrong: found $nums, expected $expected"
6726
6727         expected=2
6728         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6729         nums=$($cmd | wc -l)
6730         [ $nums -eq $expected ] ||
6731                 error "'$cmd' wrong: found $nums, expected $expected"
6732         cmd="$LFS find ! -size -5 -type f $dir"
6733         nums=$($cmd | wc -l)
6734         [ $nums -eq $expected ] ||
6735                 error "'$cmd' wrong: found $nums, expected $expected"
6736
6737         expected=12
6738         cmd="$LFS find -size -5 -type f -lazy $dir"
6739         nums=$($cmd | wc -l)
6740         [ $nums -eq $expected ] ||
6741                 error "'$cmd' wrong: found $nums, expected $expected"
6742         cmd="$LFS find -size -5 -type f $dir"
6743         nums=$($cmd | wc -l)
6744         [ $nums -eq $expected ] ||
6745                 error "'$cmd' wrong: found $nums, expected $expected"
6746 }
6747 run_test 56r "check lfs find -size works"
6748
6749 test_56ra_sub() {
6750         local expected=$1
6751         local glimpses=$2
6752         local cmd="$3"
6753
6754         cancel_lru_locks $OSC
6755
6756         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6757         local nums=$($cmd | wc -l)
6758
6759         [ $nums -eq $expected ] ||
6760                 error "'$cmd' wrong: found $nums, expected $expected"
6761
6762         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6763
6764         if (( rpcs_before + glimpses != rpcs_after )); then
6765                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6766                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6767
6768                 if [[ $glimpses == 0 ]]; then
6769                         error "'$cmd' should not send glimpse RPCs to OST"
6770                 else
6771                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6772                 fi
6773         fi
6774 }
6775
6776 test_56ra() {
6777         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6778                 skip "MDS < 2.12.58 doesn't return LSOM data"
6779         local dir=$DIR/$tdir
6780         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6781
6782         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6783
6784         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6785         $LCTL set_param -n llite.*.statahead_agl=0
6786         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6787
6788         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6789         # open and close all files to ensure LSOM is updated
6790         cancel_lru_locks $OSC
6791         find $dir -type f | xargs cat > /dev/null
6792
6793         #   expect_found  glimpse_rpcs  command_to_run
6794         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6795         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6796         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6797         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6798
6799         echo "test" > $dir/$tfile
6800         echo "test2" > $dir/$tfile.2 && sync
6801         cancel_lru_locks $OSC
6802         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6803
6804         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6805         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6806         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6807         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6808
6809         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6810         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6811         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6812         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6813         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6814         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6815 }
6816 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6817
6818 test_56rb() {
6819         local dir=$DIR/$tdir
6820         local tmp=$TMP/$tfile.log
6821         local mdt_idx;
6822
6823         test_mkdir -p $dir || error "failed to mkdir $dir"
6824         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6825                 error "failed to setstripe $dir/$tfile"
6826         mdt_idx=$($LFS getdirstripe -i $dir)
6827         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6828
6829         stack_trap "rm -f $tmp" EXIT
6830         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6831         ! grep -q obd_uuid $tmp ||
6832                 error "failed to find --size +100K --ost 0 $dir"
6833         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6834         ! grep -q obd_uuid $tmp ||
6835                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6836 }
6837 run_test 56rb "check lfs find --size --ost/--mdt works"
6838
6839 test_56rc() {
6840         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6841         local dir=$DIR/$tdir
6842         local found
6843
6844         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6845         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6846         (( $MDSCOUNT > 2 )) &&
6847                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6848         mkdir $dir/$tdir-{1..10}
6849         touch $dir/$tfile-{1..10}
6850
6851         found=$($LFS find $dir --mdt-count 2 | wc -l)
6852         expect=11
6853         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6854
6855         found=$($LFS find $dir -T +1 | wc -l)
6856         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6857         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6858
6859         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6860         expect=11
6861         (( $found == $expect )) || error "found $found all_char, expect $expect"
6862
6863         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
6864         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
6865         (( $found == $expect )) || error "found $found all_char, expect $expect"
6866 }
6867 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
6868
6869 test_56s() { # LU-611 #LU-9369
6870         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6871
6872         local dir=$DIR/$tdir
6873         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6874
6875         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6876         for i in $(seq $NUMDIRS); do
6877                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6878         done
6879
6880         local expected=$NUMDIRS
6881         local cmd="$LFS find -c $OSTCOUNT $dir"
6882         local nums=$($cmd | wc -l)
6883
6884         [ $nums -eq $expected ] || {
6885                 $LFS getstripe -R $dir
6886                 error "'$cmd' wrong: found $nums, expected $expected"
6887         }
6888
6889         expected=$((NUMDIRS + onestripe))
6890         cmd="$LFS find -stripe-count +0 -type f $dir"
6891         nums=$($cmd | wc -l)
6892         [ $nums -eq $expected ] || {
6893                 $LFS getstripe -R $dir
6894                 error "'$cmd' wrong: found $nums, expected $expected"
6895         }
6896
6897         expected=$onestripe
6898         cmd="$LFS find -stripe-count 1 -type f $dir"
6899         nums=$($cmd | wc -l)
6900         [ $nums -eq $expected ] || {
6901                 $LFS getstripe -R $dir
6902                 error "'$cmd' wrong: found $nums, expected $expected"
6903         }
6904
6905         cmd="$LFS find -stripe-count -2 -type f $dir"
6906         nums=$($cmd | wc -l)
6907         [ $nums -eq $expected ] || {
6908                 $LFS getstripe -R $dir
6909                 error "'$cmd' wrong: found $nums, expected $expected"
6910         }
6911
6912         expected=0
6913         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6914         nums=$($cmd | wc -l)
6915         [ $nums -eq $expected ] || {
6916                 $LFS getstripe -R $dir
6917                 error "'$cmd' wrong: found $nums, expected $expected"
6918         }
6919 }
6920 run_test 56s "check lfs find -stripe-count works"
6921
6922 test_56t() { # LU-611 #LU-9369
6923         local dir=$DIR/$tdir
6924
6925         setup_56 $dir 0 $NUMDIRS
6926         for i in $(seq $NUMDIRS); do
6927                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6928         done
6929
6930         local expected=$NUMDIRS
6931         local cmd="$LFS find -S 8M $dir"
6932         local nums=$($cmd | wc -l)
6933
6934         [ $nums -eq $expected ] || {
6935                 $LFS getstripe -R $dir
6936                 error "'$cmd' wrong: found $nums, expected $expected"
6937         }
6938         rm -rf $dir
6939
6940         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6941
6942         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6943
6944         expected=$(((NUMDIRS + 1) * NUMFILES))
6945         cmd="$LFS find -stripe-size 512k -type f $dir"
6946         nums=$($cmd | wc -l)
6947         [ $nums -eq $expected ] ||
6948                 error "'$cmd' wrong: found $nums, expected $expected"
6949
6950         cmd="$LFS find -stripe-size +320k -type f $dir"
6951         nums=$($cmd | wc -l)
6952         [ $nums -eq $expected ] ||
6953                 error "'$cmd' wrong: found $nums, expected $expected"
6954
6955         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6956         cmd="$LFS find -stripe-size +200k -type f $dir"
6957         nums=$($cmd | wc -l)
6958         [ $nums -eq $expected ] ||
6959                 error "'$cmd' wrong: found $nums, expected $expected"
6960
6961         cmd="$LFS find -stripe-size -640k -type f $dir"
6962         nums=$($cmd | wc -l)
6963         [ $nums -eq $expected ] ||
6964                 error "'$cmd' wrong: found $nums, expected $expected"
6965
6966         expected=4
6967         cmd="$LFS find -stripe-size 256k -type f $dir"
6968         nums=$($cmd | wc -l)
6969         [ $nums -eq $expected ] ||
6970                 error "'$cmd' wrong: found $nums, expected $expected"
6971
6972         cmd="$LFS find -stripe-size -320k -type f $dir"
6973         nums=$($cmd | wc -l)
6974         [ $nums -eq $expected ] ||
6975                 error "'$cmd' wrong: found $nums, expected $expected"
6976
6977         expected=0
6978         cmd="$LFS find -stripe-size 1024k -type f $dir"
6979         nums=$($cmd | wc -l)
6980         [ $nums -eq $expected ] ||
6981                 error "'$cmd' wrong: found $nums, expected $expected"
6982 }
6983 run_test 56t "check lfs find -stripe-size works"
6984
6985 test_56u() { # LU-611
6986         local dir=$DIR/$tdir
6987
6988         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6989
6990         if [[ $OSTCOUNT -gt 1 ]]; then
6991                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6992                 onestripe=4
6993         else
6994                 onestripe=0
6995         fi
6996
6997         local expected=$(((NUMDIRS + 1) * NUMFILES))
6998         local cmd="$LFS find -stripe-index 0 -type f $dir"
6999         local nums=$($cmd | wc -l)
7000
7001         [ $nums -eq $expected ] ||
7002                 error "'$cmd' wrong: found $nums, expected $expected"
7003
7004         expected=$onestripe
7005         cmd="$LFS find -stripe-index 1 -type f $dir"
7006         nums=$($cmd | wc -l)
7007         [ $nums -eq $expected ] ||
7008                 error "'$cmd' wrong: found $nums, expected $expected"
7009
7010         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7011         nums=$($cmd | wc -l)
7012         [ $nums -eq $expected ] ||
7013                 error "'$cmd' wrong: found $nums, expected $expected"
7014
7015         expected=0
7016         # This should produce an error and not return any files
7017         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7018         nums=$($cmd 2>/dev/null | wc -l)
7019         [ $nums -eq $expected ] ||
7020                 error "'$cmd' wrong: found $nums, expected $expected"
7021
7022         if [[ $OSTCOUNT -gt 1 ]]; then
7023                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7024                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7025                 nums=$($cmd | wc -l)
7026                 [ $nums -eq $expected ] ||
7027                         error "'$cmd' wrong: found $nums, expected $expected"
7028         fi
7029 }
7030 run_test 56u "check lfs find -stripe-index works"
7031
7032 test_56v() {
7033         local mdt_idx=0
7034         local dir=$DIR/$tdir
7035
7036         setup_56 $dir $NUMFILES $NUMDIRS
7037
7038         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7039         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7040
7041         for file in $($LFS find -m $UUID $dir); do
7042                 file_midx=$($LFS getstripe -m $file)
7043                 [ $file_midx -eq $mdt_idx ] ||
7044                         error "lfs find -m $UUID != getstripe -m $file_midx"
7045         done
7046 }
7047 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7048
7049 test_56w() {
7050         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7052
7053         local dir=$DIR/$tdir
7054
7055         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7056
7057         local stripe_size=$($LFS getstripe -S -d $dir) ||
7058                 error "$LFS getstripe -S -d $dir failed"
7059         stripe_size=${stripe_size%% *}
7060
7061         local file_size=$((stripe_size * OSTCOUNT))
7062         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7063         local required_space=$((file_num * file_size))
7064         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7065                            head -n1)
7066         [[ $free_space -le $((required_space / 1024)) ]] &&
7067                 skip_env "need $required_space, have $free_space kbytes"
7068
7069         local dd_bs=65536
7070         local dd_count=$((file_size / dd_bs))
7071
7072         # write data into the files
7073         local i
7074         local j
7075         local file
7076
7077         for i in $(seq $NUMFILES); do
7078                 file=$dir/file$i
7079                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7080                         error "write data into $file failed"
7081         done
7082         for i in $(seq $NUMDIRS); do
7083                 for j in $(seq $NUMFILES); do
7084                         file=$dir/dir$i/file$j
7085                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7086                                 error "write data into $file failed"
7087                 done
7088         done
7089
7090         # $LFS_MIGRATE will fail if hard link migration is unsupported
7091         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7092                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7093                         error "creating links to $dir/dir1/file1 failed"
7094         fi
7095
7096         local expected=-1
7097
7098         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7099
7100         # lfs_migrate file
7101         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7102
7103         echo "$cmd"
7104         eval $cmd || error "$cmd failed"
7105
7106         check_stripe_count $dir/file1 $expected
7107
7108         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7109         then
7110                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7111                 # OST 1 if it is on OST 0. This file is small enough to
7112                 # be on only one stripe.
7113                 file=$dir/migr_1_ost
7114                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7115                         error "write data into $file failed"
7116                 local obdidx=$($LFS getstripe -i $file)
7117                 local oldmd5=$(md5sum $file)
7118                 local newobdidx=0
7119
7120                 [[ $obdidx -eq 0 ]] && newobdidx=1
7121                 cmd="$LFS migrate -i $newobdidx $file"
7122                 echo $cmd
7123                 eval $cmd || error "$cmd failed"
7124
7125                 local realobdix=$($LFS getstripe -i $file)
7126                 local newmd5=$(md5sum $file)
7127
7128                 [[ $newobdidx -ne $realobdix ]] &&
7129                         error "new OST is different (was=$obdidx, "\
7130                               "wanted=$newobdidx, got=$realobdix)"
7131                 [[ "$oldmd5" != "$newmd5" ]] &&
7132                         error "md5sum differ: $oldmd5, $newmd5"
7133         fi
7134
7135         # lfs_migrate dir
7136         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7137         echo "$cmd"
7138         eval $cmd || error "$cmd failed"
7139
7140         for j in $(seq $NUMFILES); do
7141                 check_stripe_count $dir/dir1/file$j $expected
7142         done
7143
7144         # lfs_migrate works with lfs find
7145         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7146              $LFS_MIGRATE -y -c $expected"
7147         echo "$cmd"
7148         eval $cmd || error "$cmd failed"
7149
7150         for i in $(seq 2 $NUMFILES); do
7151                 check_stripe_count $dir/file$i $expected
7152         done
7153         for i in $(seq 2 $NUMDIRS); do
7154                 for j in $(seq $NUMFILES); do
7155                 check_stripe_count $dir/dir$i/file$j $expected
7156                 done
7157         done
7158 }
7159 run_test 56w "check lfs_migrate -c stripe_count works"
7160
7161 test_56wb() {
7162         local file1=$DIR/$tdir/file1
7163         local create_pool=false
7164         local initial_pool=$($LFS getstripe -p $DIR)
7165         local pool_list=()
7166         local pool=""
7167
7168         echo -n "Creating test dir..."
7169         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7170         echo "done."
7171
7172         echo -n "Creating test file..."
7173         touch $file1 || error "cannot create file"
7174         echo "done."
7175
7176         echo -n "Detecting existing pools..."
7177         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7178
7179         if [ ${#pool_list[@]} -gt 0 ]; then
7180                 echo "${pool_list[@]}"
7181                 for thispool in "${pool_list[@]}"; do
7182                         if [[ -z "$initial_pool" ||
7183                               "$initial_pool" != "$thispool" ]]; then
7184                                 pool="$thispool"
7185                                 echo "Using existing pool '$pool'"
7186                                 break
7187                         fi
7188                 done
7189         else
7190                 echo "none detected."
7191         fi
7192         if [ -z "$pool" ]; then
7193                 pool=${POOL:-testpool}
7194                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7195                 echo -n "Creating pool '$pool'..."
7196                 create_pool=true
7197                 pool_add $pool &> /dev/null ||
7198                         error "pool_add failed"
7199                 echo "done."
7200
7201                 echo -n "Adding target to pool..."
7202                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7203                         error "pool_add_targets failed"
7204                 echo "done."
7205         fi
7206
7207         echo -n "Setting pool using -p option..."
7208         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7209                 error "migrate failed rc = $?"
7210         echo "done."
7211
7212         echo -n "Verifying test file is in pool after migrating..."
7213         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7214                 error "file was not migrated to pool $pool"
7215         echo "done."
7216
7217         echo -n "Removing test file from pool '$pool'..."
7218         # "lfs migrate $file" won't remove the file from the pool
7219         # until some striping information is changed.
7220         $LFS migrate -c 1 $file1 &> /dev/null ||
7221                 error "cannot remove from pool"
7222         [ "$($LFS getstripe -p $file1)" ] &&
7223                 error "pool still set"
7224         echo "done."
7225
7226         echo -n "Setting pool using --pool option..."
7227         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7228                 error "migrate failed rc = $?"
7229         echo "done."
7230
7231         # Clean up
7232         rm -f $file1
7233         if $create_pool; then
7234                 destroy_test_pools 2> /dev/null ||
7235                         error "destroy test pools failed"
7236         fi
7237 }
7238 run_test 56wb "check lfs_migrate pool support"
7239
7240 test_56wc() {
7241         local file1="$DIR/$tdir/file1"
7242         local parent_ssize
7243         local parent_scount
7244         local cur_ssize
7245         local cur_scount
7246         local orig_ssize
7247
7248         echo -n "Creating test dir..."
7249         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7250         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7251                 error "cannot set stripe by '-S 1M -c 1'"
7252         echo "done"
7253
7254         echo -n "Setting initial stripe for test file..."
7255         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7256                 error "cannot set stripe"
7257         cur_ssize=$($LFS getstripe -S "$file1")
7258         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7259         echo "done."
7260
7261         # File currently set to -S 512K -c 1
7262
7263         # Ensure -c and -S options are rejected when -R is set
7264         echo -n "Verifying incompatible options are detected..."
7265         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7266                 error "incompatible -c and -R options not detected"
7267         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7268                 error "incompatible -S and -R options not detected"
7269         echo "done."
7270
7271         # Ensure unrecognized options are passed through to 'lfs migrate'
7272         echo -n "Verifying -S option is passed through to lfs migrate..."
7273         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7274                 error "migration failed"
7275         cur_ssize=$($LFS getstripe -S "$file1")
7276         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7277         echo "done."
7278
7279         # File currently set to -S 1M -c 1
7280
7281         # Ensure long options are supported
7282         echo -n "Verifying long options supported..."
7283         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7284                 error "long option without argument not supported"
7285         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7286                 error "long option with argument not supported"
7287         cur_ssize=$($LFS getstripe -S "$file1")
7288         [ $cur_ssize -eq 524288 ] ||
7289                 error "migrate --stripe-size $cur_ssize != 524288"
7290         echo "done."
7291
7292         # File currently set to -S 512K -c 1
7293
7294         if [ "$OSTCOUNT" -gt 1 ]; then
7295                 echo -n "Verifying explicit stripe count can be set..."
7296                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7297                         error "migrate failed"
7298                 cur_scount=$($LFS getstripe -c "$file1")
7299                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7300                 echo "done."
7301         fi
7302
7303         # File currently set to -S 512K -c 1 or -S 512K -c 2
7304
7305         # Ensure parent striping is used if -R is set, and no stripe
7306         # count or size is specified
7307         echo -n "Setting stripe for parent directory..."
7308         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7309                 error "cannot set stripe '-S 2M -c 1'"
7310         echo "done."
7311
7312         echo -n "Verifying restripe option uses parent stripe settings..."
7313         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7314         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7315         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7316                 error "migrate failed"
7317         cur_ssize=$($LFS getstripe -S "$file1")
7318         [ $cur_ssize -eq $parent_ssize ] ||
7319                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7320         cur_scount=$($LFS getstripe -c "$file1")
7321         [ $cur_scount -eq $parent_scount ] ||
7322                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7323         echo "done."
7324
7325         # File currently set to -S 1M -c 1
7326
7327         # Ensure striping is preserved if -R is not set, and no stripe
7328         # count or size is specified
7329         echo -n "Verifying striping size preserved when not specified..."
7330         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7331         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7332                 error "cannot set stripe on parent directory"
7333         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7334                 error "migrate failed"
7335         cur_ssize=$($LFS getstripe -S "$file1")
7336         [ $cur_ssize -eq $orig_ssize ] ||
7337                 error "migrate by default $cur_ssize != $orig_ssize"
7338         echo "done."
7339
7340         # Ensure file name properly detected when final option has no argument
7341         echo -n "Verifying file name properly detected..."
7342         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7343                 error "file name interpreted as option argument"
7344         echo "done."
7345
7346         # Clean up
7347         rm -f "$file1"
7348 }
7349 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7350
7351 test_56wd() {
7352         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7353
7354         local file1=$DIR/$tdir/file1
7355
7356         echo -n "Creating test dir..."
7357         test_mkdir $DIR/$tdir || error "cannot create dir"
7358         echo "done."
7359
7360         echo -n "Creating test file..."
7361         touch $file1
7362         echo "done."
7363
7364         # Ensure 'lfs migrate' will fail by using a non-existent option,
7365         # and make sure rsync is not called to recover
7366         echo -n "Make sure --no-rsync option works..."
7367         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7368                 grep -q 'refusing to fall back to rsync' ||
7369                 error "rsync was called with --no-rsync set"
7370         echo "done."
7371
7372         # Ensure rsync is called without trying 'lfs migrate' first
7373         echo -n "Make sure --rsync option works..."
7374         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7375                 grep -q 'falling back to rsync' &&
7376                 error "lfs migrate was called with --rsync set"
7377         echo "done."
7378
7379         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7380         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7381                 grep -q 'at the same time' ||
7382                 error "--rsync and --no-rsync accepted concurrently"
7383         echo "done."
7384
7385         # Clean up
7386         rm -f $file1
7387 }
7388 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7389
7390 test_56we() {
7391         local td=$DIR/$tdir
7392         local tf=$td/$tfile
7393
7394         test_mkdir $td || error "cannot create $td"
7395         touch $tf || error "cannot touch $tf"
7396
7397         echo -n "Make sure --non-direct|-D works..."
7398         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7399                 grep -q "lfs migrate --non-direct" ||
7400                 error "--non-direct option cannot work correctly"
7401         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7402                 grep -q "lfs migrate -D" ||
7403                 error "-D option cannot work correctly"
7404         echo "done."
7405 }
7406 run_test 56we "check lfs_migrate --non-direct|-D support"
7407
7408 test_56x() {
7409         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7410         check_swap_layouts_support
7411
7412         local dir=$DIR/$tdir
7413         local ref1=/etc/passwd
7414         local file1=$dir/file1
7415
7416         test_mkdir $dir || error "creating dir $dir"
7417         $LFS setstripe -c 2 $file1
7418         cp $ref1 $file1
7419         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7420         stripe=$($LFS getstripe -c $file1)
7421         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7422         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7423
7424         # clean up
7425         rm -f $file1
7426 }
7427 run_test 56x "lfs migration support"
7428
7429 test_56xa() {
7430         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7431         check_swap_layouts_support
7432
7433         local dir=$DIR/$tdir/$testnum
7434
7435         test_mkdir -p $dir
7436
7437         local ref1=/etc/passwd
7438         local file1=$dir/file1
7439
7440         $LFS setstripe -c 2 $file1
7441         cp $ref1 $file1
7442         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7443
7444         local stripe=$($LFS getstripe -c $file1)
7445
7446         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7447         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7448
7449         # clean up
7450         rm -f $file1
7451 }
7452 run_test 56xa "lfs migration --block support"
7453
7454 check_migrate_links() {
7455         local dir="$1"
7456         local file1="$dir/file1"
7457         local begin="$2"
7458         local count="$3"
7459         local runas="$4"
7460         local total_count=$(($begin + $count - 1))
7461         local symlink_count=10
7462         local uniq_count=10
7463
7464         if [ ! -f "$file1" ]; then
7465                 echo -n "creating initial file..."
7466                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7467                         error "cannot setstripe initial file"
7468                 echo "done"
7469
7470                 echo -n "creating symlinks..."
7471                 for s in $(seq 1 $symlink_count); do
7472                         ln -s "$file1" "$dir/slink$s" ||
7473                                 error "cannot create symlinks"
7474                 done
7475                 echo "done"
7476
7477                 echo -n "creating nonlinked files..."
7478                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7479                         error "cannot create nonlinked files"
7480                 echo "done"
7481         fi
7482
7483         # create hard links
7484         if [ ! -f "$dir/file$total_count" ]; then
7485                 echo -n "creating hard links $begin:$total_count..."
7486                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7487                         /dev/null || error "cannot create hard links"
7488                 echo "done"
7489         fi
7490
7491         echo -n "checking number of hard links listed in xattrs..."
7492         local fid=$($LFS getstripe -F "$file1")
7493         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7494
7495         echo "${#paths[*]}"
7496         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7497                         skip "hard link list has unexpected size, skipping test"
7498         fi
7499         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7500                         error "link names should exceed xattrs size"
7501         fi
7502
7503         echo -n "migrating files..."
7504         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7505         local rc=$?
7506         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7507         echo "done"
7508
7509         # make sure all links have been properly migrated
7510         echo -n "verifying files..."
7511         fid=$($LFS getstripe -F "$file1") ||
7512                 error "cannot get fid for file $file1"
7513         for i in $(seq 2 $total_count); do
7514                 local fid2=$($LFS getstripe -F $dir/file$i)
7515
7516                 [ "$fid2" == "$fid" ] ||
7517                         error "migrated hard link has mismatched FID"
7518         done
7519
7520         # make sure hard links were properly detected, and migration was
7521         # performed only once for the entire link set; nonlinked files should
7522         # also be migrated
7523         local actual=$(grep -c 'done' <<< "$migrate_out")
7524         local expected=$(($uniq_count + 1))
7525
7526         [ "$actual" -eq  "$expected" ] ||
7527                 error "hard links individually migrated ($actual != $expected)"
7528
7529         # make sure the correct number of hard links are present
7530         local hardlinks=$(stat -c '%h' "$file1")
7531
7532         [ $hardlinks -eq $total_count ] ||
7533                 error "num hard links $hardlinks != $total_count"
7534         echo "done"
7535
7536         return 0
7537 }
7538
7539 test_56xb() {
7540         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7541                 skip "Need MDS version at least 2.10.55"
7542
7543         local dir="$DIR/$tdir"
7544
7545         test_mkdir "$dir" || error "cannot create dir $dir"
7546
7547         echo "testing lfs migrate mode when all links fit within xattrs"
7548         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7549
7550         echo "testing rsync mode when all links fit within xattrs"
7551         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7552
7553         echo "testing lfs migrate mode when all links do not fit within xattrs"
7554         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7555
7556         echo "testing rsync mode when all links do not fit within xattrs"
7557         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7558
7559         chown -R $RUNAS_ID $dir
7560         echo "testing non-root lfs migrate mode when not all links are in xattr"
7561         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7562
7563         # clean up
7564         rm -rf $dir
7565 }
7566 run_test 56xb "lfs migration hard link support"
7567
7568 test_56xc() {
7569         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7570
7571         local dir="$DIR/$tdir"
7572
7573         test_mkdir "$dir" || error "cannot create dir $dir"
7574
7575         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7576         echo -n "Setting initial stripe for 20MB test file..."
7577         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7578                 error "cannot setstripe 20MB file"
7579         echo "done"
7580         echo -n "Sizing 20MB test file..."
7581         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7582         echo "done"
7583         echo -n "Verifying small file autostripe count is 1..."
7584         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7585                 error "cannot migrate 20MB file"
7586         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7587                 error "cannot get stripe for $dir/20mb"
7588         [ $stripe_count -eq 1 ] ||
7589                 error "unexpected stripe count $stripe_count for 20MB file"
7590         rm -f "$dir/20mb"
7591         echo "done"
7592
7593         # Test 2: File is small enough to fit within the available space on
7594         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7595         # have at least an additional 1KB for each desired stripe for test 3
7596         echo -n "Setting stripe for 1GB test file..."
7597         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7598         echo "done"
7599         echo -n "Sizing 1GB test file..."
7600         # File size is 1GB + 3KB
7601         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7602         echo "done"
7603
7604         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7605         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7606         if (( avail > 524288 * OSTCOUNT )); then
7607                 echo -n "Migrating 1GB file..."
7608                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7609                         error "cannot migrate 1GB file"
7610                 echo "done"
7611                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7612                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7613                         error "cannot getstripe for 1GB file"
7614                 [ $stripe_count -eq 2 ] ||
7615                         error "unexpected stripe count $stripe_count != 2"
7616                 echo "done"
7617         fi
7618
7619         # Test 3: File is too large to fit within the available space on
7620         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7621         if [ $OSTCOUNT -ge 3 ]; then
7622                 # The required available space is calculated as
7623                 # file size (1GB + 3KB) / OST count (3).
7624                 local kb_per_ost=349526
7625
7626                 echo -n "Migrating 1GB file with limit..."
7627                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7628                         error "cannot migrate 1GB file with limit"
7629                 echo "done"
7630
7631                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7632                 echo -n "Verifying 1GB autostripe count with limited space..."
7633                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7634                         error "unexpected stripe count $stripe_count (min 3)"
7635                 echo "done"
7636         fi
7637
7638         # clean up
7639         rm -rf $dir
7640 }
7641 run_test 56xc "lfs migration autostripe"
7642
7643 test_56xd() {
7644         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7645
7646         local dir=$DIR/$tdir
7647         local f_mgrt=$dir/$tfile.mgrt
7648         local f_yaml=$dir/$tfile.yaml
7649         local f_copy=$dir/$tfile.copy
7650         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7651         local layout_copy="-c 2 -S 2M -i 1"
7652         local yamlfile=$dir/yamlfile
7653         local layout_before;
7654         local layout_after;
7655
7656         test_mkdir "$dir" || error "cannot create dir $dir"
7657         $LFS setstripe $layout_yaml $f_yaml ||
7658                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7659         $LFS getstripe --yaml $f_yaml > $yamlfile
7660         $LFS setstripe $layout_copy $f_copy ||
7661                 error "cannot setstripe $f_copy with layout $layout_copy"
7662         touch $f_mgrt
7663         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7664
7665         # 1. test option --yaml
7666         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7667                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7668         layout_before=$(get_layout_param $f_yaml)
7669         layout_after=$(get_layout_param $f_mgrt)
7670         [ "$layout_after" == "$layout_before" ] ||
7671                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7672
7673         # 2. test option --copy
7674         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7675                 error "cannot migrate $f_mgrt with --copy $f_copy"
7676         layout_before=$(get_layout_param $f_copy)
7677         layout_after=$(get_layout_param $f_mgrt)
7678         [ "$layout_after" == "$layout_before" ] ||
7679                 error "lfs_migrate --copy: $layout_after != $layout_before"
7680 }
7681 run_test 56xd "check lfs_migrate --yaml and --copy support"
7682
7683 test_56xe() {
7684         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7685
7686         local dir=$DIR/$tdir
7687         local f_comp=$dir/$tfile
7688         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7689         local layout_before=""
7690         local layout_after=""
7691
7692         test_mkdir "$dir" || error "cannot create dir $dir"
7693         $LFS setstripe $layout $f_comp ||
7694                 error "cannot setstripe $f_comp with layout $layout"
7695         layout_before=$(get_layout_param $f_comp)
7696         dd if=/dev/zero of=$f_comp bs=1M count=4
7697
7698         # 1. migrate a comp layout file by lfs_migrate
7699         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7700         layout_after=$(get_layout_param $f_comp)
7701         [ "$layout_before" == "$layout_after" ] ||
7702                 error "lfs_migrate: $layout_before != $layout_after"
7703
7704         # 2. migrate a comp layout file by lfs migrate
7705         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7706         layout_after=$(get_layout_param $f_comp)
7707         [ "$layout_before" == "$layout_after" ] ||
7708                 error "lfs migrate: $layout_before != $layout_after"
7709 }
7710 run_test 56xe "migrate a composite layout file"
7711
7712 test_56xf() {
7713         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7714
7715         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7716                 skip "Need server version at least 2.13.53"
7717
7718         local dir=$DIR/$tdir
7719         local f_comp=$dir/$tfile
7720         local layout="-E 1M -c1 -E -1 -c2"
7721         local fid_before=""
7722         local fid_after=""
7723
7724         test_mkdir "$dir" || error "cannot create dir $dir"
7725         $LFS setstripe $layout $f_comp ||
7726                 error "cannot setstripe $f_comp with layout $layout"
7727         fid_before=$($LFS getstripe --fid $f_comp)
7728         dd if=/dev/zero of=$f_comp bs=1M count=4
7729
7730         # 1. migrate a comp layout file to a comp layout
7731         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7732         fid_after=$($LFS getstripe --fid $f_comp)
7733         [ "$fid_before" == "$fid_after" ] ||
7734                 error "comp-to-comp migrate: $fid_before != $fid_after"
7735
7736         # 2. migrate a comp layout file to a plain layout
7737         $LFS migrate -c2 $f_comp ||
7738                 error "cannot migrate $f_comp by lfs migrate"
7739         fid_after=$($LFS getstripe --fid $f_comp)
7740         [ "$fid_before" == "$fid_after" ] ||
7741                 error "comp-to-plain migrate: $fid_before != $fid_after"
7742
7743         # 3. migrate a plain layout file to a comp layout
7744         $LFS migrate $layout $f_comp ||
7745                 error "cannot migrate $f_comp by lfs migrate"
7746         fid_after=$($LFS getstripe --fid $f_comp)
7747         [ "$fid_before" == "$fid_after" ] ||
7748                 error "plain-to-comp migrate: $fid_before != $fid_after"
7749 }
7750 run_test 56xf "FID is not lost during migration of a composite layout file"
7751
7752 check_file_ost_range() {
7753         local file="$1"
7754         shift
7755         local range="$*"
7756         local -a file_range
7757         local idx
7758
7759         file_range=($($LFS getstripe -y "$file" |
7760                 awk '/l_ost_idx:/ { print $NF }'))
7761
7762         if [[ "${#file_range[@]}" = 0 ]]; then
7763                 echo "No osts found for $file"
7764                 return 1
7765         fi
7766
7767         for idx in "${file_range[@]}"; do
7768                 [[ " $range " =~ " $idx " ]] ||
7769                         return 1
7770         done
7771
7772         return 0
7773 }
7774
7775 sub_test_56xg() {
7776         local stripe_opt="$1"
7777         local pool="$2"
7778         shift 2
7779         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7780
7781         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7782                 error "Fail to migrate $tfile on $pool"
7783         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7784                 error "$tfile is not in pool $pool"
7785         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7786                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7787 }
7788
7789 test_56xg() {
7790         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7791         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7792         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7793                 skip "Need MDS version newer than 2.14.52"
7794
7795         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7796         local -a pool_ranges=("0 0" "1 1" "0 1")
7797
7798         # init pools
7799         for i in "${!pool_names[@]}"; do
7800                 pool_add ${pool_names[$i]} ||
7801                         error "pool_add failed (pool: ${pool_names[$i]})"
7802                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7803                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7804         done
7805
7806         # init the file to migrate
7807         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7808                 error "Unable to create $tfile on OST1"
7809         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7810                 error "Unable to write on $tfile"
7811
7812         echo "1. migrate $tfile on pool ${pool_names[0]}"
7813         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7814
7815         echo "2. migrate $tfile on pool ${pool_names[2]}"
7816         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7817
7818         echo "3. migrate $tfile on pool ${pool_names[1]}"
7819         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7820
7821         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7822         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7823         echo
7824
7825         # Clean pools
7826         destroy_test_pools ||
7827                 error "pool_destroy failed"
7828 }
7829 run_test 56xg "lfs migrate pool support"
7830
7831 test_56y() {
7832         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7833                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7834
7835         local res=""
7836         local dir=$DIR/$tdir
7837         local f1=$dir/file1
7838         local f2=$dir/file2
7839
7840         test_mkdir -p $dir || error "creating dir $dir"
7841         touch $f1 || error "creating std file $f1"
7842         $MULTIOP $f2 H2c || error "creating released file $f2"
7843
7844         # a directory can be raid0, so ask only for files
7845         res=$($LFS find $dir -L raid0 -type f | wc -l)
7846         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7847
7848         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7849         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7850
7851         # only files can be released, so no need to force file search
7852         res=$($LFS find $dir -L released)
7853         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7854
7855         res=$($LFS find $dir -type f \! -L released)
7856         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7857 }
7858 run_test 56y "lfs find -L raid0|released"
7859
7860 test_56z() { # LU-4824
7861         # This checks to make sure 'lfs find' continues after errors
7862         # There are two classes of errors that should be caught:
7863         # - If multiple paths are provided, all should be searched even if one
7864         #   errors out
7865         # - If errors are encountered during the search, it should not terminate
7866         #   early
7867         local dir=$DIR/$tdir
7868         local i
7869
7870         test_mkdir $dir
7871         for i in d{0..9}; do
7872                 test_mkdir $dir/$i
7873                 touch $dir/$i/$tfile
7874         done
7875         $LFS find $DIR/non_existent_dir $dir &&
7876                 error "$LFS find did not return an error"
7877         # Make a directory unsearchable. This should NOT be the last entry in
7878         # directory order.  Arbitrarily pick the 6th entry
7879         chmod 700 $($LFS find $dir -type d | sed '6!d')
7880
7881         $RUNAS $LFS find $DIR/non_existent $dir
7882         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7883
7884         # The user should be able to see 10 directories and 9 files
7885         (( count == 19 )) ||
7886                 error "$LFS find found $count != 19 entries after error"
7887 }
7888 run_test 56z "lfs find should continue after an error"
7889
7890 test_56aa() { # LU-5937
7891         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7892
7893         local dir=$DIR/$tdir
7894
7895         mkdir $dir
7896         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7897
7898         createmany -o $dir/striped_dir/${tfile}- 1024
7899         local dirs=$($LFS find --size +8k $dir/)
7900
7901         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7902 }
7903 run_test 56aa "lfs find --size under striped dir"
7904
7905 test_56ab() { # LU-10705
7906         test_mkdir $DIR/$tdir
7907         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7908         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7909         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7910         # Flush writes to ensure valid blocks.  Need to be more thorough for
7911         # ZFS, since blocks are not allocated/returned to client immediately.
7912         sync_all_data
7913         wait_zfs_commit ost1 2
7914         cancel_lru_locks osc
7915         ls -ls $DIR/$tdir
7916
7917         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7918
7919         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7920
7921         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7922         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7923
7924         rm -f $DIR/$tdir/$tfile.[123]
7925 }
7926 run_test 56ab "lfs find --blocks"
7927
7928 # LU-11188
7929 test_56aca() {
7930         local dir="$DIR/$tdir"
7931         local perms=(001 002 003 004 005 006 007
7932                      010 020 030 040 050 060 070
7933                      100 200 300 400 500 600 700
7934                      111 222 333 444 555 666 777)
7935         local perm_minus=(8 8 4 8 4 4 2
7936                           8 8 4 8 4 4 2
7937                           8 8 4 8 4 4 2
7938                           4 4 2 4 2 2 1)
7939         local perm_slash=(8  8 12  8 12 12 14
7940                           8  8 12  8 12 12 14
7941                           8  8 12  8 12 12 14
7942                          16 16 24 16 24 24 28)
7943
7944         test_mkdir "$dir"
7945         for perm in ${perms[*]}; do
7946                 touch "$dir/$tfile.$perm"
7947                 chmod $perm "$dir/$tfile.$perm"
7948         done
7949
7950         for ((i = 0; i < ${#perms[*]}; i++)); do
7951                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7952                 (( $num == 1 )) ||
7953                         error "lfs find -perm ${perms[i]}:"\
7954                               "$num != 1"
7955
7956                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7957                 (( $num == ${perm_minus[i]} )) ||
7958                         error "lfs find -perm -${perms[i]}:"\
7959                               "$num != ${perm_minus[i]}"
7960
7961                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7962                 (( $num == ${perm_slash[i]} )) ||
7963                         error "lfs find -perm /${perms[i]}:"\
7964                               "$num != ${perm_slash[i]}"
7965         done
7966 }
7967 run_test 56aca "check lfs find -perm with octal representation"
7968
7969 test_56acb() {
7970         local dir=$DIR/$tdir
7971         # p is the permission of write and execute for user, group and other
7972         # without the umask. It is used to test +wx.
7973         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7974         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7975         local symbolic=(+t  a+t u+t g+t o+t
7976                         g+s u+s o+s +s o+sr
7977                         o=r,ug+o,u+w
7978                         u+ g+ o+ a+ ugo+
7979                         u- g- o- a- ugo-
7980                         u= g= o= a= ugo=
7981                         o=r,ug+o,u+w u=r,a+u,u+w
7982                         g=r,ugo=g,u+w u+x,+X +X
7983                         u+x,u+X u+X u+x,g+X o+r,+X
7984                         u+x,go+X +wx +rwx)
7985
7986         test_mkdir $dir
7987         for perm in ${perms[*]}; do
7988                 touch "$dir/$tfile.$perm"
7989                 chmod $perm "$dir/$tfile.$perm"
7990         done
7991
7992         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
7993                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
7994
7995                 (( $num == 1 )) ||
7996                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
7997         done
7998 }
7999 run_test 56acb "check lfs find -perm with symbolic representation"
8000
8001 test_56acc() {
8002         local dir=$DIR/$tdir
8003         local tests="17777 787 789 abcd
8004                 ug=uu ug=a ug=gu uo=ou urw
8005                 u+xg+x a=r,u+x,"
8006
8007         test_mkdir $dir
8008         for err in $tests; do
8009                 if $LFS find $dir -perm $err 2>/dev/null; then
8010                         error "lfs find -perm $err: parsing should have failed"
8011                 fi
8012         done
8013 }
8014 run_test 56acc "check parsing error for lfs find -perm"
8015
8016 test_56ba() {
8017         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8018                 skip "Need MDS version at least 2.10.50"
8019
8020         # Create composite files with one component
8021         local dir=$DIR/$tdir
8022
8023         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8024         # Create composite files with three components
8025         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8026         # Create non-composite files
8027         createmany -o $dir/${tfile}- 10
8028
8029         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8030
8031         [[ $nfiles == 10 ]] ||
8032                 error "lfs find -E 1M found $nfiles != 10 files"
8033
8034         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8035         [[ $nfiles == 25 ]] ||
8036                 error "lfs find ! -E 1M found $nfiles != 25 files"
8037
8038         # All files have a component that starts at 0
8039         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8040         [[ $nfiles == 35 ]] ||
8041                 error "lfs find --component-start 0 - $nfiles != 35 files"
8042
8043         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8044         [[ $nfiles == 15 ]] ||
8045                 error "lfs find --component-start 2M - $nfiles != 15 files"
8046
8047         # All files created here have a componenet that does not starts at 2M
8048         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8049         [[ $nfiles == 35 ]] ||
8050                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8051
8052         # Find files with a specified number of components
8053         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8054         [[ $nfiles == 15 ]] ||
8055                 error "lfs find --component-count 3 - $nfiles != 15 files"
8056
8057         # Remember non-composite files have a component count of zero
8058         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8059         [[ $nfiles == 10 ]] ||
8060                 error "lfs find --component-count 0 - $nfiles != 10 files"
8061
8062         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8063         [[ $nfiles == 20 ]] ||
8064                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8065
8066         # All files have a flag called "init"
8067         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8068         [[ $nfiles == 35 ]] ||
8069                 error "lfs find --component-flags init - $nfiles != 35 files"
8070
8071         # Multi-component files will have a component not initialized
8072         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8073         [[ $nfiles == 15 ]] ||
8074                 error "lfs find !--component-flags init - $nfiles != 15 files"
8075
8076         rm -rf $dir
8077
8078 }
8079 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8080
8081 test_56ca() {
8082         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8083                 skip "Need MDS version at least 2.10.57"
8084
8085         local td=$DIR/$tdir
8086         local tf=$td/$tfile
8087         local dir
8088         local nfiles
8089         local cmd
8090         local i
8091         local j
8092
8093         # create mirrored directories and mirrored files
8094         mkdir $td || error "mkdir $td failed"
8095         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8096         createmany -o $tf- 10 || error "create $tf- failed"
8097
8098         for i in $(seq 2); do
8099                 dir=$td/dir$i
8100                 mkdir $dir || error "mkdir $dir failed"
8101                 $LFS mirror create -N$((3 + i)) $dir ||
8102                         error "create mirrored dir $dir failed"
8103                 createmany -o $dir/$tfile- 10 ||
8104                         error "create $dir/$tfile- failed"
8105         done
8106
8107         # change the states of some mirrored files
8108         echo foo > $tf-6
8109         for i in $(seq 2); do
8110                 dir=$td/dir$i
8111                 for j in $(seq 4 9); do
8112                         echo foo > $dir/$tfile-$j
8113                 done
8114         done
8115
8116         # find mirrored files with specific mirror count
8117         cmd="$LFS find --mirror-count 3 --type f $td"
8118         nfiles=$($cmd | wc -l)
8119         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8120
8121         cmd="$LFS find ! --mirror-count 3 --type f $td"
8122         nfiles=$($cmd | wc -l)
8123         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8124
8125         cmd="$LFS find --mirror-count +2 --type f $td"
8126         nfiles=$($cmd | wc -l)
8127         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8128
8129         cmd="$LFS find --mirror-count -6 --type f $td"
8130         nfiles=$($cmd | wc -l)
8131         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8132
8133         # find mirrored files with specific file state
8134         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8135         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8136
8137         cmd="$LFS find --mirror-state=ro --type f $td"
8138         nfiles=$($cmd | wc -l)
8139         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8140
8141         cmd="$LFS find ! --mirror-state=ro --type f $td"
8142         nfiles=$($cmd | wc -l)
8143         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8144
8145         cmd="$LFS find --mirror-state=wp --type f $td"
8146         nfiles=$($cmd | wc -l)
8147         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8148
8149         cmd="$LFS find ! --mirror-state=sp --type f $td"
8150         nfiles=$($cmd | wc -l)
8151         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8152 }
8153 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8154
8155 test_56da() { # LU-14179
8156         local path=$DIR/$tdir
8157
8158         test_mkdir $path
8159         cd $path
8160
8161         local longdir=$(str_repeat 'a' 255)
8162
8163         for i in {1..15}; do
8164                 path=$path/$longdir
8165                 test_mkdir $longdir
8166                 cd $longdir
8167         done
8168
8169         local len=${#path}
8170         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8171
8172         test_mkdir $lastdir
8173         cd $lastdir
8174         # PATH_MAX-1
8175         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8176
8177         # NAME_MAX
8178         touch $(str_repeat 'f' 255)
8179
8180         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8181                 error "lfs find reported an error"
8182
8183         rm -rf $DIR/$tdir
8184 }
8185 run_test 56da "test lfs find with long paths"
8186
8187 test_57a() {
8188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8189         # note test will not do anything if MDS is not local
8190         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8191                 skip_env "ldiskfs only test"
8192         fi
8193         remote_mds_nodsh && skip "remote MDS with nodsh"
8194
8195         local MNTDEV="osd*.*MDT*.mntdev"
8196         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8197         [ -z "$DEV" ] && error "can't access $MNTDEV"
8198         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8199                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8200                         error "can't access $DEV"
8201                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8202                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8203                 rm $TMP/t57a.dump
8204         done
8205 }
8206 run_test 57a "verify MDS filesystem created with large inodes =="
8207
8208 test_57b() {
8209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8210         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8211                 skip_env "ldiskfs only test"
8212         fi
8213         remote_mds_nodsh && skip "remote MDS with nodsh"
8214
8215         local dir=$DIR/$tdir
8216         local filecount=100
8217         local file1=$dir/f1
8218         local fileN=$dir/f$filecount
8219
8220         rm -rf $dir || error "removing $dir"
8221         test_mkdir -c1 $dir
8222         local mdtidx=$($LFS getstripe -m $dir)
8223         local mdtname=MDT$(printf %04x $mdtidx)
8224         local facet=mds$((mdtidx + 1))
8225
8226         echo "mcreating $filecount files"
8227         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8228
8229         # verify that files do not have EAs yet
8230         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8231                 error "$file1 has an EA"
8232         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8233                 error "$fileN has an EA"
8234
8235         sync
8236         sleep 1
8237         df $dir  #make sure we get new statfs data
8238         local mdsfree=$(do_facet $facet \
8239                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8240         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8241         local file
8242
8243         echo "opening files to create objects/EAs"
8244         for file in $(seq -f $dir/f%g 1 $filecount); do
8245                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8246                         error "opening $file"
8247         done
8248
8249         # verify that files have EAs now
8250         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8251         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8252
8253         sleep 1  #make sure we get new statfs data
8254         df $dir
8255         local mdsfree2=$(do_facet $facet \
8256                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8257         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8258
8259         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8260                 if [ "$mdsfree" != "$mdsfree2" ]; then
8261                         error "MDC before $mdcfree != after $mdcfree2"
8262                 else
8263                         echo "MDC before $mdcfree != after $mdcfree2"
8264                         echo "unable to confirm if MDS has large inodes"
8265                 fi
8266         fi
8267         rm -rf $dir
8268 }
8269 run_test 57b "default LOV EAs are stored inside large inodes ==="
8270
8271 test_58() {
8272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8273         [ -z "$(which wiretest 2>/dev/null)" ] &&
8274                         skip_env "could not find wiretest"
8275
8276         wiretest
8277 }
8278 run_test 58 "verify cross-platform wire constants =============="
8279
8280 test_59() {
8281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8282
8283         echo "touch 130 files"
8284         createmany -o $DIR/f59- 130
8285         echo "rm 130 files"
8286         unlinkmany $DIR/f59- 130
8287         sync
8288         # wait for commitment of removal
8289         wait_delete_completed
8290 }
8291 run_test 59 "verify cancellation of llog records async ========="
8292
8293 TEST60_HEAD="test_60 run $RANDOM"
8294 test_60a() {
8295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8296         remote_mgs_nodsh && skip "remote MGS with nodsh"
8297         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8298                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8299                         skip_env "missing subtest run-llog.sh"
8300
8301         log "$TEST60_HEAD - from kernel mode"
8302         do_facet mgs "$LCTL dk > /dev/null"
8303         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8304         do_facet mgs $LCTL dk > $TMP/$tfile
8305
8306         # LU-6388: test llog_reader
8307         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8308         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8309         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8310                         skip_env "missing llog_reader"
8311         local fstype=$(facet_fstype mgs)
8312         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8313                 skip_env "Only for ldiskfs or zfs type mgs"
8314
8315         local mntpt=$(facet_mntpt mgs)
8316         local mgsdev=$(mgsdevname 1)
8317         local fid_list
8318         local fid
8319         local rec_list
8320         local rec
8321         local rec_type
8322         local obj_file
8323         local path
8324         local seq
8325         local oid
8326         local pass=true
8327
8328         #get fid and record list
8329         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8330                 tail -n 4))
8331         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8332                 tail -n 4))
8333         #remount mgs as ldiskfs or zfs type
8334         stop mgs || error "stop mgs failed"
8335         mount_fstype mgs || error "remount mgs failed"
8336         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8337                 fid=${fid_list[i]}
8338                 rec=${rec_list[i]}
8339                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8340                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8341                 oid=$((16#$oid))
8342
8343                 case $fstype in
8344                         ldiskfs )
8345                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8346                         zfs )
8347                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8348                 esac
8349                 echo "obj_file is $obj_file"
8350                 do_facet mgs $llog_reader $obj_file
8351
8352                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8353                         awk '{ print $3 }' | sed -e "s/^type=//g")
8354                 if [ $rec_type != $rec ]; then
8355                         echo "FAILED test_60a wrong record type $rec_type," \
8356                               "should be $rec"
8357                         pass=false
8358                         break
8359                 fi
8360
8361                 #check obj path if record type is LLOG_LOGID_MAGIC
8362                 if [ "$rec" == "1064553b" ]; then
8363                         path=$(do_facet mgs $llog_reader $obj_file |
8364                                 grep "path=" | awk '{ print $NF }' |
8365                                 sed -e "s/^path=//g")
8366                         if [ $obj_file != $mntpt/$path ]; then
8367                                 echo "FAILED test_60a wrong obj path" \
8368                                       "$montpt/$path, should be $obj_file"
8369                                 pass=false
8370                                 break
8371                         fi
8372                 fi
8373         done
8374         rm -f $TMP/$tfile
8375         #restart mgs before "error", otherwise it will block the next test
8376         stop mgs || error "stop mgs failed"
8377         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8378         $pass || error "test failed, see FAILED test_60a messages for specifics"
8379 }
8380 run_test 60a "llog_test run from kernel module and test llog_reader"
8381
8382 test_60b() { # bug 6411
8383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8384
8385         dmesg > $DIR/$tfile
8386         LLOG_COUNT=$(do_facet mgs dmesg |
8387                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8388                           /llog_[a-z]*.c:[0-9]/ {
8389                                 if (marker)
8390                                         from_marker++
8391                                 from_begin++
8392                           }
8393                           END {
8394                                 if (marker)
8395                                         print from_marker
8396                                 else
8397                                         print from_begin
8398                           }")
8399
8400         [[ $LLOG_COUNT -gt 120 ]] &&
8401                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8402 }
8403 run_test 60b "limit repeated messages from CERROR/CWARN"
8404
8405 test_60c() {
8406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8407
8408         echo "create 5000 files"
8409         createmany -o $DIR/f60c- 5000
8410 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8411         lctl set_param fail_loc=0x80000137
8412         unlinkmany $DIR/f60c- 5000
8413         lctl set_param fail_loc=0
8414 }
8415 run_test 60c "unlink file when mds full"
8416
8417 test_60d() {
8418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8419
8420         SAVEPRINTK=$(lctl get_param -n printk)
8421         # verify "lctl mark" is even working"
8422         MESSAGE="test message ID $RANDOM $$"
8423         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8424         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8425
8426         lctl set_param printk=0 || error "set lnet.printk failed"
8427         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8428         MESSAGE="new test message ID $RANDOM $$"
8429         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8430         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8431         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8432
8433         lctl set_param -n printk="$SAVEPRINTK"
8434 }
8435 run_test 60d "test printk console message masking"
8436
8437 test_60e() {
8438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8439         remote_mds_nodsh && skip "remote MDS with nodsh"
8440
8441         touch $DIR/$tfile
8442 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8443         do_facet mds1 lctl set_param fail_loc=0x15b
8444         rm $DIR/$tfile
8445 }
8446 run_test 60e "no space while new llog is being created"
8447
8448 test_60f() {
8449         local old_path=$($LCTL get_param -n debug_path)
8450
8451         stack_trap "$LCTL set_param debug_path=$old_path"
8452         stack_trap "rm -f $TMP/$tfile*"
8453         rm -f $TMP/$tfile* 2> /dev/null
8454         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8455         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8456         test_mkdir $DIR/$tdir
8457         # retry in case the open is cached and not released
8458         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8459                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8460                 sleep 0.1
8461         done
8462         ls $TMP/$tfile*
8463         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8464 }
8465 run_test 60f "change debug_path works"
8466
8467 test_60g() {
8468         local pid
8469         local i
8470
8471         test_mkdir -c $MDSCOUNT $DIR/$tdir
8472
8473         (
8474                 local index=0
8475                 while true; do
8476                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8477                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8478                                 2>/dev/null
8479                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8480                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8481                         index=$((index + 1))
8482                 done
8483         ) &
8484
8485         pid=$!
8486
8487         for i in {0..100}; do
8488                 # define OBD_FAIL_OSD_TXN_START    0x19a
8489                 local index=$((i % MDSCOUNT + 1))
8490
8491                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8492                         > /dev/null
8493                 sleep 0.01
8494         done
8495
8496         kill -9 $pid
8497
8498         for i in $(seq $MDSCOUNT); do
8499                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8500         done
8501
8502         mkdir $DIR/$tdir/new || error "mkdir failed"
8503         rmdir $DIR/$tdir/new || error "rmdir failed"
8504
8505         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8506                 -t namespace
8507         for i in $(seq $MDSCOUNT); do
8508                 wait_update_facet mds$i "$LCTL get_param -n \
8509                         mdd.$(facet_svc mds$i).lfsck_namespace |
8510                         awk '/^status/ { print \\\$2 }'" "completed"
8511         done
8512
8513         ls -R $DIR/$tdir
8514         rm -rf $DIR/$tdir || error "rmdir failed"
8515 }
8516 run_test 60g "transaction abort won't cause MDT hung"
8517
8518 test_60h() {
8519         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8520                 skip "Need MDS version at least 2.12.52"
8521         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8522
8523         local f
8524
8525         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8526         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8527         for fail_loc in 0x80000188 0x80000189; do
8528                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8529                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8530                         error "mkdir $dir-$fail_loc failed"
8531                 for i in {0..10}; do
8532                         # create may fail on missing stripe
8533                         echo $i > $DIR/$tdir-$fail_loc/$i
8534                 done
8535                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8536                         error "getdirstripe $tdir-$fail_loc failed"
8537                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8538                         error "migrate $tdir-$fail_loc failed"
8539                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8540                         error "getdirstripe $tdir-$fail_loc failed"
8541                 pushd $DIR/$tdir-$fail_loc
8542                 for f in *; do
8543                         echo $f | cmp $f - || error "$f data mismatch"
8544                 done
8545                 popd
8546                 rm -rf $DIR/$tdir-$fail_loc
8547         done
8548 }
8549 run_test 60h "striped directory with missing stripes can be accessed"
8550
8551 function t60i_load() {
8552         mkdir $DIR/$tdir
8553         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8554         $LCTL set_param fail_loc=0x131c fail_val=1
8555         for ((i=0; i<5000; i++)); do
8556                 touch $DIR/$tdir/f$i
8557         done
8558 }
8559
8560 test_60i() {
8561         changelog_register || error "changelog_register failed"
8562         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8563         changelog_users $SINGLEMDS | grep -q $cl_user ||
8564                 error "User $cl_user not found in changelog_users"
8565         changelog_chmask "ALL"
8566         t60i_load &
8567         local PID=$!
8568         for((i=0; i<100; i++)); do
8569                 changelog_dump >/dev/null ||
8570                         error "can't read changelog"
8571         done
8572         kill $PID
8573         wait $PID
8574         changelog_deregister || error "changelog_deregister failed"
8575         $LCTL set_param fail_loc=0
8576 }
8577 run_test 60i "llog: new record vs reader race"
8578
8579 test_61a() {
8580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8581
8582         f="$DIR/f61"
8583         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8584         cancel_lru_locks osc
8585         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8586         sync
8587 }
8588 run_test 61a "mmap() writes don't make sync hang ================"
8589
8590 test_61b() {
8591         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8592 }
8593 run_test 61b "mmap() of unstriped file is successful"
8594
8595 # bug 2330 - insufficient obd_match error checking causes LBUG
8596 test_62() {
8597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8598
8599         f="$DIR/f62"
8600         echo foo > $f
8601         cancel_lru_locks osc
8602         lctl set_param fail_loc=0x405
8603         cat $f && error "cat succeeded, expect -EIO"
8604         lctl set_param fail_loc=0
8605 }
8606 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8607 # match every page all of the time.
8608 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8609
8610 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8611 # Though this test is irrelevant anymore, it helped to reveal some
8612 # other grant bugs (LU-4482), let's keep it.
8613 test_63a() {   # was test_63
8614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8615
8616         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8617
8618         for i in `seq 10` ; do
8619                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8620                 sleep 5
8621                 kill $!
8622                 sleep 1
8623         done
8624
8625         rm -f $DIR/f63 || true
8626 }
8627 run_test 63a "Verify oig_wait interruption does not crash ======="
8628
8629 # bug 2248 - async write errors didn't return to application on sync
8630 # bug 3677 - async write errors left page locked
8631 test_63b() {
8632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8633
8634         debugsave
8635         lctl set_param debug=-1
8636
8637         # ensure we have a grant to do async writes
8638         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8639         rm $DIR/$tfile
8640
8641         sync    # sync lest earlier test intercept the fail_loc
8642
8643         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8644         lctl set_param fail_loc=0x80000406
8645         $MULTIOP $DIR/$tfile Owy && \
8646                 error "sync didn't return ENOMEM"
8647         sync; sleep 2; sync     # do a real sync this time to flush page
8648         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8649                 error "locked page left in cache after async error" || true
8650         debugrestore
8651 }
8652 run_test 63b "async write errors should be returned to fsync ==="
8653
8654 test_64a () {
8655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8656
8657         lfs df $DIR
8658         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8659 }
8660 run_test 64a "verify filter grant calculations (in kernel) ====="
8661
8662 test_64b () {
8663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8664
8665         bash oos.sh $MOUNT || error "oos.sh failed: $?"
8666 }
8667 run_test 64b "check out-of-space detection on client"
8668
8669 test_64c() {
8670         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8671 }
8672 run_test 64c "verify grant shrink"
8673
8674 import_param() {
8675         local tgt=$1
8676         local param=$2
8677
8678         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8679 }
8680
8681 # this does exactly what osc_request.c:osc_announce_cached() does in
8682 # order to calculate max amount of grants to ask from server
8683 want_grant() {
8684         local tgt=$1
8685
8686         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8687         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8688
8689         ((rpc_in_flight++));
8690         nrpages=$((nrpages * rpc_in_flight))
8691
8692         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8693
8694         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8695
8696         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8697         local undirty=$((nrpages * PAGE_SIZE))
8698
8699         local max_extent_pages
8700         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8701         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8702         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8703         local grant_extent_tax
8704         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8705
8706         undirty=$((undirty + nrextents * grant_extent_tax))
8707
8708         echo $undirty
8709 }
8710
8711 # this is size of unit for grant allocation. It should be equal to
8712 # what tgt_grant.c:tgt_grant_chunk() calculates
8713 grant_chunk() {
8714         local tgt=$1
8715         local max_brw_size
8716         local grant_extent_tax
8717
8718         max_brw_size=$(import_param $tgt max_brw_size)
8719
8720         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8721
8722         echo $(((max_brw_size + grant_extent_tax) * 2))
8723 }
8724
8725 test_64d() {
8726         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8727                 skip "OST < 2.10.55 doesn't limit grants enough"
8728
8729         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8730
8731         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8732                 skip "no grant_param connect flag"
8733
8734         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8735
8736         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8737         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8738
8739
8740         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8741         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8742
8743         $LFS setstripe $DIR/$tfile -i 0 -c 1
8744         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8745         ddpid=$!
8746
8747         while kill -0 $ddpid; do
8748                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8749
8750                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8751                         kill $ddpid
8752                         error "cur_grant $cur_grant > $max_cur_granted"
8753                 fi
8754
8755                 sleep 1
8756         done
8757 }
8758 run_test 64d "check grant limit exceed"
8759
8760 check_grants() {
8761         local tgt=$1
8762         local expected=$2
8763         local msg=$3
8764         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8765
8766         ((cur_grants == expected)) ||
8767                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8768 }
8769
8770 round_up_p2() {
8771         echo $((($1 + $2 - 1) & ~($2 - 1)))
8772 }
8773
8774 test_64e() {
8775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8776         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8777                 skip "Need OSS version at least 2.11.56"
8778
8779         # Remount client to reset grant
8780         remount_client $MOUNT || error "failed to remount client"
8781         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8782
8783         local init_grants=$(import_param $osc_tgt initial_grant)
8784
8785         check_grants $osc_tgt $init_grants "init grants"
8786
8787         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8788         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8789         local gbs=$(import_param $osc_tgt grant_block_size)
8790
8791         # write random number of bytes from max_brw_size / 4 to max_brw_size
8792         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8793         # align for direct io
8794         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8795         # round to grant consumption unit
8796         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8797
8798         local grants=$((wb_round_up + extent_tax))
8799
8800         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8801
8802         # define OBD_FAIL_TGT_NO_GRANT 0x725
8803         # make the server not grant more back
8804         do_facet ost1 $LCTL set_param fail_loc=0x725
8805         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8806
8807         do_facet ost1 $LCTL set_param fail_loc=0
8808
8809         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8810
8811         rm -f $DIR/$tfile || error "rm failed"
8812
8813         # Remount client to reset grant
8814         remount_client $MOUNT || error "failed to remount client"
8815         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8816
8817         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8818
8819         # define OBD_FAIL_TGT_NO_GRANT 0x725
8820         # make the server not grant more back
8821         do_facet ost1 $LCTL set_param fail_loc=0x725
8822         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8823         do_facet ost1 $LCTL set_param fail_loc=0
8824
8825         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8826 }
8827 run_test 64e "check grant consumption (no grant allocation)"
8828
8829 test_64f() {
8830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8831
8832         # Remount client to reset grant
8833         remount_client $MOUNT || error "failed to remount client"
8834         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8835
8836         local init_grants=$(import_param $osc_tgt initial_grant)
8837         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8838         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8839         local gbs=$(import_param $osc_tgt grant_block_size)
8840         local chunk=$(grant_chunk $osc_tgt)
8841
8842         # write random number of bytes from max_brw_size / 4 to max_brw_size
8843         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8844         # align for direct io
8845         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8846         # round to grant consumption unit
8847         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8848
8849         local grants=$((wb_round_up + extent_tax))
8850
8851         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8852         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8853                 error "error writing to $DIR/$tfile"
8854
8855         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8856                 "direct io with grant allocation"
8857
8858         rm -f $DIR/$tfile || error "rm failed"
8859
8860         # Remount client to reset grant
8861         remount_client $MOUNT || error "failed to remount client"
8862         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8863
8864         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8865
8866         local cmd="oO_WRONLY:w${write_bytes}_yc"
8867
8868         $MULTIOP $DIR/$tfile $cmd &
8869         MULTIPID=$!
8870         sleep 1
8871
8872         check_grants $osc_tgt $((init_grants - grants)) \
8873                 "buffered io, not write rpc"
8874
8875         kill -USR1 $MULTIPID
8876         wait
8877
8878         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8879                 "buffered io, one RPC"
8880 }
8881 run_test 64f "check grant consumption (with grant allocation)"
8882
8883 test_64g() {
8884         #[ $MDS1_VERSION -lt $(version_code 2.14.54) ] &&
8885         #       skip "Need MDS version at least 2.14.54"
8886
8887         local mdts=$(comma_list $(mdts_nodes))
8888
8889         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
8890                         tr '\n' ' ')
8891         stack_trap "$LCTL set_param $old"
8892
8893         # generate dirty pages and increase dirty granted on MDT
8894         stack_trap "rm -f $DIR/$tfile-*"
8895         for (( i = 0; i < 10; i++)); do
8896                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
8897                         error "can't set stripe"
8898                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
8899                         error "can't dd"
8900                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
8901                         $LFS getstripe $DIR/$tfile-$i
8902                         error "not DoM file"
8903                 }
8904         done
8905
8906         # flush dirty pages
8907         sync
8908
8909         # wait until grant shrink reset grant dirty on MDTs
8910         for ((i = 0; i < 120; i++)); do
8911                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8912                         awk '{sum=sum+$1} END {print sum}')
8913                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
8914                 echo "$grant_dirty grants, $vm_dirty pages"
8915                 (( grant_dirty + vm_dirty == 0 )) && break
8916                 (( i == 3 )) && sync &&
8917                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
8918                 sleep 1
8919         done
8920
8921         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8922                 awk '{sum=sum+$1} END {print sum}')
8923         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
8924 }
8925 run_test 64g "grant shrink on MDT"
8926
8927 test_64h() {
8928         local instance=$($LFS getname -i $DIR)
8929         local osc_tgt="$FSNAME-OST0000-osc-$instance"
8930         local num_exps=$(do_facet ost1 \
8931             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
8932         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8933         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
8934         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8935
8936         # 10MiB is for file to be written, max_brw_size * 16 *
8937         # num_exps is space reserve so that tgt_grant_shrink() decided
8938         # to not shrink
8939         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
8940         (( avail * 1024 < expect )) &&
8941                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
8942
8943         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
8944         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
8945         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
8946         $LCTL set_param osc.*OST0000*.grant_shrink=1
8947         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
8948
8949         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8950         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
8951
8952         # drop cache so that coming read would do rpc
8953         cancel_lru_locks osc
8954
8955         # shrink interval is set to 10, pause for 7 seconds so that
8956         # grant thread did not wake up yet but coming read entered
8957         # shrink mode for rpc (osc_should_shrink_grant())
8958         sleep 7
8959
8960         declare -a cur_grant_bytes
8961         declare -a tot_granted
8962         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
8963         tot_granted[0]=$(do_facet ost1 \
8964             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
8965
8966         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
8967
8968         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
8969         tot_granted[1]=$(do_facet ost1 \
8970             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
8971
8972         # grant change should be equal on both sides
8973         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
8974                 tot_granted[0] - tot_granted[1])) ||
8975                 error "grant change mismatch, "                                \
8976                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
8977                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
8978 }
8979 run_test 64h "grant shrink on read"
8980
8981 test_64i() {
8982         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
8983                 skip "need OST at least 2.14.55 to avoid grant shrink on replay"
8984
8985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8986         remote_ost_nodsh && skip "remote OSTs with nodsh"
8987
8988         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8989
8990         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
8991
8992         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
8993         local instance=$($LFS getname -i $DIR)
8994
8995         local osc_tgt="$FSNAME-OST0000-osc-$instance"
8996         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
8997
8998         # shrink grants and simulate rpc loss
8999         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9000         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9001         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9002
9003         fail ost1
9004
9005         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9006
9007         local testid=$(echo $TESTNAME | tr '_' ' ')
9008
9009         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9010                 grep "GRANT, real grant" &&
9011                 error "client has more grants then it owns" || true
9012 }
9013 run_test 64i "shrink on reconnect"
9014
9015 # bug 1414 - set/get directories' stripe info
9016 test_65a() {
9017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9018
9019         test_mkdir $DIR/$tdir
9020         touch $DIR/$tdir/f1
9021         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9022 }
9023 run_test 65a "directory with no stripe info"
9024
9025 test_65b() {
9026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9027
9028         test_mkdir $DIR/$tdir
9029         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9030
9031         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9032                                                 error "setstripe"
9033         touch $DIR/$tdir/f2
9034         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9035 }
9036 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9037
9038 test_65c() {
9039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9040         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9041
9042         test_mkdir $DIR/$tdir
9043         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9044
9045         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9046                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9047         touch $DIR/$tdir/f3
9048         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9049 }
9050 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9051
9052 test_65d() {
9053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9054
9055         test_mkdir $DIR/$tdir
9056         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9057         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9058
9059         if [[ $STRIPECOUNT -le 0 ]]; then
9060                 sc=1
9061         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9062                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9063                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9064         else
9065                 sc=$(($STRIPECOUNT - 1))
9066         fi
9067         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9068         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9069         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9070                 error "lverify failed"
9071 }
9072 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9073
9074 test_65e() {
9075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9076
9077         test_mkdir $DIR/$tdir
9078
9079         $LFS setstripe $DIR/$tdir || error "setstripe"
9080         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9081                                         error "no stripe info failed"
9082         touch $DIR/$tdir/f6
9083         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9084 }
9085 run_test 65e "directory setstripe defaults"
9086
9087 test_65f() {
9088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9089
9090         test_mkdir $DIR/${tdir}f
9091         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9092                 error "setstripe succeeded" || true
9093 }
9094 run_test 65f "dir setstripe permission (should return error) ==="
9095
9096 test_65g() {
9097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9098
9099         test_mkdir $DIR/$tdir
9100         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9101
9102         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9103                 error "setstripe -S failed"
9104         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9105         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9106                 error "delete default stripe failed"
9107 }
9108 run_test 65g "directory setstripe -d"
9109
9110 test_65h() {
9111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9112
9113         test_mkdir $DIR/$tdir
9114         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9115
9116         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9117                 error "setstripe -S failed"
9118         test_mkdir $DIR/$tdir/dd1
9119         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9120                 error "stripe info inherit failed"
9121 }
9122 run_test 65h "directory stripe info inherit ===================="
9123
9124 test_65i() {
9125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9126
9127         save_layout_restore_at_exit $MOUNT
9128
9129         # bug6367: set non-default striping on root directory
9130         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9131
9132         # bug12836: getstripe on -1 default directory striping
9133         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9134
9135         # bug12836: getstripe -v on -1 default directory striping
9136         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9137
9138         # bug12836: new find on -1 default directory striping
9139         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9140 }
9141 run_test 65i "various tests to set root directory striping"
9142
9143 test_65j() { # bug6367
9144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9145
9146         sync; sleep 1
9147
9148         # if we aren't already remounting for each test, do so for this test
9149         if [ "$I_MOUNTED" = "yes" ]; then
9150                 cleanup || error "failed to unmount"
9151                 setup
9152         fi
9153
9154         save_layout_restore_at_exit $MOUNT
9155
9156         $LFS setstripe -d $MOUNT || error "setstripe failed"
9157 }
9158 run_test 65j "set default striping on root directory (bug 6367)="
9159
9160 cleanup_65k() {
9161         rm -rf $DIR/$tdir
9162         wait_delete_completed
9163         do_facet $SINGLEMDS "lctl set_param -n \
9164                 osp.$ost*MDT0000.max_create_count=$max_count"
9165         do_facet $SINGLEMDS "lctl set_param -n \
9166                 osp.$ost*MDT0000.create_count=$count"
9167         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9168         echo $INACTIVE_OSC "is Activate"
9169
9170         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9171 }
9172
9173 test_65k() { # bug11679
9174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9175         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9176         remote_mds_nodsh && skip "remote MDS with nodsh"
9177
9178         local disable_precreate=true
9179         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9180                 disable_precreate=false
9181
9182         echo "Check OST status: "
9183         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9184                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9185
9186         for OSC in $MDS_OSCS; do
9187                 echo $OSC "is active"
9188                 do_facet $SINGLEMDS lctl --device %$OSC activate
9189         done
9190
9191         for INACTIVE_OSC in $MDS_OSCS; do
9192                 local ost=$(osc_to_ost $INACTIVE_OSC)
9193                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9194                                lov.*md*.target_obd |
9195                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9196
9197                 mkdir -p $DIR/$tdir
9198                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9199                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9200
9201                 echo "Deactivate: " $INACTIVE_OSC
9202                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9203
9204                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9205                               osp.$ost*MDT0000.create_count")
9206                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9207                                   osp.$ost*MDT0000.max_create_count")
9208                 $disable_precreate &&
9209                         do_facet $SINGLEMDS "lctl set_param -n \
9210                                 osp.$ost*MDT0000.max_create_count=0"
9211
9212                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9213                         [ -f $DIR/$tdir/$idx ] && continue
9214                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9215                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9216                                 { cleanup_65k;
9217                                   error "setstripe $idx should succeed"; }
9218                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9219                 done
9220                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9221                 rmdir $DIR/$tdir
9222
9223                 do_facet $SINGLEMDS "lctl set_param -n \
9224                         osp.$ost*MDT0000.max_create_count=$max_count"
9225                 do_facet $SINGLEMDS "lctl set_param -n \
9226                         osp.$ost*MDT0000.create_count=$count"
9227                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9228                 echo $INACTIVE_OSC "is Activate"
9229
9230                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9231         done
9232 }
9233 run_test 65k "validate manual striping works properly with deactivated OSCs"
9234
9235 test_65l() { # bug 12836
9236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9237
9238         test_mkdir -p $DIR/$tdir/test_dir
9239         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9240         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9241 }
9242 run_test 65l "lfs find on -1 stripe dir ========================"
9243
9244 test_65m() {
9245         local layout=$(save_layout $MOUNT)
9246         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9247                 restore_layout $MOUNT $layout
9248                 error "setstripe should fail by non-root users"
9249         }
9250         true
9251 }
9252 run_test 65m "normal user can't set filesystem default stripe"
9253
9254 test_65n() {
9255         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9256         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9257                 skip "Need MDS version at least 2.12.50"
9258         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9259
9260         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9261         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9262         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9263
9264         save_layout_restore_at_exit $MOUNT
9265
9266         # new subdirectory under root directory should not inherit
9267         # the default layout from root
9268         local dir1=$MOUNT/$tdir-1
9269         mkdir $dir1 || error "mkdir $dir1 failed"
9270         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9271                 error "$dir1 shouldn't have LOV EA"
9272
9273         # delete the default layout on root directory
9274         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9275
9276         local dir2=$MOUNT/$tdir-2
9277         mkdir $dir2 || error "mkdir $dir2 failed"
9278         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9279                 error "$dir2 shouldn't have LOV EA"
9280
9281         # set a new striping pattern on root directory
9282         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9283         local new_def_stripe_size=$((def_stripe_size * 2))
9284         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9285                 error "set stripe size on $MOUNT failed"
9286
9287         # new file created in $dir2 should inherit the new stripe size from
9288         # the filesystem default
9289         local file2=$dir2/$tfile-2
9290         touch $file2 || error "touch $file2 failed"
9291
9292         local file2_stripe_size=$($LFS getstripe -S $file2)
9293         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9294         {
9295                 echo "file2_stripe_size: '$file2_stripe_size'"
9296                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9297                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9298         }
9299
9300         local dir3=$MOUNT/$tdir-3
9301         mkdir $dir3 || error "mkdir $dir3 failed"
9302         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9303         # the root layout, which is the actual default layout that will be used
9304         # when new files are created in $dir3.
9305         local dir3_layout=$(get_layout_param $dir3)
9306         local root_dir_layout=$(get_layout_param $MOUNT)
9307         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9308         {
9309                 echo "dir3_layout: '$dir3_layout'"
9310                 echo "root_dir_layout: '$root_dir_layout'"
9311                 error "$dir3 should show the default layout from $MOUNT"
9312         }
9313
9314         # set OST pool on root directory
9315         local pool=$TESTNAME
9316         pool_add $pool || error "add $pool failed"
9317         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9318                 error "add targets to $pool failed"
9319
9320         $LFS setstripe -p $pool $MOUNT ||
9321                 error "set OST pool on $MOUNT failed"
9322
9323         # new file created in $dir3 should inherit the pool from
9324         # the filesystem default
9325         local file3=$dir3/$tfile-3
9326         touch $file3 || error "touch $file3 failed"
9327
9328         local file3_pool=$($LFS getstripe -p $file3)
9329         [[ "$file3_pool" = "$pool" ]] ||
9330                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9331
9332         local dir4=$MOUNT/$tdir-4
9333         mkdir $dir4 || error "mkdir $dir4 failed"
9334         local dir4_layout=$(get_layout_param $dir4)
9335         root_dir_layout=$(get_layout_param $MOUNT)
9336         echo "$LFS getstripe -d $dir4"
9337         $LFS getstripe -d $dir4
9338         echo "$LFS getstripe -d $MOUNT"
9339         $LFS getstripe -d $MOUNT
9340         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9341         {
9342                 echo "dir4_layout: '$dir4_layout'"
9343                 echo "root_dir_layout: '$root_dir_layout'"
9344                 error "$dir4 should show the default layout from $MOUNT"
9345         }
9346
9347         # new file created in $dir4 should inherit the pool from
9348         # the filesystem default
9349         local file4=$dir4/$tfile-4
9350         touch $file4 || error "touch $file4 failed"
9351
9352         local file4_pool=$($LFS getstripe -p $file4)
9353         [[ "$file4_pool" = "$pool" ]] ||
9354                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9355
9356         # new subdirectory under non-root directory should inherit
9357         # the default layout from its parent directory
9358         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9359                 error "set directory layout on $dir4 failed"
9360
9361         local dir5=$dir4/$tdir-5
9362         mkdir $dir5 || error "mkdir $dir5 failed"
9363
9364         dir4_layout=$(get_layout_param $dir4)
9365         local dir5_layout=$(get_layout_param $dir5)
9366         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9367         {
9368                 echo "dir4_layout: '$dir4_layout'"
9369                 echo "dir5_layout: '$dir5_layout'"
9370                 error "$dir5 should inherit the default layout from $dir4"
9371         }
9372
9373         # though subdir under ROOT doesn't inherit default layout, but
9374         # its sub dir/file should be created with default layout.
9375         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9376         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9377                 skip "Need MDS version at least 2.12.59"
9378
9379         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9380         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9381         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9382
9383         if [ $default_lmv_hash == "none" ]; then
9384                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9385         else
9386                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9387                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9388         fi
9389
9390         $LFS setdirstripe -D -c 2 $MOUNT ||
9391                 error "setdirstripe -D -c 2 failed"
9392         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9393         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9394         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9395
9396         # $dir4 layout includes pool
9397         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9398         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9399                 error "pool lost on setstripe"
9400         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9401         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9402                 error "pool lost on compound layout setstripe"
9403 }
9404 run_test 65n "don't inherit default layout from root for new subdirectories"
9405
9406 # bug 2543 - update blocks count on client
9407 test_66() {
9408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9409
9410         COUNT=${COUNT:-8}
9411         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9412         sync; sync_all_data; sync; sync_all_data
9413         cancel_lru_locks osc
9414         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9415         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9416 }
9417 run_test 66 "update inode blocks count on client ==============="
9418
9419 meminfo() {
9420         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9421 }
9422
9423 swap_used() {
9424         swapon -s | awk '($1 == "'$1'") { print $4 }'
9425 }
9426
9427 # bug5265, obdfilter oa2dentry return -ENOENT
9428 # #define OBD_FAIL_SRV_ENOENT 0x217
9429 test_69() {
9430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9431         remote_ost_nodsh && skip "remote OST with nodsh"
9432
9433         f="$DIR/$tfile"
9434         $LFS setstripe -c 1 -i 0 $f
9435
9436         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9437
9438         do_facet ost1 lctl set_param fail_loc=0x217
9439         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9440         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9441
9442         do_facet ost1 lctl set_param fail_loc=0
9443         $DIRECTIO write $f 0 2 || error "write error"
9444
9445         cancel_lru_locks osc
9446         $DIRECTIO read $f 0 1 || error "read error"
9447
9448         do_facet ost1 lctl set_param fail_loc=0x217
9449         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9450
9451         do_facet ost1 lctl set_param fail_loc=0
9452         rm -f $f
9453 }
9454 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9455
9456 test_71() {
9457         test_mkdir $DIR/$tdir
9458         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9459         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9460 }
9461 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9462
9463 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9465         [ "$RUNAS_ID" = "$UID" ] &&
9466                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9467         # Check that testing environment is properly set up. Skip if not
9468         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9469                 skip_env "User $RUNAS_ID does not exist - skipping"
9470
9471         touch $DIR/$tfile
9472         chmod 777 $DIR/$tfile
9473         chmod ug+s $DIR/$tfile
9474         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9475                 error "$RUNAS dd $DIR/$tfile failed"
9476         # See if we are still setuid/sgid
9477         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9478                 error "S/gid is not dropped on write"
9479         # Now test that MDS is updated too
9480         cancel_lru_locks mdc
9481         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9482                 error "S/gid is not dropped on MDS"
9483         rm -f $DIR/$tfile
9484 }
9485 run_test 72a "Test that remove suid works properly (bug5695) ===="
9486
9487 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9488         local perm
9489
9490         [ "$RUNAS_ID" = "$UID" ] &&
9491                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9492         [ "$RUNAS_ID" -eq 0 ] &&
9493                 skip_env "RUNAS_ID = 0 -- skipping"
9494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9495         # Check that testing environment is properly set up. Skip if not
9496         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9497                 skip_env "User $RUNAS_ID does not exist - skipping"
9498
9499         touch $DIR/${tfile}-f{g,u}
9500         test_mkdir $DIR/${tfile}-dg
9501         test_mkdir $DIR/${tfile}-du
9502         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9503         chmod g+s $DIR/${tfile}-{f,d}g
9504         chmod u+s $DIR/${tfile}-{f,d}u
9505         for perm in 777 2777 4777; do
9506                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9507                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9508                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9509                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9510         done
9511         true
9512 }
9513 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9514
9515 # bug 3462 - multiple simultaneous MDC requests
9516 test_73() {
9517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9518
9519         test_mkdir $DIR/d73-1
9520         test_mkdir $DIR/d73-2
9521         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9522         pid1=$!
9523
9524         lctl set_param fail_loc=0x80000129
9525         $MULTIOP $DIR/d73-1/f73-2 Oc &
9526         sleep 1
9527         lctl set_param fail_loc=0
9528
9529         $MULTIOP $DIR/d73-2/f73-3 Oc &
9530         pid3=$!
9531
9532         kill -USR1 $pid1
9533         wait $pid1 || return 1
9534
9535         sleep 25
9536
9537         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9538         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9539         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9540
9541         rm -rf $DIR/d73-*
9542 }
9543 run_test 73 "multiple MDC requests (should not deadlock)"
9544
9545 test_74a() { # bug 6149, 6184
9546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9547
9548         touch $DIR/f74a
9549         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9550         #
9551         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9552         # will spin in a tight reconnection loop
9553         $LCTL set_param fail_loc=0x8000030e
9554         # get any lock that won't be difficult - lookup works.
9555         ls $DIR/f74a
9556         $LCTL set_param fail_loc=0
9557         rm -f $DIR/f74a
9558         true
9559 }
9560 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9561
9562 test_74b() { # bug 13310
9563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9564
9565         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9566         #
9567         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9568         # will spin in a tight reconnection loop
9569         $LCTL set_param fail_loc=0x8000030e
9570         # get a "difficult" lock
9571         touch $DIR/f74b
9572         $LCTL set_param fail_loc=0
9573         rm -f $DIR/f74b
9574         true
9575 }
9576 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9577
9578 test_74c() {
9579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9580
9581         #define OBD_FAIL_LDLM_NEW_LOCK
9582         $LCTL set_param fail_loc=0x319
9583         touch $DIR/$tfile && error "touch successful"
9584         $LCTL set_param fail_loc=0
9585         true
9586 }
9587 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9588
9589 slab_lic=/sys/kernel/slab/lustre_inode_cache
9590 num_objects() {
9591         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9592         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9593                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9594 }
9595
9596 test_76a() { # Now for b=20433, added originally in b=1443
9597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9598
9599         cancel_lru_locks osc
9600         # there may be some slab objects cached per core
9601         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9602         local before=$(num_objects)
9603         local count=$((512 * cpus))
9604         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9605         local margin=$((count / 10))
9606         if [[ -f $slab_lic/aliases ]]; then
9607                 local aliases=$(cat $slab_lic/aliases)
9608                 (( aliases > 0 )) && margin=$((margin * aliases))
9609         fi
9610
9611         echo "before slab objects: $before"
9612         for i in $(seq $count); do
9613                 touch $DIR/$tfile
9614                 rm -f $DIR/$tfile
9615         done
9616         cancel_lru_locks osc
9617         local after=$(num_objects)
9618         echo "created: $count, after slab objects: $after"
9619         # shared slab counts are not very accurate, allow significant margin
9620         # the main goal is that the cache growth is not permanently > $count
9621         while (( after > before + margin )); do
9622                 sleep 1
9623                 after=$(num_objects)
9624                 wait=$((wait + 1))
9625                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9626                 if (( wait > 60 )); then
9627                         error "inode slab grew from $before+$margin to $after"
9628                 fi
9629         done
9630 }
9631 run_test 76a "confirm clients recycle inodes properly ===="
9632
9633 test_76b() {
9634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9635         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9636
9637         local count=512
9638         local before=$(num_objects)
9639
9640         for i in $(seq $count); do
9641                 mkdir $DIR/$tdir
9642                 rmdir $DIR/$tdir
9643         done
9644
9645         local after=$(num_objects)
9646         local wait=0
9647
9648         while (( after > before )); do
9649                 sleep 1
9650                 after=$(num_objects)
9651                 wait=$((wait + 1))
9652                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9653                 if (( wait > 60 )); then
9654                         error "inode slab grew from $before to $after"
9655                 fi
9656         done
9657
9658         echo "slab objects before: $before, after: $after"
9659 }
9660 run_test 76b "confirm clients recycle directory inodes properly ===="
9661
9662 export ORIG_CSUM=""
9663 set_checksums()
9664 {
9665         # Note: in sptlrpc modes which enable its own bulk checksum, the
9666         # original crc32_le bulk checksum will be automatically disabled,
9667         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9668         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9669         # In this case set_checksums() will not be no-op, because sptlrpc
9670         # bulk checksum will be enabled all through the test.
9671
9672         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9673         lctl set_param -n osc.*.checksums $1
9674         return 0
9675 }
9676
9677 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9678                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9679 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9680                              tr -d [] | head -n1)}
9681 set_checksum_type()
9682 {
9683         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9684         rc=$?
9685         log "set checksum type to $1, rc = $rc"
9686         return $rc
9687 }
9688
9689 get_osc_checksum_type()
9690 {
9691         # arugment 1: OST name, like OST0000
9692         ost=$1
9693         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9694                         sed 's/.*\[\(.*\)\].*/\1/g')
9695         rc=$?
9696         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9697         echo $checksum_type
9698 }
9699
9700 F77_TMP=$TMP/f77-temp
9701 F77SZ=8
9702 setup_f77() {
9703         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9704                 error "error writing to $F77_TMP"
9705 }
9706
9707 test_77a() { # bug 10889
9708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9709         $GSS && skip_env "could not run with gss"
9710
9711         [ ! -f $F77_TMP ] && setup_f77
9712         set_checksums 1
9713         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9714         set_checksums 0
9715         rm -f $DIR/$tfile
9716 }
9717 run_test 77a "normal checksum read/write operation"
9718
9719 test_77b() { # bug 10889
9720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9721         $GSS && skip_env "could not run with gss"
9722
9723         [ ! -f $F77_TMP ] && setup_f77
9724         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9725         $LCTL set_param fail_loc=0x80000409
9726         set_checksums 1
9727
9728         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9729                 error "dd error: $?"
9730         $LCTL set_param fail_loc=0
9731
9732         for algo in $CKSUM_TYPES; do
9733                 cancel_lru_locks osc
9734                 set_checksum_type $algo
9735                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9736                 $LCTL set_param fail_loc=0x80000408
9737                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9738                 $LCTL set_param fail_loc=0
9739         done
9740         set_checksums 0
9741         set_checksum_type $ORIG_CSUM_TYPE
9742         rm -f $DIR/$tfile
9743 }
9744 run_test 77b "checksum error on client write, read"
9745
9746 cleanup_77c() {
9747         trap 0
9748         set_checksums 0
9749         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9750         $check_ost &&
9751                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9752         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9753         $check_ost && [ -n "$ost_file_prefix" ] &&
9754                 do_facet ost1 rm -f ${ost_file_prefix}\*
9755 }
9756
9757 test_77c() {
9758         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9759         $GSS && skip_env "could not run with gss"
9760         remote_ost_nodsh && skip "remote OST with nodsh"
9761
9762         local bad1
9763         local osc_file_prefix
9764         local osc_file
9765         local check_ost=false
9766         local ost_file_prefix
9767         local ost_file
9768         local orig_cksum
9769         local dump_cksum
9770         local fid
9771
9772         # ensure corruption will occur on first OSS/OST
9773         $LFS setstripe -i 0 $DIR/$tfile
9774
9775         [ ! -f $F77_TMP ] && setup_f77
9776         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9777                 error "dd write error: $?"
9778         fid=$($LFS path2fid $DIR/$tfile)
9779
9780         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9781         then
9782                 check_ost=true
9783                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9784                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9785         else
9786                 echo "OSS do not support bulk pages dump upon error"
9787         fi
9788
9789         osc_file_prefix=$($LCTL get_param -n debug_path)
9790         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9791
9792         trap cleanup_77c EXIT
9793
9794         set_checksums 1
9795         # enable bulk pages dump upon error on Client
9796         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9797         # enable bulk pages dump upon error on OSS
9798         $check_ost &&
9799                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9800
9801         # flush Client cache to allow next read to reach OSS
9802         cancel_lru_locks osc
9803
9804         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9805         $LCTL set_param fail_loc=0x80000408
9806         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9807         $LCTL set_param fail_loc=0
9808
9809         rm -f $DIR/$tfile
9810
9811         # check cksum dump on Client
9812         osc_file=$(ls ${osc_file_prefix}*)
9813         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9814         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9815         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9816         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9817         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9818                      cksum)
9819         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9820         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9821                 error "dump content does not match on Client"
9822
9823         $check_ost || skip "No need to check cksum dump on OSS"
9824
9825         # check cksum dump on OSS
9826         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9827         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9828         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9829         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9830         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9831                 error "dump content does not match on OSS"
9832
9833         cleanup_77c
9834 }
9835 run_test 77c "checksum error on client read with debug"
9836
9837 test_77d() { # bug 10889
9838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9839         $GSS && skip_env "could not run with gss"
9840
9841         stack_trap "rm -f $DIR/$tfile"
9842         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9843         $LCTL set_param fail_loc=0x80000409
9844         set_checksums 1
9845         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9846                 error "direct write: rc=$?"
9847         $LCTL set_param fail_loc=0
9848         set_checksums 0
9849
9850         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9851         $LCTL set_param fail_loc=0x80000408
9852         set_checksums 1
9853         cancel_lru_locks osc
9854         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9855                 error "direct read: rc=$?"
9856         $LCTL set_param fail_loc=0
9857         set_checksums 0
9858 }
9859 run_test 77d "checksum error on OST direct write, read"
9860
9861 test_77f() { # bug 10889
9862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9863         $GSS && skip_env "could not run with gss"
9864
9865         set_checksums 1
9866         stack_trap "rm -f $DIR/$tfile"
9867         for algo in $CKSUM_TYPES; do
9868                 cancel_lru_locks osc
9869                 set_checksum_type $algo
9870                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9871                 $LCTL set_param fail_loc=0x409
9872                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9873                         error "direct write succeeded"
9874                 $LCTL set_param fail_loc=0
9875         done
9876         set_checksum_type $ORIG_CSUM_TYPE
9877         set_checksums 0
9878 }
9879 run_test 77f "repeat checksum error on write (expect error)"
9880
9881 test_77g() { # bug 10889
9882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9883         $GSS && skip_env "could not run with gss"
9884         remote_ost_nodsh && skip "remote OST with nodsh"
9885
9886         [ ! -f $F77_TMP ] && setup_f77
9887
9888         local file=$DIR/$tfile
9889         stack_trap "rm -f $file" EXIT
9890
9891         $LFS setstripe -c 1 -i 0 $file
9892         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9893         do_facet ost1 lctl set_param fail_loc=0x8000021a
9894         set_checksums 1
9895         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9896                 error "write error: rc=$?"
9897         do_facet ost1 lctl set_param fail_loc=0
9898         set_checksums 0
9899
9900         cancel_lru_locks osc
9901         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9902         do_facet ost1 lctl set_param fail_loc=0x8000021b
9903         set_checksums 1
9904         cmp $F77_TMP $file || error "file compare failed"
9905         do_facet ost1 lctl set_param fail_loc=0
9906         set_checksums 0
9907 }
9908 run_test 77g "checksum error on OST write, read"
9909
9910 test_77k() { # LU-10906
9911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9912         $GSS && skip_env "could not run with gss"
9913
9914         local cksum_param="osc.$FSNAME*.checksums"
9915         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9916         local checksum
9917         local i
9918
9919         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9920         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9921         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9922
9923         for i in 0 1; do
9924                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9925                         error "failed to set checksum=$i on MGS"
9926                 wait_update $HOSTNAME "$get_checksum" $i
9927                 #remount
9928                 echo "remount client, checksum should be $i"
9929                 remount_client $MOUNT || error "failed to remount client"
9930                 checksum=$(eval $get_checksum)
9931                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9932         done
9933         # remove persistent param to avoid races with checksum mountopt below
9934         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9935                 error "failed to delete checksum on MGS"
9936
9937         for opt in "checksum" "nochecksum"; do
9938                 #remount with mount option
9939                 echo "remount client with option $opt, checksum should be $i"
9940                 umount_client $MOUNT || error "failed to umount client"
9941                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9942                         error "failed to mount client with option '$opt'"
9943                 checksum=$(eval $get_checksum)
9944                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9945                 i=$((i - 1))
9946         done
9947
9948         remount_client $MOUNT || error "failed to remount client"
9949 }
9950 run_test 77k "enable/disable checksum correctly"
9951
9952 test_77l() {
9953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9954         $GSS && skip_env "could not run with gss"
9955
9956         set_checksums 1
9957         stack_trap "set_checksums $ORIG_CSUM" EXIT
9958         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9959
9960         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9961
9962         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9963         for algo in $CKSUM_TYPES; do
9964                 set_checksum_type $algo || error "fail to set checksum type $algo"
9965                 osc_algo=$(get_osc_checksum_type OST0000)
9966                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9967
9968                 # no locks, no reqs to let the connection idle
9969                 cancel_lru_locks osc
9970                 lru_resize_disable osc
9971                 wait_osc_import_state client ost1 IDLE
9972
9973                 # ensure ost1 is connected
9974                 stat $DIR/$tfile >/dev/null || error "can't stat"
9975                 wait_osc_import_state client ost1 FULL
9976
9977                 osc_algo=$(get_osc_checksum_type OST0000)
9978                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9979         done
9980         return 0
9981 }
9982 run_test 77l "preferred checksum type is remembered after reconnected"
9983
9984 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9985 rm -f $F77_TMP
9986 unset F77_TMP
9987
9988 test_77m() {
9989         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
9990                 skip "Need at least version 2.14.52"
9991         local param=checksum_speed
9992
9993         $LCTL get_param $param || error "reading $param failed"
9994
9995         csum_speeds=$($LCTL get_param -n $param)
9996
9997         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
9998                 error "known checksum types are missing"
9999 }
10000 run_test 77m "Verify checksum_speed is correctly read"
10001
10002 check_filefrag_77n() {
10003         local nr_ext=0
10004         local starts=()
10005         local ends=()
10006
10007         while read extidx a b start end rest; do
10008                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10009                         nr_ext=$(( $nr_ext + 1 ))
10010                         starts+=( ${start%..} )
10011                         ends+=( ${end%:} )
10012                 fi
10013         done < <( filefrag -sv $1 )
10014
10015         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10016         return 1
10017 }
10018
10019 test_77n() {
10020         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10021
10022         touch $DIR/$tfile
10023         $TRUNCATE $DIR/$tfile 0
10024         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10025         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10026         check_filefrag_77n $DIR/$tfile ||
10027                 skip "$tfile blocks not contiguous around hole"
10028
10029         set_checksums 1
10030         stack_trap "set_checksums $ORIG_CSUM" EXIT
10031         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10032         stack_trap "rm -f $DIR/$tfile"
10033
10034         for algo in $CKSUM_TYPES; do
10035                 if [[ "$algo" =~ ^t10 ]]; then
10036                         set_checksum_type $algo ||
10037                                 error "fail to set checksum type $algo"
10038                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10039                                 error "fail to read $tfile with $algo"
10040                 fi
10041         done
10042         rm -f $DIR/$tfile
10043         return 0
10044 }
10045 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10046
10047 test_77o() {
10048         (( $CLIENT_VERSION >= $(version_code 2.14.54) )) ||
10049                 skip "Need at least version 2.14.54"
10050         local ofd=obdfilter
10051         local mdt=mdt
10052
10053         # print OST checksum_type
10054         echo "$ofd.$FSNAME-*.checksum_type:"
10055         do_nodes $(comma_list $(osts_nodes)) \
10056                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10057
10058         # print MDT checksum_type
10059         echo "$mdt.$FSNAME-*.checksum_type:"
10060         do_nodes $(comma_list $(mdts_nodes)) \
10061                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10062
10063         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10064                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10065
10066         (( $o_count == $OSTCOUNT )) ||
10067                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10068
10069         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10070                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10071
10072         (( $m_count == $MDSCOUNT )) ||
10073                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10074 }
10075 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10076
10077 cleanup_test_78() {
10078         trap 0
10079         rm -f $DIR/$tfile
10080 }
10081
10082 test_78() { # bug 10901
10083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10084         remote_ost || skip_env "local OST"
10085
10086         NSEQ=5
10087         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10088         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10089         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10090         echo "MemTotal: $MEMTOTAL"
10091
10092         # reserve 256MB of memory for the kernel and other running processes,
10093         # and then take 1/2 of the remaining memory for the read/write buffers.
10094         if [ $MEMTOTAL -gt 512 ] ;then
10095                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10096         else
10097                 # for those poor memory-starved high-end clusters...
10098                 MEMTOTAL=$((MEMTOTAL / 2))
10099         fi
10100         echo "Mem to use for directio: $MEMTOTAL"
10101
10102         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10103         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10104         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10105         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10106                 head -n1)
10107         echo "Smallest OST: $SMALLESTOST"
10108         [[ $SMALLESTOST -lt 10240 ]] &&
10109                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10110
10111         trap cleanup_test_78 EXIT
10112
10113         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10114                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10115
10116         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10117         echo "File size: $F78SIZE"
10118         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10119         for i in $(seq 1 $NSEQ); do
10120                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10121                 echo directIO rdwr round $i of $NSEQ
10122                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10123         done
10124
10125         cleanup_test_78
10126 }
10127 run_test 78 "handle large O_DIRECT writes correctly ============"
10128
10129 test_79() { # bug 12743
10130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10131
10132         wait_delete_completed
10133
10134         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10135         BKFREE=$(calc_osc_kbytes kbytesfree)
10136         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10137
10138         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10139         DFTOTAL=`echo $STRING | cut -d, -f1`
10140         DFUSED=`echo $STRING  | cut -d, -f2`
10141         DFAVAIL=`echo $STRING | cut -d, -f3`
10142         DFFREE=$(($DFTOTAL - $DFUSED))
10143
10144         ALLOWANCE=$((64 * $OSTCOUNT))
10145
10146         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10147            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10148                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10149         fi
10150         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10151            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10152                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10153         fi
10154         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10155            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10156                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10157         fi
10158 }
10159 run_test 79 "df report consistency check ======================="
10160
10161 test_80() { # bug 10718
10162         remote_ost_nodsh && skip "remote OST with nodsh"
10163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10164
10165         # relax strong synchronous semantics for slow backends like ZFS
10166         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10167                 local soc="obdfilter.*.sync_lock_cancel"
10168                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10169
10170                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10171                 if [ -z "$save" ]; then
10172                         soc="obdfilter.*.sync_on_lock_cancel"
10173                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10174                 fi
10175
10176                 if [ "$save" != "never" ]; then
10177                         local hosts=$(comma_list $(osts_nodes))
10178
10179                         do_nodes $hosts $LCTL set_param $soc=never
10180                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10181                 fi
10182         fi
10183
10184         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10185         sync; sleep 1; sync
10186         local before=$(date +%s)
10187         cancel_lru_locks osc
10188         local after=$(date +%s)
10189         local diff=$((after - before))
10190         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10191
10192         rm -f $DIR/$tfile
10193 }
10194 run_test 80 "Page eviction is equally fast at high offsets too"
10195
10196 test_81a() { # LU-456
10197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10198         remote_ost_nodsh && skip "remote OST with nodsh"
10199
10200         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10201         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10202         do_facet ost1 lctl set_param fail_loc=0x80000228
10203
10204         # write should trigger a retry and success
10205         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10206         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10207         RC=$?
10208         if [ $RC -ne 0 ] ; then
10209                 error "write should success, but failed for $RC"
10210         fi
10211 }
10212 run_test 81a "OST should retry write when get -ENOSPC ==============="
10213
10214 test_81b() { # LU-456
10215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10216         remote_ost_nodsh && skip "remote OST with nodsh"
10217
10218         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10219         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10220         do_facet ost1 lctl set_param fail_loc=0x228
10221
10222         # write should retry several times and return -ENOSPC finally
10223         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10224         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10225         RC=$?
10226         ENOSPC=28
10227         if [ $RC -ne $ENOSPC ] ; then
10228                 error "dd should fail for -ENOSPC, but succeed."
10229         fi
10230 }
10231 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10232
10233 test_99() {
10234         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10235
10236         test_mkdir $DIR/$tdir.cvsroot
10237         chown $RUNAS_ID $DIR/$tdir.cvsroot
10238
10239         cd $TMP
10240         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10241
10242         cd /etc/init.d
10243         # some versions of cvs import exit(1) when asked to import links or
10244         # files they can't read.  ignore those files.
10245         local toignore=$(find . -type l -printf '-I %f\n' -o \
10246                          ! -perm /4 -printf '-I %f\n')
10247         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10248                 $tdir.reposname vtag rtag
10249
10250         cd $DIR
10251         test_mkdir $DIR/$tdir.reposname
10252         chown $RUNAS_ID $DIR/$tdir.reposname
10253         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10254
10255         cd $DIR/$tdir.reposname
10256         $RUNAS touch foo99
10257         $RUNAS cvs add -m 'addmsg' foo99
10258         $RUNAS cvs update
10259         $RUNAS cvs commit -m 'nomsg' foo99
10260         rm -fr $DIR/$tdir.cvsroot
10261 }
10262 run_test 99 "cvs strange file/directory operations"
10263
10264 test_100() {
10265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10266         [[ "$NETTYPE" =~ tcp ]] ||
10267                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10268         remote_ost_nodsh && skip "remote OST with nodsh"
10269         remote_mds_nodsh && skip "remote MDS with nodsh"
10270         remote_servers ||
10271                 skip "useless for local single node setup"
10272
10273         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10274                 [ "$PROT" != "tcp" ] && continue
10275                 RPORT=$(echo $REMOTE | cut -d: -f2)
10276                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10277
10278                 rc=0
10279                 LPORT=`echo $LOCAL | cut -d: -f2`
10280                 if [ $LPORT -ge 1024 ]; then
10281                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10282                         netstat -tna
10283                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10284                 fi
10285         done
10286         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10287 }
10288 run_test 100 "check local port using privileged port ==========="
10289
10290 function get_named_value()
10291 {
10292     local tag=$1
10293
10294     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10295 }
10296
10297 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10298                    awk '/^max_cached_mb/ { print $2 }')
10299
10300 cleanup_101a() {
10301         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10302         trap 0
10303 }
10304
10305 test_101a() {
10306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10307
10308         local s
10309         local discard
10310         local nreads=10000
10311         local cache_limit=32
10312
10313         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10314         trap cleanup_101a EXIT
10315         $LCTL set_param -n llite.*.read_ahead_stats=0
10316         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10317
10318         #
10319         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10320         #
10321         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10322         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10323
10324         discard=0
10325         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10326                    get_named_value 'read.but.discarded'); do
10327                         discard=$(($discard + $s))
10328         done
10329         cleanup_101a
10330
10331         $LCTL get_param osc.*-osc*.rpc_stats
10332         $LCTL get_param llite.*.read_ahead_stats
10333
10334         # Discard is generally zero, but sometimes a few random reads line up
10335         # and trigger larger readahead, which is wasted & leads to discards.
10336         if [[ $(($discard)) -gt $nreads ]]; then
10337                 error "too many ($discard) discarded pages"
10338         fi
10339         rm -f $DIR/$tfile || true
10340 }
10341 run_test 101a "check read-ahead for random reads"
10342
10343 setup_test101bc() {
10344         test_mkdir $DIR/$tdir
10345         local ssize=$1
10346         local FILE_LENGTH=$2
10347         STRIPE_OFFSET=0
10348
10349         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10350
10351         local list=$(comma_list $(osts_nodes))
10352         set_osd_param $list '' read_cache_enable 0
10353         set_osd_param $list '' writethrough_cache_enable 0
10354
10355         trap cleanup_test101bc EXIT
10356         # prepare the read-ahead file
10357         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10358
10359         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10360                                 count=$FILE_SIZE_MB 2> /dev/null
10361
10362 }
10363
10364 cleanup_test101bc() {
10365         trap 0
10366         rm -rf $DIR/$tdir
10367         rm -f $DIR/$tfile
10368
10369         local list=$(comma_list $(osts_nodes))
10370         set_osd_param $list '' read_cache_enable 1
10371         set_osd_param $list '' writethrough_cache_enable 1
10372 }
10373
10374 calc_total() {
10375         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10376 }
10377
10378 ra_check_101() {
10379         local READ_SIZE=$1
10380         local STRIPE_SIZE=$2
10381         local FILE_LENGTH=$3
10382         local RA_INC=1048576
10383         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
10384         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
10385                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
10386         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
10387                   get_named_value 'read.but.discarded' | calc_total)
10388         if [[ $DISCARD -gt $discard_limit ]]; then
10389                 $LCTL get_param llite.*.read_ahead_stats
10390                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
10391         else
10392                 echo "Read-ahead success for size ${READ_SIZE}"
10393         fi
10394 }
10395
10396 test_101b() {
10397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10398         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10399
10400         local STRIPE_SIZE=1048576
10401         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10402
10403         if [ $SLOW == "yes" ]; then
10404                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10405         else
10406                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10407         fi
10408
10409         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10410
10411         # prepare the read-ahead file
10412         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10413         cancel_lru_locks osc
10414         for BIDX in 2 4 8 16 32 64 128 256
10415         do
10416                 local BSIZE=$((BIDX*4096))
10417                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10418                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10419                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10420                 $LCTL set_param -n llite.*.read_ahead_stats=0
10421                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10422                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10423                 cancel_lru_locks osc
10424                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10425         done
10426         cleanup_test101bc
10427         true
10428 }
10429 run_test 101b "check stride-io mode read-ahead ================="
10430
10431 test_101c() {
10432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10433
10434         local STRIPE_SIZE=1048576
10435         local FILE_LENGTH=$((STRIPE_SIZE*100))
10436         local nreads=10000
10437         local rsize=65536
10438         local osc_rpc_stats
10439
10440         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10441
10442         cancel_lru_locks osc
10443         $LCTL set_param osc.*.rpc_stats=0
10444         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10445         $LCTL get_param osc.*.rpc_stats
10446         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10447                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10448                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10449                 local size
10450
10451                 if [ $lines -le 20 ]; then
10452                         echo "continue debug"
10453                         continue
10454                 fi
10455                 for size in 1 2 4 8; do
10456                         local rpc=$(echo "$stats" |
10457                                     awk '($1 == "'$size':") {print $2; exit; }')
10458                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10459                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10460                 done
10461                 echo "$osc_rpc_stats check passed!"
10462         done
10463         cleanup_test101bc
10464         true
10465 }
10466 run_test 101c "check stripe_size aligned read-ahead"
10467
10468 test_101d() {
10469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10470
10471         local file=$DIR/$tfile
10472         local sz_MB=${FILESIZE_101d:-80}
10473         local ra_MB=${READAHEAD_MB:-40}
10474
10475         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10476         [ $free_MB -lt $sz_MB ] &&
10477                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10478
10479         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10480         $LFS setstripe -c -1 $file || error "setstripe failed"
10481
10482         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10483         echo Cancel LRU locks on lustre client to flush the client cache
10484         cancel_lru_locks osc
10485
10486         echo Disable read-ahead
10487         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10488         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10489         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10490         $LCTL get_param -n llite.*.max_read_ahead_mb
10491
10492         echo "Reading the test file $file with read-ahead disabled"
10493         local sz_KB=$((sz_MB * 1024 / 4))
10494         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10495         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10496         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10497                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10498
10499         echo "Cancel LRU locks on lustre client to flush the client cache"
10500         cancel_lru_locks osc
10501         echo Enable read-ahead with ${ra_MB}MB
10502         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10503
10504         echo "Reading the test file $file with read-ahead enabled"
10505         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10506                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10507
10508         echo "read-ahead disabled time read $raOFF"
10509         echo "read-ahead enabled time read $raON"
10510
10511         rm -f $file
10512         wait_delete_completed
10513
10514         # use awk for this check instead of bash because it handles decimals
10515         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10516                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10517 }
10518 run_test 101d "file read with and without read-ahead enabled"
10519
10520 test_101e() {
10521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10522
10523         local file=$DIR/$tfile
10524         local size_KB=500  #KB
10525         local count=100
10526         local bsize=1024
10527
10528         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10529         local need_KB=$((count * size_KB))
10530         [[ $free_KB -le $need_KB ]] &&
10531                 skip_env "Need free space $need_KB, have $free_KB"
10532
10533         echo "Creating $count ${size_KB}K test files"
10534         for ((i = 0; i < $count; i++)); do
10535                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10536         done
10537
10538         echo "Cancel LRU locks on lustre client to flush the client cache"
10539         cancel_lru_locks $OSC
10540
10541         echo "Reset readahead stats"
10542         $LCTL set_param -n llite.*.read_ahead_stats=0
10543
10544         for ((i = 0; i < $count; i++)); do
10545                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10546         done
10547
10548         $LCTL get_param llite.*.max_cached_mb
10549         $LCTL get_param llite.*.read_ahead_stats
10550         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10551                      get_named_value 'misses' | calc_total)
10552
10553         for ((i = 0; i < $count; i++)); do
10554                 rm -rf $file.$i 2>/dev/null
10555         done
10556
10557         #10000 means 20% reads are missing in readahead
10558         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10559 }
10560 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10561
10562 test_101f() {
10563         which iozone || skip_env "no iozone installed"
10564
10565         local old_debug=$($LCTL get_param debug)
10566         old_debug=${old_debug#*=}
10567         $LCTL set_param debug="reada mmap"
10568
10569         # create a test file
10570         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10571
10572         echo Cancel LRU locks on lustre client to flush the client cache
10573         cancel_lru_locks osc
10574
10575         echo Reset readahead stats
10576         $LCTL set_param -n llite.*.read_ahead_stats=0
10577
10578         echo mmap read the file with small block size
10579         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10580                 > /dev/null 2>&1
10581
10582         echo checking missing pages
10583         $LCTL get_param llite.*.read_ahead_stats
10584         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10585                         get_named_value 'misses' | calc_total)
10586
10587         $LCTL set_param debug="$old_debug"
10588         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10589         rm -f $DIR/$tfile
10590 }
10591 run_test 101f "check mmap read performance"
10592
10593 test_101g_brw_size_test() {
10594         local mb=$1
10595         local pages=$((mb * 1048576 / PAGE_SIZE))
10596         local file=$DIR/$tfile
10597
10598         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10599                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10600         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10601                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10602                         return 2
10603         done
10604
10605         stack_trap "rm -f $file" EXIT
10606         $LCTL set_param -n osc.*.rpc_stats=0
10607
10608         # 10 RPCs should be enough for the test
10609         local count=10
10610         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10611                 { error "dd write ${mb} MB blocks failed"; return 3; }
10612         cancel_lru_locks osc
10613         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10614                 { error "dd write ${mb} MB blocks failed"; return 4; }
10615
10616         # calculate number of full-sized read and write RPCs
10617         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10618                 sed -n '/pages per rpc/,/^$/p' |
10619                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10620                 END { print reads,writes }'))
10621         # allow one extra full-sized read RPC for async readahead
10622         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10623                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10624         [[ ${rpcs[1]} == $count ]] ||
10625                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10626 }
10627
10628 test_101g() {
10629         remote_ost_nodsh && skip "remote OST with nodsh"
10630
10631         local rpcs
10632         local osts=$(get_facets OST)
10633         local list=$(comma_list $(osts_nodes))
10634         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10635         local brw_size="obdfilter.*.brw_size"
10636
10637         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10638
10639         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10640
10641         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10642                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10643                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10644            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10645                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10646                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10647
10648                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10649                         suffix="M"
10650
10651                 if [[ $orig_mb -lt 16 ]]; then
10652                         save_lustre_params $osts "$brw_size" > $p
10653                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10654                                 error "set 16MB RPC size failed"
10655
10656                         echo "remount client to enable new RPC size"
10657                         remount_client $MOUNT || error "remount_client failed"
10658                 fi
10659
10660                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10661                 # should be able to set brw_size=12, but no rpc_stats for that
10662                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10663         fi
10664
10665         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10666
10667         if [[ $orig_mb -lt 16 ]]; then
10668                 restore_lustre_params < $p
10669                 remount_client $MOUNT || error "remount_client restore failed"
10670         fi
10671
10672         rm -f $p $DIR/$tfile
10673 }
10674 run_test 101g "Big bulk(4/16 MiB) readahead"
10675
10676 test_101h() {
10677         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10678
10679         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10680                 error "dd 70M file failed"
10681         echo Cancel LRU locks on lustre client to flush the client cache
10682         cancel_lru_locks osc
10683
10684         echo "Reset readahead stats"
10685         $LCTL set_param -n llite.*.read_ahead_stats 0
10686
10687         echo "Read 10M of data but cross 64M bundary"
10688         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10689         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10690                      get_named_value 'misses' | calc_total)
10691         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10692         rm -f $p $DIR/$tfile
10693 }
10694 run_test 101h "Readahead should cover current read window"
10695
10696 test_101i() {
10697         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10698                 error "dd 10M file failed"
10699
10700         local max_per_file_mb=$($LCTL get_param -n \
10701                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10702         cancel_lru_locks osc
10703         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10704         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10705                 error "set max_read_ahead_per_file_mb to 1 failed"
10706
10707         echo "Reset readahead stats"
10708         $LCTL set_param llite.*.read_ahead_stats=0
10709
10710         dd if=$DIR/$tfile of=/dev/null bs=2M
10711
10712         $LCTL get_param llite.*.read_ahead_stats
10713         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10714                      awk '/misses/ { print $2 }')
10715         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10716         rm -f $DIR/$tfile
10717 }
10718 run_test 101i "allow current readahead to exceed reservation"
10719
10720 test_101j() {
10721         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10722                 error "setstripe $DIR/$tfile failed"
10723         local file_size=$((1048576 * 16))
10724         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10725         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10726
10727         echo Disable read-ahead
10728         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10729
10730         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10731         for blk in $PAGE_SIZE 1048576 $file_size; do
10732                 cancel_lru_locks osc
10733                 echo "Reset readahead stats"
10734                 $LCTL set_param -n llite.*.read_ahead_stats=0
10735                 local count=$(($file_size / $blk))
10736                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10737                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10738                              get_named_value 'failed.to.fast.read' | calc_total)
10739                 $LCTL get_param -n llite.*.read_ahead_stats
10740                 [ $miss -eq $count ] || error "expected $count got $miss"
10741         done
10742
10743         rm -f $p $DIR/$tfile
10744 }
10745 run_test 101j "A complete read block should be submitted when no RA"
10746
10747 setup_test102() {
10748         test_mkdir $DIR/$tdir
10749         chown $RUNAS_ID $DIR/$tdir
10750         STRIPE_SIZE=65536
10751         STRIPE_OFFSET=1
10752         STRIPE_COUNT=$OSTCOUNT
10753         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10754
10755         trap cleanup_test102 EXIT
10756         cd $DIR
10757         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10758         cd $DIR/$tdir
10759         for num in 1 2 3 4; do
10760                 for count in $(seq 1 $STRIPE_COUNT); do
10761                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10762                                 local size=`expr $STRIPE_SIZE \* $num`
10763                                 local file=file"$num-$idx-$count"
10764                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10765                         done
10766                 done
10767         done
10768
10769         cd $DIR
10770         $1 tar cf $TMP/f102.tar $tdir --xattrs
10771 }
10772
10773 cleanup_test102() {
10774         trap 0
10775         rm -f $TMP/f102.tar
10776         rm -rf $DIR/d0.sanity/d102
10777 }
10778
10779 test_102a() {
10780         [ "$UID" != 0 ] && skip "must run as root"
10781         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10782                 skip_env "must have user_xattr"
10783
10784         [ -z "$(which setfattr 2>/dev/null)" ] &&
10785                 skip_env "could not find setfattr"
10786
10787         local testfile=$DIR/$tfile
10788
10789         touch $testfile
10790         echo "set/get xattr..."
10791         setfattr -n trusted.name1 -v value1 $testfile ||
10792                 error "setfattr -n trusted.name1=value1 $testfile failed"
10793         getfattr -n trusted.name1 $testfile 2> /dev/null |
10794           grep "trusted.name1=.value1" ||
10795                 error "$testfile missing trusted.name1=value1"
10796
10797         setfattr -n user.author1 -v author1 $testfile ||
10798                 error "setfattr -n user.author1=author1 $testfile failed"
10799         getfattr -n user.author1 $testfile 2> /dev/null |
10800           grep "user.author1=.author1" ||
10801                 error "$testfile missing trusted.author1=author1"
10802
10803         echo "listxattr..."
10804         setfattr -n trusted.name2 -v value2 $testfile ||
10805                 error "$testfile unable to set trusted.name2"
10806         setfattr -n trusted.name3 -v value3 $testfile ||
10807                 error "$testfile unable to set trusted.name3"
10808         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10809             grep "trusted.name" | wc -l) -eq 3 ] ||
10810                 error "$testfile missing 3 trusted.name xattrs"
10811
10812         setfattr -n user.author2 -v author2 $testfile ||
10813                 error "$testfile unable to set user.author2"
10814         setfattr -n user.author3 -v author3 $testfile ||
10815                 error "$testfile unable to set user.author3"
10816         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10817             grep "user.author" | wc -l) -eq 3 ] ||
10818                 error "$testfile missing 3 user.author xattrs"
10819
10820         echo "remove xattr..."
10821         setfattr -x trusted.name1 $testfile ||
10822                 error "$testfile error deleting trusted.name1"
10823         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10824                 error "$testfile did not delete trusted.name1 xattr"
10825
10826         setfattr -x user.author1 $testfile ||
10827                 error "$testfile error deleting user.author1"
10828         echo "set lustre special xattr ..."
10829         $LFS setstripe -c1 $testfile
10830         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10831                 awk -F "=" '/trusted.lov/ { print $2 }' )
10832         setfattr -n "trusted.lov" -v $lovea $testfile ||
10833                 error "$testfile doesn't ignore setting trusted.lov again"
10834         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10835                 error "$testfile allow setting invalid trusted.lov"
10836         rm -f $testfile
10837 }
10838 run_test 102a "user xattr test =================================="
10839
10840 check_102b_layout() {
10841         local layout="$*"
10842         local testfile=$DIR/$tfile
10843
10844         echo "test layout '$layout'"
10845         $LFS setstripe $layout $testfile || error "setstripe failed"
10846         $LFS getstripe -y $testfile
10847
10848         echo "get/set/list trusted.lov xattr ..." # b=10930
10849         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10850         [[ "$value" =~ "trusted.lov" ]] ||
10851                 error "can't get trusted.lov from $testfile"
10852         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10853                 error "getstripe failed"
10854
10855         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10856
10857         value=$(cut -d= -f2 <<<$value)
10858         # LU-13168: truncated xattr should fail if short lov_user_md header
10859         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10860                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10861         for len in $lens; do
10862                 echo "setfattr $len $testfile.2"
10863                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10864                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10865         done
10866         local stripe_size=$($LFS getstripe -S $testfile.2)
10867         local stripe_count=$($LFS getstripe -c $testfile.2)
10868         [[ $stripe_size -eq 65536 ]] ||
10869                 error "stripe size $stripe_size != 65536"
10870         [[ $stripe_count -eq $stripe_count_orig ]] ||
10871                 error "stripe count $stripe_count != $stripe_count_orig"
10872         rm $testfile $testfile.2
10873 }
10874
10875 test_102b() {
10876         [ -z "$(which setfattr 2>/dev/null)" ] &&
10877                 skip_env "could not find setfattr"
10878         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10879
10880         # check plain layout
10881         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10882
10883         # and also check composite layout
10884         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10885
10886 }
10887 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10888
10889 test_102c() {
10890         [ -z "$(which setfattr 2>/dev/null)" ] &&
10891                 skip_env "could not find setfattr"
10892         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10893
10894         # b10930: get/set/list lustre.lov xattr
10895         echo "get/set/list lustre.lov xattr ..."
10896         test_mkdir $DIR/$tdir
10897         chown $RUNAS_ID $DIR/$tdir
10898         local testfile=$DIR/$tdir/$tfile
10899         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10900                 error "setstripe failed"
10901         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10902                 error "getstripe failed"
10903         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10904         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10905
10906         local testfile2=${testfile}2
10907         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10908                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10909
10910         $RUNAS $MCREATE $testfile2
10911         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10912         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10913         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10914         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10915         [ $stripe_count -eq $STRIPECOUNT ] ||
10916                 error "stripe count $stripe_count != $STRIPECOUNT"
10917 }
10918 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10919
10920 compare_stripe_info1() {
10921         local stripe_index_all_zero=true
10922
10923         for num in 1 2 3 4; do
10924                 for count in $(seq 1 $STRIPE_COUNT); do
10925                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10926                                 local size=$((STRIPE_SIZE * num))
10927                                 local file=file"$num-$offset-$count"
10928                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10929                                 [[ $stripe_size -ne $size ]] &&
10930                                     error "$file: size $stripe_size != $size"
10931                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10932                                 # allow fewer stripes to be created, ORI-601
10933                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10934                                     error "$file: count $stripe_count != $count"
10935                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10936                                 [[ $stripe_index -ne 0 ]] &&
10937                                         stripe_index_all_zero=false
10938                         done
10939                 done
10940         done
10941         $stripe_index_all_zero &&
10942                 error "all files are being extracted starting from OST index 0"
10943         return 0
10944 }
10945
10946 have_xattrs_include() {
10947         tar --help | grep -q xattrs-include &&
10948                 echo --xattrs-include="lustre.*"
10949 }
10950
10951 test_102d() {
10952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10953         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10954
10955         XINC=$(have_xattrs_include)
10956         setup_test102
10957         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10958         cd $DIR/$tdir/$tdir
10959         compare_stripe_info1
10960 }
10961 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10962
10963 test_102f() {
10964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10965         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10966
10967         XINC=$(have_xattrs_include)
10968         setup_test102
10969         test_mkdir $DIR/$tdir.restore
10970         cd $DIR
10971         tar cf - --xattrs $tdir | tar xf - \
10972                 -C $DIR/$tdir.restore --xattrs $XINC
10973         cd $DIR/$tdir.restore/$tdir
10974         compare_stripe_info1
10975 }
10976 run_test 102f "tar copy files, not keep osts"
10977
10978 grow_xattr() {
10979         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10980                 skip "must have user_xattr"
10981         [ -z "$(which setfattr 2>/dev/null)" ] &&
10982                 skip_env "could not find setfattr"
10983         [ -z "$(which getfattr 2>/dev/null)" ] &&
10984                 skip_env "could not find getfattr"
10985
10986         local xsize=${1:-1024}  # in bytes
10987         local file=$DIR/$tfile
10988         local value="$(generate_string $xsize)"
10989         local xbig=trusted.big
10990         local toobig=$2
10991
10992         touch $file
10993         log "save $xbig on $file"
10994         if [ -z "$toobig" ]
10995         then
10996                 setfattr -n $xbig -v $value $file ||
10997                         error "saving $xbig on $file failed"
10998         else
10999                 setfattr -n $xbig -v $value $file &&
11000                         error "saving $xbig on $file succeeded"
11001                 return 0
11002         fi
11003
11004         local orig=$(get_xattr_value $xbig $file)
11005         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11006
11007         local xsml=trusted.sml
11008         log "save $xsml on $file"
11009         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11010
11011         local new=$(get_xattr_value $xbig $file)
11012         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11013
11014         log "grow $xsml on $file"
11015         setfattr -n $xsml -v "$value" $file ||
11016                 error "growing $xsml on $file failed"
11017
11018         new=$(get_xattr_value $xbig $file)
11019         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11020         log "$xbig still valid after growing $xsml"
11021
11022         rm -f $file
11023 }
11024
11025 test_102h() { # bug 15777
11026         grow_xattr 1024
11027 }
11028 run_test 102h "grow xattr from inside inode to external block"
11029
11030 test_102ha() {
11031         large_xattr_enabled || skip_env "ea_inode feature disabled"
11032
11033         echo "setting xattr of max xattr size: $(max_xattr_size)"
11034         grow_xattr $(max_xattr_size)
11035
11036         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11037         echo "This should fail:"
11038         grow_xattr $(($(max_xattr_size) + 10)) 1
11039 }
11040 run_test 102ha "grow xattr from inside inode to external inode"
11041
11042 test_102i() { # bug 17038
11043         [ -z "$(which getfattr 2>/dev/null)" ] &&
11044                 skip "could not find getfattr"
11045
11046         touch $DIR/$tfile
11047         ln -s $DIR/$tfile $DIR/${tfile}link
11048         getfattr -n trusted.lov $DIR/$tfile ||
11049                 error "lgetxattr on $DIR/$tfile failed"
11050         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11051                 grep -i "no such attr" ||
11052                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11053         rm -f $DIR/$tfile $DIR/${tfile}link
11054 }
11055 run_test 102i "lgetxattr test on symbolic link ============"
11056
11057 test_102j() {
11058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11059         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11060
11061         XINC=$(have_xattrs_include)
11062         setup_test102 "$RUNAS"
11063         chown $RUNAS_ID $DIR/$tdir
11064         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11065         cd $DIR/$tdir/$tdir
11066         compare_stripe_info1 "$RUNAS"
11067 }
11068 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11069
11070 test_102k() {
11071         [ -z "$(which setfattr 2>/dev/null)" ] &&
11072                 skip "could not find setfattr"
11073
11074         touch $DIR/$tfile
11075         # b22187 just check that does not crash for regular file.
11076         setfattr -n trusted.lov $DIR/$tfile
11077         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11078         local test_kdir=$DIR/$tdir
11079         test_mkdir $test_kdir
11080         local default_size=$($LFS getstripe -S $test_kdir)
11081         local default_count=$($LFS getstripe -c $test_kdir)
11082         local default_offset=$($LFS getstripe -i $test_kdir)
11083         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11084                 error 'dir setstripe failed'
11085         setfattr -n trusted.lov $test_kdir
11086         local stripe_size=$($LFS getstripe -S $test_kdir)
11087         local stripe_count=$($LFS getstripe -c $test_kdir)
11088         local stripe_offset=$($LFS getstripe -i $test_kdir)
11089         [ $stripe_size -eq $default_size ] ||
11090                 error "stripe size $stripe_size != $default_size"
11091         [ $stripe_count -eq $default_count ] ||
11092                 error "stripe count $stripe_count != $default_count"
11093         [ $stripe_offset -eq $default_offset ] ||
11094                 error "stripe offset $stripe_offset != $default_offset"
11095         rm -rf $DIR/$tfile $test_kdir
11096 }
11097 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11098
11099 test_102l() {
11100         [ -z "$(which getfattr 2>/dev/null)" ] &&
11101                 skip "could not find getfattr"
11102
11103         # LU-532 trusted. xattr is invisible to non-root
11104         local testfile=$DIR/$tfile
11105
11106         touch $testfile
11107
11108         echo "listxattr as user..."
11109         chown $RUNAS_ID $testfile
11110         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11111             grep -q "trusted" &&
11112                 error "$testfile trusted xattrs are user visible"
11113
11114         return 0;
11115 }
11116 run_test 102l "listxattr size test =================================="
11117
11118 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11119         local path=$DIR/$tfile
11120         touch $path
11121
11122         listxattr_size_check $path || error "listattr_size_check $path failed"
11123 }
11124 run_test 102m "Ensure listxattr fails on small bufffer ========"
11125
11126 cleanup_test102
11127
11128 getxattr() { # getxattr path name
11129         # Return the base64 encoding of the value of xattr name on path.
11130         local path=$1
11131         local name=$2
11132
11133         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11134         # file: $path
11135         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11136         #
11137         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11138
11139         getfattr --absolute-names --encoding=base64 --name=$name $path |
11140                 awk -F= -v name=$name '$1 == name {
11141                         print substr($0, index($0, "=") + 1);
11142         }'
11143 }
11144
11145 test_102n() { # LU-4101 mdt: protect internal xattrs
11146         [ -z "$(which setfattr 2>/dev/null)" ] &&
11147                 skip "could not find setfattr"
11148         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11149         then
11150                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11151         fi
11152
11153         local file0=$DIR/$tfile.0
11154         local file1=$DIR/$tfile.1
11155         local xattr0=$TMP/$tfile.0
11156         local xattr1=$TMP/$tfile.1
11157         local namelist="lov lma lmv link fid version som hsm"
11158         local name
11159         local value
11160
11161         rm -rf $file0 $file1 $xattr0 $xattr1
11162         touch $file0 $file1
11163
11164         # Get 'before' xattrs of $file1.
11165         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11166
11167         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11168                 namelist+=" lfsck_namespace"
11169         for name in $namelist; do
11170                 # Try to copy xattr from $file0 to $file1.
11171                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11172
11173                 setfattr --name=trusted.$name --value="$value" $file1 ||
11174                         error "setxattr 'trusted.$name' failed"
11175
11176                 # Try to set a garbage xattr.
11177                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11178
11179                 if [[ x$name == "xlov" ]]; then
11180                         setfattr --name=trusted.lov --value="$value" $file1 &&
11181                         error "setxattr invalid 'trusted.lov' success"
11182                 else
11183                         setfattr --name=trusted.$name --value="$value" $file1 ||
11184                                 error "setxattr invalid 'trusted.$name' failed"
11185                 fi
11186
11187                 # Try to remove the xattr from $file1. We don't care if this
11188                 # appears to succeed or fail, we just don't want there to be
11189                 # any changes or crashes.
11190                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11191         done
11192
11193         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11194         then
11195                 name="lfsck_ns"
11196                 # Try to copy xattr from $file0 to $file1.
11197                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11198
11199                 setfattr --name=trusted.$name --value="$value" $file1 ||
11200                         error "setxattr 'trusted.$name' failed"
11201
11202                 # Try to set a garbage xattr.
11203                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11204
11205                 setfattr --name=trusted.$name --value="$value" $file1 ||
11206                         error "setxattr 'trusted.$name' failed"
11207
11208                 # Try to remove the xattr from $file1. We don't care if this
11209                 # appears to succeed or fail, we just don't want there to be
11210                 # any changes or crashes.
11211                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11212         fi
11213
11214         # Get 'after' xattrs of file1.
11215         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11216
11217         if ! diff $xattr0 $xattr1; then
11218                 error "before and after xattrs of '$file1' differ"
11219         fi
11220
11221         rm -rf $file0 $file1 $xattr0 $xattr1
11222
11223         return 0
11224 }
11225 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11226
11227 test_102p() { # LU-4703 setxattr did not check ownership
11228         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11229                 skip "MDS needs to be at least 2.5.56"
11230
11231         local testfile=$DIR/$tfile
11232
11233         touch $testfile
11234
11235         echo "setfacl as user..."
11236         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11237         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11238
11239         echo "setfattr as user..."
11240         setfacl -m "u:$RUNAS_ID:---" $testfile
11241         $RUNAS setfattr -x system.posix_acl_access $testfile
11242         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11243 }
11244 run_test 102p "check setxattr(2) correctly fails without permission"
11245
11246 test_102q() {
11247         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11248                 skip "MDS needs to be at least 2.6.92"
11249
11250         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11251 }
11252 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11253
11254 test_102r() {
11255         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11256                 skip "MDS needs to be at least 2.6.93"
11257
11258         touch $DIR/$tfile || error "touch"
11259         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11260         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11261         rm $DIR/$tfile || error "rm"
11262
11263         #normal directory
11264         mkdir -p $DIR/$tdir || error "mkdir"
11265         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11266         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11267         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11268                 error "$testfile error deleting user.author1"
11269         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11270                 grep "user.$(basename $tdir)" &&
11271                 error "$tdir did not delete user.$(basename $tdir)"
11272         rmdir $DIR/$tdir || error "rmdir"
11273
11274         #striped directory
11275         test_mkdir $DIR/$tdir
11276         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11277         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11278         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11279                 error "$testfile error deleting user.author1"
11280         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11281                 grep "user.$(basename $tdir)" &&
11282                 error "$tdir did not delete user.$(basename $tdir)"
11283         rmdir $DIR/$tdir || error "rm striped dir"
11284 }
11285 run_test 102r "set EAs with empty values"
11286
11287 test_102s() {
11288         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11289                 skip "MDS needs to be at least 2.11.52"
11290
11291         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11292
11293         save_lustre_params client "llite.*.xattr_cache" > $save
11294
11295         for cache in 0 1; do
11296                 lctl set_param llite.*.xattr_cache=$cache
11297
11298                 rm -f $DIR/$tfile
11299                 touch $DIR/$tfile || error "touch"
11300                 for prefix in lustre security system trusted user; do
11301                         # Note getxattr() may fail with 'Operation not
11302                         # supported' or 'No such attribute' depending
11303                         # on prefix and cache.
11304                         getfattr -n $prefix.n102s $DIR/$tfile &&
11305                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11306                 done
11307         done
11308
11309         restore_lustre_params < $save
11310 }
11311 run_test 102s "getting nonexistent xattrs should fail"
11312
11313 test_102t() {
11314         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11315                 skip "MDS needs to be at least 2.11.52"
11316
11317         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11318
11319         save_lustre_params client "llite.*.xattr_cache" > $save
11320
11321         for cache in 0 1; do
11322                 lctl set_param llite.*.xattr_cache=$cache
11323
11324                 for buf_size in 0 256; do
11325                         rm -f $DIR/$tfile
11326                         touch $DIR/$tfile || error "touch"
11327                         setfattr -n user.multiop $DIR/$tfile
11328                         $MULTIOP $DIR/$tfile oa$buf_size ||
11329                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11330                 done
11331         done
11332
11333         restore_lustre_params < $save
11334 }
11335 run_test 102t "zero length xattr values handled correctly"
11336
11337 run_acl_subtest()
11338 {
11339     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11340     return $?
11341 }
11342
11343 test_103a() {
11344         [ "$UID" != 0 ] && skip "must run as root"
11345         $GSS && skip_env "could not run under gss"
11346         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11347                 skip_env "must have acl enabled"
11348         [ -z "$(which setfacl 2>/dev/null)" ] &&
11349                 skip_env "could not find setfacl"
11350         remote_mds_nodsh && skip "remote MDS with nodsh"
11351
11352         gpasswd -a daemon bin                           # LU-5641
11353         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11354
11355         declare -a identity_old
11356
11357         for num in $(seq $MDSCOUNT); do
11358                 switch_identity $num true || identity_old[$num]=$?
11359         done
11360
11361         SAVE_UMASK=$(umask)
11362         umask 0022
11363         mkdir -p $DIR/$tdir
11364         cd $DIR/$tdir
11365
11366         echo "performing cp ..."
11367         run_acl_subtest cp || error "run_acl_subtest cp failed"
11368         echo "performing getfacl-noacl..."
11369         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11370         echo "performing misc..."
11371         run_acl_subtest misc || error  "misc test failed"
11372         echo "performing permissions..."
11373         run_acl_subtest permissions || error "permissions failed"
11374         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11375         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11376                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11377                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11378         then
11379                 echo "performing permissions xattr..."
11380                 run_acl_subtest permissions_xattr ||
11381                         error "permissions_xattr failed"
11382         fi
11383         echo "performing setfacl..."
11384         run_acl_subtest setfacl || error  "setfacl test failed"
11385
11386         # inheritance test got from HP
11387         echo "performing inheritance..."
11388         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11389         chmod +x make-tree || error "chmod +x failed"
11390         run_acl_subtest inheritance || error "inheritance test failed"
11391         rm -f make-tree
11392
11393         echo "LU-974 ignore umask when acl is enabled..."
11394         run_acl_subtest 974 || error "LU-974 umask test failed"
11395         if [ $MDSCOUNT -ge 2 ]; then
11396                 run_acl_subtest 974_remote ||
11397                         error "LU-974 umask test failed under remote dir"
11398         fi
11399
11400         echo "LU-2561 newly created file is same size as directory..."
11401         if [ "$mds1_FSTYPE" != "zfs" ]; then
11402                 run_acl_subtest 2561 || error "LU-2561 test failed"
11403         else
11404                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11405         fi
11406
11407         run_acl_subtest 4924 || error "LU-4924 test failed"
11408
11409         cd $SAVE_PWD
11410         umask $SAVE_UMASK
11411
11412         for num in $(seq $MDSCOUNT); do
11413                 if [ "${identity_old[$num]}" = 1 ]; then
11414                         switch_identity $num false || identity_old[$num]=$?
11415                 fi
11416         done
11417 }
11418 run_test 103a "acl test"
11419
11420 test_103b() {
11421         declare -a pids
11422         local U
11423
11424         for U in {0..511}; do
11425                 {
11426                 local O=$(printf "%04o" $U)
11427
11428                 umask $(printf "%04o" $((511 ^ $O)))
11429                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11430                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11431
11432                 (( $S == ($O & 0666) )) ||
11433                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11434
11435                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11436                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11437                 (( $S == ($O & 0666) )) ||
11438                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11439
11440                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11441                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11442                 (( $S == ($O & 0666) )) ||
11443                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11444                 rm -f $DIR/$tfile.[smp]$0
11445                 } &
11446                 local pid=$!
11447
11448                 # limit the concurrently running threads to 64. LU-11878
11449                 local idx=$((U % 64))
11450                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11451                 pids[idx]=$pid
11452         done
11453         wait
11454 }
11455 run_test 103b "umask lfs setstripe"
11456
11457 test_103c() {
11458         mkdir -p $DIR/$tdir
11459         cp -rp $DIR/$tdir $DIR/$tdir.bak
11460
11461         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11462                 error "$DIR/$tdir shouldn't contain default ACL"
11463         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11464                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11465         true
11466 }
11467 run_test 103c "'cp -rp' won't set empty acl"
11468
11469 test_103e() {
11470         local numacl
11471         local fileacl
11472         local saved_debug=$($LCTL get_param -n debug)
11473
11474         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
11475                 skip "MDS needs to be at least 2.14.0"
11476
11477         large_xattr_enabled || skip_env "ea_inode feature disabled"
11478
11479         mkdir -p $DIR/$tdir
11480         # add big LOV EA to cause reply buffer overflow earlier
11481         $LFS setstripe -C 1000 $DIR/$tdir
11482         lctl set_param mdc.*-mdc*.stats=clear
11483
11484         $LCTL set_param debug=0
11485         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11486         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11487
11488         # add a large number of default ACLs (expect 8000+ for 2.13+)
11489         for U in {2..7000}; do
11490                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11491                         error "Able to add just $U default ACLs"
11492         done
11493         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11494         echo "$numacl default ACLs created"
11495
11496         stat $DIR/$tdir || error "Cannot stat directory"
11497         # check file creation
11498         touch $DIR/$tdir/$tfile ||
11499                 error "failed to create $tfile with $numacl default ACLs"
11500         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11501         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11502         echo "$fileacl ACLs were inherited"
11503         (( $fileacl == $numacl )) ||
11504                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11505         # check that new ACLs creation adds new ACLs to inherited ACLs
11506         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11507                 error "Cannot set new ACL"
11508         numacl=$((numacl + 1))
11509         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11510         (( $fileacl == $numacl )) ||
11511                 error "failed to add new ACL: $fileacl != $numacl as expected"
11512         # adds more ACLs to a file to reach their maximum at 8000+
11513         numacl=0
11514         for U in {20000..25000}; do
11515                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11516                 numacl=$((numacl + 1))
11517         done
11518         echo "Added $numacl more ACLs to the file"
11519         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11520         echo "Total $fileacl ACLs in file"
11521         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11522         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11523         rmdir $DIR/$tdir || error "Cannot remove directory"
11524 }
11525 run_test 103e "inheritance of big amount of default ACLs"
11526
11527 test_103f() {
11528         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11529                 skip "MDS needs to be at least 2.14.51"
11530
11531         large_xattr_enabled || skip_env "ea_inode feature disabled"
11532
11533         # enable changelog to consume more internal MDD buffers
11534         changelog_register
11535
11536         mkdir -p $DIR/$tdir
11537         # add big LOV EA
11538         $LFS setstripe -C 1000 $DIR/$tdir
11539         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11540         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11541         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11542         rmdir $DIR/$tdir || error "Cannot remove directory"
11543 }
11544 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11545
11546 test_104a() {
11547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11548
11549         touch $DIR/$tfile
11550         lfs df || error "lfs df failed"
11551         lfs df -ih || error "lfs df -ih failed"
11552         lfs df -h $DIR || error "lfs df -h $DIR failed"
11553         lfs df -i $DIR || error "lfs df -i $DIR failed"
11554         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11555         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11556
11557         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11558         lctl --device %$OSC deactivate
11559         lfs df || error "lfs df with deactivated OSC failed"
11560         lctl --device %$OSC activate
11561         # wait the osc back to normal
11562         wait_osc_import_ready client ost
11563
11564         lfs df || error "lfs df with reactivated OSC failed"
11565         rm -f $DIR/$tfile
11566 }
11567 run_test 104a "lfs df [-ih] [path] test ========================="
11568
11569 test_104b() {
11570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11571         [ $RUNAS_ID -eq $UID ] &&
11572                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11573
11574         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11575                         grep "Permission denied" | wc -l)))
11576         if [ $denied_cnt -ne 0 ]; then
11577                 error "lfs check servers test failed"
11578         fi
11579 }
11580 run_test 104b "$RUNAS lfs check servers test ===================="
11581
11582 #
11583 # Verify $1 is within range of $2.
11584 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11585 # $1 is <= 2% of $2. Else Fail.
11586 #
11587 value_in_range() {
11588         # Strip all units (M, G, T)
11589         actual=$(echo $1 | tr -d A-Z)
11590         expect=$(echo $2 | tr -d A-Z)
11591
11592         expect_lo=$(($expect * 98 / 100)) # 2% below
11593         expect_hi=$(($expect * 102 / 100)) # 2% above
11594
11595         # permit 2% drift above and below
11596         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11597 }
11598
11599 test_104c() {
11600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11601         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11602
11603         local ost_param="osd-zfs.$FSNAME-OST0000."
11604         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11605         local ofacets=$(get_facets OST)
11606         local mfacets=$(get_facets MDS)
11607         local saved_ost_blocks=
11608         local saved_mdt_blocks=
11609
11610         echo "Before recordsize change"
11611         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11612         df=($(df -h | grep "/mnt/lustre"$))
11613
11614         # For checking.
11615         echo "lfs output : ${lfs_df[*]}"
11616         echo "df  output : ${df[*]}"
11617
11618         for facet in ${ofacets//,/ }; do
11619                 if [ -z $saved_ost_blocks ]; then
11620                         saved_ost_blocks=$(do_facet $facet \
11621                                 lctl get_param -n $ost_param.blocksize)
11622                         echo "OST Blocksize: $saved_ost_blocks"
11623                 fi
11624                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11625                 do_facet $facet zfs set recordsize=32768 $ost
11626         done
11627
11628         # BS too small. Sufficient for functional testing.
11629         for facet in ${mfacets//,/ }; do
11630                 if [ -z $saved_mdt_blocks ]; then
11631                         saved_mdt_blocks=$(do_facet $facet \
11632                                 lctl get_param -n $mdt_param.blocksize)
11633                         echo "MDT Blocksize: $saved_mdt_blocks"
11634                 fi
11635                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11636                 do_facet $facet zfs set recordsize=32768 $mdt
11637         done
11638
11639         # Give new values chance to reflect change
11640         sleep 2
11641
11642         echo "After recordsize change"
11643         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11644         df_after=($(df -h | grep "/mnt/lustre"$))
11645
11646         # For checking.
11647         echo "lfs output : ${lfs_df_after[*]}"
11648         echo "df  output : ${df_after[*]}"
11649
11650         # Verify lfs df
11651         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11652                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11653         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11654                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11655         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11656                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11657
11658         # Verify df
11659         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11660                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11661         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11662                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11663         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11664                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11665
11666         # Restore MDT recordize back to original
11667         for facet in ${mfacets//,/ }; do
11668                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11669                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11670         done
11671
11672         # Restore OST recordize back to original
11673         for facet in ${ofacets//,/ }; do
11674                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11675                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11676         done
11677
11678         return 0
11679 }
11680 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11681
11682 test_105a() {
11683         # doesn't work on 2.4 kernels
11684         touch $DIR/$tfile
11685         if $(flock_is_enabled); then
11686                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11687         else
11688                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11689         fi
11690         rm -f $DIR/$tfile
11691 }
11692 run_test 105a "flock when mounted without -o flock test ========"
11693
11694 test_105b() {
11695         touch $DIR/$tfile
11696         if $(flock_is_enabled); then
11697                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11698         else
11699                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11700         fi
11701         rm -f $DIR/$tfile
11702 }
11703 run_test 105b "fcntl when mounted without -o flock test ========"
11704
11705 test_105c() {
11706         touch $DIR/$tfile
11707         if $(flock_is_enabled); then
11708                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11709         else
11710                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11711         fi
11712         rm -f $DIR/$tfile
11713 }
11714 run_test 105c "lockf when mounted without -o flock test"
11715
11716 test_105d() { # bug 15924
11717         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11718
11719         test_mkdir $DIR/$tdir
11720         flock_is_enabled || skip_env "mount w/o flock enabled"
11721         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11722         $LCTL set_param fail_loc=0x80000315
11723         flocks_test 2 $DIR/$tdir
11724 }
11725 run_test 105d "flock race (should not freeze) ========"
11726
11727 test_105e() { # bug 22660 && 22040
11728         flock_is_enabled || skip_env "mount w/o flock enabled"
11729
11730         touch $DIR/$tfile
11731         flocks_test 3 $DIR/$tfile
11732 }
11733 run_test 105e "Two conflicting flocks from same process"
11734
11735 test_106() { #bug 10921
11736         test_mkdir $DIR/$tdir
11737         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11738         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11739 }
11740 run_test 106 "attempt exec of dir followed by chown of that dir"
11741
11742 test_107() {
11743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11744
11745         CDIR=`pwd`
11746         local file=core
11747
11748         cd $DIR
11749         rm -f $file
11750
11751         local save_pattern=$(sysctl -n kernel.core_pattern)
11752         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11753         sysctl -w kernel.core_pattern=$file
11754         sysctl -w kernel.core_uses_pid=0
11755
11756         ulimit -c unlimited
11757         sleep 60 &
11758         SLEEPPID=$!
11759
11760         sleep 1
11761
11762         kill -s 11 $SLEEPPID
11763         wait $SLEEPPID
11764         if [ -e $file ]; then
11765                 size=`stat -c%s $file`
11766                 [ $size -eq 0 ] && error "Fail to create core file $file"
11767         else
11768                 error "Fail to create core file $file"
11769         fi
11770         rm -f $file
11771         sysctl -w kernel.core_pattern=$save_pattern
11772         sysctl -w kernel.core_uses_pid=$save_uses_pid
11773         cd $CDIR
11774 }
11775 run_test 107 "Coredump on SIG"
11776
11777 test_110() {
11778         test_mkdir $DIR/$tdir
11779         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11780         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11781                 error "mkdir with 256 char should fail, but did not"
11782         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11783                 error "create with 255 char failed"
11784         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11785                 error "create with 256 char should fail, but did not"
11786
11787         ls -l $DIR/$tdir
11788         rm -rf $DIR/$tdir
11789 }
11790 run_test 110 "filename length checking"
11791
11792 #
11793 # Purpose: To verify dynamic thread (OSS) creation.
11794 #
11795 test_115() {
11796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11797         remote_ost_nodsh && skip "remote OST with nodsh"
11798
11799         # Lustre does not stop service threads once they are started.
11800         # Reset number of running threads to default.
11801         stopall
11802         setupall
11803
11804         local OSTIO_pre
11805         local save_params="$TMP/sanity-$TESTNAME.parameters"
11806
11807         # Get ll_ost_io count before I/O
11808         OSTIO_pre=$(do_facet ost1 \
11809                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11810         # Exit if lustre is not running (ll_ost_io not running).
11811         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11812
11813         echo "Starting with $OSTIO_pre threads"
11814         local thread_max=$((OSTIO_pre * 2))
11815         local rpc_in_flight=$((thread_max * 2))
11816         # Number of I/O Process proposed to be started.
11817         local nfiles
11818         local facets=$(get_facets OST)
11819
11820         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11821         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11822
11823         # Set in_flight to $rpc_in_flight
11824         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11825                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11826         nfiles=${rpc_in_flight}
11827         # Set ost thread_max to $thread_max
11828         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11829
11830         # 5 Minutes should be sufficient for max number of OSS
11831         # threads(thread_max) to be created.
11832         local timeout=300
11833
11834         # Start I/O.
11835         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11836         test_mkdir $DIR/$tdir
11837         for i in $(seq $nfiles); do
11838                 local file=$DIR/$tdir/${tfile}-$i
11839                 $LFS setstripe -c -1 -i 0 $file
11840                 ($WTL $file $timeout)&
11841         done
11842
11843         # I/O Started - Wait for thread_started to reach thread_max or report
11844         # error if thread_started is more than thread_max.
11845         echo "Waiting for thread_started to reach thread_max"
11846         local thread_started=0
11847         local end_time=$((SECONDS + timeout))
11848
11849         while [ $SECONDS -le $end_time ] ; do
11850                 echo -n "."
11851                 # Get ost i/o thread_started count.
11852                 thread_started=$(do_facet ost1 \
11853                         "$LCTL get_param \
11854                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11855                 # Break out if thread_started is equal/greater than thread_max
11856                 if [[ $thread_started -ge $thread_max ]]; then
11857                         echo ll_ost_io thread_started $thread_started, \
11858                                 equal/greater than thread_max $thread_max
11859                         break
11860                 fi
11861                 sleep 1
11862         done
11863
11864         # Cleanup - We have the numbers, Kill i/o jobs if running.
11865         jobcount=($(jobs -p))
11866         for i in $(seq 0 $((${#jobcount[@]}-1)))
11867         do
11868                 kill -9 ${jobcount[$i]}
11869                 if [ $? -ne 0 ] ; then
11870                         echo Warning: \
11871                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11872                 fi
11873         done
11874
11875         # Cleanup files left by WTL binary.
11876         for i in $(seq $nfiles); do
11877                 local file=$DIR/$tdir/${tfile}-$i
11878                 rm -rf $file
11879                 if [ $? -ne 0 ] ; then
11880                         echo "Warning: Failed to delete file $file"
11881                 fi
11882         done
11883
11884         restore_lustre_params <$save_params
11885         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11886
11887         # Error out if no new thread has started or Thread started is greater
11888         # than thread max.
11889         if [[ $thread_started -le $OSTIO_pre ||
11890                         $thread_started -gt $thread_max ]]; then
11891                 error "ll_ost_io: thread_started $thread_started" \
11892                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11893                       "No new thread started or thread started greater " \
11894                       "than thread_max."
11895         fi
11896 }
11897 run_test 115 "verify dynamic thread creation===================="
11898
11899 free_min_max () {
11900         wait_delete_completed
11901         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11902         echo "OST kbytes available: ${AVAIL[@]}"
11903         MAXV=${AVAIL[0]}
11904         MAXI=0
11905         MINV=${AVAIL[0]}
11906         MINI=0
11907         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11908                 #echo OST $i: ${AVAIL[i]}kb
11909                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11910                         MAXV=${AVAIL[i]}
11911                         MAXI=$i
11912                 fi
11913                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11914                         MINV=${AVAIL[i]}
11915                         MINI=$i
11916                 fi
11917         done
11918         echo "Min free space: OST $MINI: $MINV"
11919         echo "Max free space: OST $MAXI: $MAXV"
11920 }
11921
11922 test_116a() { # was previously test_116()
11923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11924         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11925         remote_mds_nodsh && skip "remote MDS with nodsh"
11926
11927         echo -n "Free space priority "
11928         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11929                 head -n1
11930         declare -a AVAIL
11931         free_min_max
11932
11933         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11934         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11935         stack_trap simple_cleanup_common
11936
11937         # Check if we need to generate uneven OSTs
11938         test_mkdir -p $DIR/$tdir/OST${MINI}
11939         local FILL=$((MINV / 4))
11940         local DIFF=$((MAXV - MINV))
11941         local DIFF2=$((DIFF * 100 / MINV))
11942
11943         local threshold=$(do_facet $SINGLEMDS \
11944                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11945         threshold=${threshold%%%}
11946         echo -n "Check for uneven OSTs: "
11947         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11948
11949         if [[ $DIFF2 -gt $threshold ]]; then
11950                 echo "ok"
11951                 echo "Don't need to fill OST$MINI"
11952         else
11953                 # generate uneven OSTs. Write 2% over the QOS threshold value
11954                 echo "no"
11955                 DIFF=$((threshold - DIFF2 + 2))
11956                 DIFF2=$((MINV * DIFF / 100))
11957                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11958                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11959                         error "setstripe failed"
11960                 DIFF=$((DIFF2 / 2048))
11961                 i=0
11962                 while [ $i -lt $DIFF ]; do
11963                         i=$((i + 1))
11964                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11965                                 bs=2M count=1 2>/dev/null
11966                         echo -n .
11967                 done
11968                 echo .
11969                 sync
11970                 sleep_maxage
11971                 free_min_max
11972         fi
11973
11974         DIFF=$((MAXV - MINV))
11975         DIFF2=$((DIFF * 100 / MINV))
11976         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11977         if [ $DIFF2 -gt $threshold ]; then
11978                 echo "ok"
11979         else
11980                 skip "QOS imbalance criteria not met"
11981         fi
11982
11983         MINI1=$MINI
11984         MINV1=$MINV
11985         MAXI1=$MAXI
11986         MAXV1=$MAXV
11987
11988         # now fill using QOS
11989         $LFS setstripe -c 1 $DIR/$tdir
11990         FILL=$((FILL / 200))
11991         if [ $FILL -gt 600 ]; then
11992                 FILL=600
11993         fi
11994         echo "writing $FILL files to QOS-assigned OSTs"
11995         i=0
11996         while [ $i -lt $FILL ]; do
11997                 i=$((i + 1))
11998                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11999                         count=1 2>/dev/null
12000                 echo -n .
12001         done
12002         echo "wrote $i 200k files"
12003         sync
12004         sleep_maxage
12005
12006         echo "Note: free space may not be updated, so measurements might be off"
12007         free_min_max
12008         DIFF2=$((MAXV - MINV))
12009         echo "free space delta: orig $DIFF final $DIFF2"
12010         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12011         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12012         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12013         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12014         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12015         if [[ $DIFF -gt 0 ]]; then
12016                 FILL=$((DIFF2 * 100 / DIFF - 100))
12017                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12018         fi
12019
12020         # Figure out which files were written where
12021         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12022                awk '/'$MINI1': / {print $2; exit}')
12023         echo $UUID
12024         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12025         echo "$MINC files created on smaller OST $MINI1"
12026         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12027                awk '/'$MAXI1': / {print $2; exit}')
12028         echo $UUID
12029         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12030         echo "$MAXC files created on larger OST $MAXI1"
12031         if [[ $MINC -gt 0 ]]; then
12032                 FILL=$((MAXC * 100 / MINC - 100))
12033                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12034         fi
12035         [[ $MAXC -gt $MINC ]] ||
12036                 error_ignore LU-9 "stripe QOS didn't balance free space"
12037 }
12038 run_test 116a "stripe QOS: free space balance ==================="
12039
12040 test_116b() { # LU-2093
12041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12042         remote_mds_nodsh && skip "remote MDS with nodsh"
12043
12044 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12045         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12046                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12047         [ -z "$old_rr" ] && skip "no QOS"
12048         do_facet $SINGLEMDS lctl set_param \
12049                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12050         mkdir -p $DIR/$tdir
12051         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12052         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12053         do_facet $SINGLEMDS lctl set_param fail_loc=0
12054         rm -rf $DIR/$tdir
12055         do_facet $SINGLEMDS lctl set_param \
12056                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12057 }
12058 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12059
12060 test_117() # bug 10891
12061 {
12062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12063
12064         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12065         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12066         lctl set_param fail_loc=0x21e
12067         > $DIR/$tfile || error "truncate failed"
12068         lctl set_param fail_loc=0
12069         echo "Truncate succeeded."
12070         rm -f $DIR/$tfile
12071 }
12072 run_test 117 "verify osd extend =========="
12073
12074 NO_SLOW_RESENDCOUNT=4
12075 export OLD_RESENDCOUNT=""
12076 set_resend_count () {
12077         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12078         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12079         lctl set_param -n $PROC_RESENDCOUNT $1
12080         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12081 }
12082
12083 # for reduce test_118* time (b=14842)
12084 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12085
12086 # Reset async IO behavior after error case
12087 reset_async() {
12088         FILE=$DIR/reset_async
12089
12090         # Ensure all OSCs are cleared
12091         $LFS setstripe -c -1 $FILE
12092         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12093         sync
12094         rm $FILE
12095 }
12096
12097 test_118a() #bug 11710
12098 {
12099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12100
12101         reset_async
12102
12103         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12104         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12105         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12106
12107         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12108                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12109                 return 1;
12110         fi
12111         rm -f $DIR/$tfile
12112 }
12113 run_test 118a "verify O_SYNC works =========="
12114
12115 test_118b()
12116 {
12117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12118         remote_ost_nodsh && skip "remote OST with nodsh"
12119
12120         reset_async
12121
12122         #define OBD_FAIL_SRV_ENOENT 0x217
12123         set_nodes_failloc "$(osts_nodes)" 0x217
12124         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12125         RC=$?
12126         set_nodes_failloc "$(osts_nodes)" 0
12127         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12128         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12129                     grep -c writeback)
12130
12131         if [[ $RC -eq 0 ]]; then
12132                 error "Must return error due to dropped pages, rc=$RC"
12133                 return 1;
12134         fi
12135
12136         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12137                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12138                 return 1;
12139         fi
12140
12141         echo "Dirty pages not leaked on ENOENT"
12142
12143         # Due to the above error the OSC will issue all RPCs syncronously
12144         # until a subsequent RPC completes successfully without error.
12145         $MULTIOP $DIR/$tfile Ow4096yc
12146         rm -f $DIR/$tfile
12147
12148         return 0
12149 }
12150 run_test 118b "Reclaim dirty pages on fatal error =========="
12151
12152 test_118c()
12153 {
12154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12155
12156         # for 118c, restore the original resend count, LU-1940
12157         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12158                                 set_resend_count $OLD_RESENDCOUNT
12159         remote_ost_nodsh && skip "remote OST with nodsh"
12160
12161         reset_async
12162
12163         #define OBD_FAIL_OST_EROFS               0x216
12164         set_nodes_failloc "$(osts_nodes)" 0x216
12165
12166         # multiop should block due to fsync until pages are written
12167         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12168         MULTIPID=$!
12169         sleep 1
12170
12171         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12172                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12173         fi
12174
12175         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12176                     grep -c writeback)
12177         if [[ $WRITEBACK -eq 0 ]]; then
12178                 error "No page in writeback, writeback=$WRITEBACK"
12179         fi
12180
12181         set_nodes_failloc "$(osts_nodes)" 0
12182         wait $MULTIPID
12183         RC=$?
12184         if [[ $RC -ne 0 ]]; then
12185                 error "Multiop fsync failed, rc=$RC"
12186         fi
12187
12188         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12189         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12190                     grep -c writeback)
12191         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12192                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12193         fi
12194
12195         rm -f $DIR/$tfile
12196         echo "Dirty pages flushed via fsync on EROFS"
12197         return 0
12198 }
12199 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12200
12201 # continue to use small resend count to reduce test_118* time (b=14842)
12202 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12203
12204 test_118d()
12205 {
12206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12207         remote_ost_nodsh && skip "remote OST with nodsh"
12208
12209         reset_async
12210
12211         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12212         set_nodes_failloc "$(osts_nodes)" 0x214
12213         # multiop should block due to fsync until pages are written
12214         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12215         MULTIPID=$!
12216         sleep 1
12217
12218         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12219                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12220         fi
12221
12222         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12223                     grep -c writeback)
12224         if [[ $WRITEBACK -eq 0 ]]; then
12225                 error "No page in writeback, writeback=$WRITEBACK"
12226         fi
12227
12228         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12229         set_nodes_failloc "$(osts_nodes)" 0
12230
12231         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12232         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12233                     grep -c writeback)
12234         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12235                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12236         fi
12237
12238         rm -f $DIR/$tfile
12239         echo "Dirty pages gaurenteed flushed via fsync"
12240         return 0
12241 }
12242 run_test 118d "Fsync validation inject a delay of the bulk =========="
12243
12244 test_118f() {
12245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12246
12247         reset_async
12248
12249         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12250         lctl set_param fail_loc=0x8000040a
12251
12252         # Should simulate EINVAL error which is fatal
12253         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12254         RC=$?
12255         if [[ $RC -eq 0 ]]; then
12256                 error "Must return error due to dropped pages, rc=$RC"
12257         fi
12258
12259         lctl set_param fail_loc=0x0
12260
12261         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12262         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12263         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12264                     grep -c writeback)
12265         if [[ $LOCKED -ne 0 ]]; then
12266                 error "Locked pages remain in cache, locked=$LOCKED"
12267         fi
12268
12269         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12270                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12271         fi
12272
12273         rm -f $DIR/$tfile
12274         echo "No pages locked after fsync"
12275
12276         reset_async
12277         return 0
12278 }
12279 run_test 118f "Simulate unrecoverable OSC side error =========="
12280
12281 test_118g() {
12282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12283
12284         reset_async
12285
12286         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12287         lctl set_param fail_loc=0x406
12288
12289         # simulate local -ENOMEM
12290         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12291         RC=$?
12292
12293         lctl set_param fail_loc=0
12294         if [[ $RC -eq 0 ]]; then
12295                 error "Must return error due to dropped pages, rc=$RC"
12296         fi
12297
12298         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12299         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12300         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12301                         grep -c writeback)
12302         if [[ $LOCKED -ne 0 ]]; then
12303                 error "Locked pages remain in cache, locked=$LOCKED"
12304         fi
12305
12306         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12307                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12308         fi
12309
12310         rm -f $DIR/$tfile
12311         echo "No pages locked after fsync"
12312
12313         reset_async
12314         return 0
12315 }
12316 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12317
12318 test_118h() {
12319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12320         remote_ost_nodsh && skip "remote OST with nodsh"
12321
12322         reset_async
12323
12324         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12325         set_nodes_failloc "$(osts_nodes)" 0x20e
12326         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12327         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12328         RC=$?
12329
12330         set_nodes_failloc "$(osts_nodes)" 0
12331         if [[ $RC -eq 0 ]]; then
12332                 error "Must return error due to dropped pages, rc=$RC"
12333         fi
12334
12335         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12336         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12337         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12338                     grep -c writeback)
12339         if [[ $LOCKED -ne 0 ]]; then
12340                 error "Locked pages remain in cache, locked=$LOCKED"
12341         fi
12342
12343         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12344                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12345         fi
12346
12347         rm -f $DIR/$tfile
12348         echo "No pages locked after fsync"
12349
12350         return 0
12351 }
12352 run_test 118h "Verify timeout in handling recoverables errors  =========="
12353
12354 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12355
12356 test_118i() {
12357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12358         remote_ost_nodsh && skip "remote OST with nodsh"
12359
12360         reset_async
12361
12362         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12363         set_nodes_failloc "$(osts_nodes)" 0x20e
12364
12365         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12366         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12367         PID=$!
12368         sleep 5
12369         set_nodes_failloc "$(osts_nodes)" 0
12370
12371         wait $PID
12372         RC=$?
12373         if [[ $RC -ne 0 ]]; then
12374                 error "got error, but should be not, rc=$RC"
12375         fi
12376
12377         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12378         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12379         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12380         if [[ $LOCKED -ne 0 ]]; then
12381                 error "Locked pages remain in cache, locked=$LOCKED"
12382         fi
12383
12384         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12385                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12386         fi
12387
12388         rm -f $DIR/$tfile
12389         echo "No pages locked after fsync"
12390
12391         return 0
12392 }
12393 run_test 118i "Fix error before timeout in recoverable error  =========="
12394
12395 [ "$SLOW" = "no" ] && set_resend_count 4
12396
12397 test_118j() {
12398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12399         remote_ost_nodsh && skip "remote OST with nodsh"
12400
12401         reset_async
12402
12403         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12404         set_nodes_failloc "$(osts_nodes)" 0x220
12405
12406         # return -EIO from OST
12407         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12408         RC=$?
12409         set_nodes_failloc "$(osts_nodes)" 0x0
12410         if [[ $RC -eq 0 ]]; then
12411                 error "Must return error due to dropped pages, rc=$RC"
12412         fi
12413
12414         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12415         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12416         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12417         if [[ $LOCKED -ne 0 ]]; then
12418                 error "Locked pages remain in cache, locked=$LOCKED"
12419         fi
12420
12421         # in recoverable error on OST we want resend and stay until it finished
12422         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12423                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12424         fi
12425
12426         rm -f $DIR/$tfile
12427         echo "No pages locked after fsync"
12428
12429         return 0
12430 }
12431 run_test 118j "Simulate unrecoverable OST side error =========="
12432
12433 test_118k()
12434 {
12435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12436         remote_ost_nodsh && skip "remote OSTs with nodsh"
12437
12438         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12439         set_nodes_failloc "$(osts_nodes)" 0x20e
12440         test_mkdir $DIR/$tdir
12441
12442         for ((i=0;i<10;i++)); do
12443                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12444                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12445                 SLEEPPID=$!
12446                 sleep 0.500s
12447                 kill $SLEEPPID
12448                 wait $SLEEPPID
12449         done
12450
12451         set_nodes_failloc "$(osts_nodes)" 0
12452         rm -rf $DIR/$tdir
12453 }
12454 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12455
12456 test_118l() # LU-646
12457 {
12458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12459
12460         test_mkdir $DIR/$tdir
12461         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12462         rm -rf $DIR/$tdir
12463 }
12464 run_test 118l "fsync dir"
12465
12466 test_118m() # LU-3066
12467 {
12468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12469
12470         test_mkdir $DIR/$tdir
12471         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12472         rm -rf $DIR/$tdir
12473 }
12474 run_test 118m "fdatasync dir ========="
12475
12476 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12477
12478 test_118n()
12479 {
12480         local begin
12481         local end
12482
12483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12484         remote_ost_nodsh && skip "remote OSTs with nodsh"
12485
12486         # Sleep to avoid a cached response.
12487         #define OBD_STATFS_CACHE_SECONDS 1
12488         sleep 2
12489
12490         # Inject a 10 second delay in the OST_STATFS handler.
12491         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12492         set_nodes_failloc "$(osts_nodes)" 0x242
12493
12494         begin=$SECONDS
12495         stat --file-system $MOUNT > /dev/null
12496         end=$SECONDS
12497
12498         set_nodes_failloc "$(osts_nodes)" 0
12499
12500         if ((end - begin > 20)); then
12501             error "statfs took $((end - begin)) seconds, expected 10"
12502         fi
12503 }
12504 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12505
12506 test_119a() # bug 11737
12507 {
12508         BSIZE=$((512 * 1024))
12509         directio write $DIR/$tfile 0 1 $BSIZE
12510         # We ask to read two blocks, which is more than a file size.
12511         # directio will indicate an error when requested and actual
12512         # sizes aren't equeal (a normal situation in this case) and
12513         # print actual read amount.
12514         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12515         if [ "$NOB" != "$BSIZE" ]; then
12516                 error "read $NOB bytes instead of $BSIZE"
12517         fi
12518         rm -f $DIR/$tfile
12519 }
12520 run_test 119a "Short directIO read must return actual read amount"
12521
12522 test_119b() # bug 11737
12523 {
12524         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12525
12526         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12527         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12528         sync
12529         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12530                 error "direct read failed"
12531         rm -f $DIR/$tfile
12532 }
12533 run_test 119b "Sparse directIO read must return actual read amount"
12534
12535 test_119c() # bug 13099
12536 {
12537         BSIZE=1048576
12538         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12539         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12540         rm -f $DIR/$tfile
12541 }
12542 run_test 119c "Testing for direct read hitting hole"
12543
12544 test_119d() # bug 15950
12545 {
12546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12547
12548         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12549         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12550         BSIZE=1048576
12551         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12552         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12553         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12554         lctl set_param fail_loc=0x40d
12555         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12556         pid_dio=$!
12557         sleep 1
12558         cat $DIR/$tfile > /dev/null &
12559         lctl set_param fail_loc=0
12560         pid_reads=$!
12561         wait $pid_dio
12562         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12563         sleep 2
12564         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12565         error "the read rpcs have not completed in 2s"
12566         rm -f $DIR/$tfile
12567         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12568 }
12569 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12570
12571 test_120a() {
12572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12573         remote_mds_nodsh && skip "remote MDS with nodsh"
12574         test_mkdir -i0 -c1 $DIR/$tdir
12575         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12576                 skip_env "no early lock cancel on server"
12577
12578         lru_resize_disable mdc
12579         lru_resize_disable osc
12580         cancel_lru_locks mdc
12581         # asynchronous object destroy at MDT could cause bl ast to client
12582         cancel_lru_locks osc
12583
12584         stat $DIR/$tdir > /dev/null
12585         can1=$(do_facet mds1 \
12586                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12587                awk '/ldlm_cancel/ {print $2}')
12588         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12589                awk '/ldlm_bl_callback/ {print $2}')
12590         test_mkdir -i0 -c1 $DIR/$tdir/d1
12591         can2=$(do_facet mds1 \
12592                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12593                awk '/ldlm_cancel/ {print $2}')
12594         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12595                awk '/ldlm_bl_callback/ {print $2}')
12596         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12597         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12598         lru_resize_enable mdc
12599         lru_resize_enable osc
12600 }
12601 run_test 120a "Early Lock Cancel: mkdir test"
12602
12603 test_120b() {
12604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12605         remote_mds_nodsh && skip "remote MDS with nodsh"
12606         test_mkdir $DIR/$tdir
12607         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12608                 skip_env "no early lock cancel on server"
12609
12610         lru_resize_disable mdc
12611         lru_resize_disable osc
12612         cancel_lru_locks mdc
12613         stat $DIR/$tdir > /dev/null
12614         can1=$(do_facet $SINGLEMDS \
12615                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12616                awk '/ldlm_cancel/ {print $2}')
12617         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12618                awk '/ldlm_bl_callback/ {print $2}')
12619         touch $DIR/$tdir/f1
12620         can2=$(do_facet $SINGLEMDS \
12621                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12622                awk '/ldlm_cancel/ {print $2}')
12623         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12624                awk '/ldlm_bl_callback/ {print $2}')
12625         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12626         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12627         lru_resize_enable mdc
12628         lru_resize_enable osc
12629 }
12630 run_test 120b "Early Lock Cancel: create test"
12631
12632 test_120c() {
12633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12634         remote_mds_nodsh && skip "remote MDS with nodsh"
12635         test_mkdir -i0 -c1 $DIR/$tdir
12636         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12637                 skip "no early lock cancel on server"
12638
12639         lru_resize_disable mdc
12640         lru_resize_disable osc
12641         test_mkdir -i0 -c1 $DIR/$tdir/d1
12642         test_mkdir -i0 -c1 $DIR/$tdir/d2
12643         touch $DIR/$tdir/d1/f1
12644         cancel_lru_locks mdc
12645         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12646         can1=$(do_facet mds1 \
12647                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12648                awk '/ldlm_cancel/ {print $2}')
12649         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12650                awk '/ldlm_bl_callback/ {print $2}')
12651         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12652         can2=$(do_facet mds1 \
12653                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12654                awk '/ldlm_cancel/ {print $2}')
12655         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12656                awk '/ldlm_bl_callback/ {print $2}')
12657         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12658         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12659         lru_resize_enable mdc
12660         lru_resize_enable osc
12661 }
12662 run_test 120c "Early Lock Cancel: link test"
12663
12664 test_120d() {
12665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12666         remote_mds_nodsh && skip "remote MDS with nodsh"
12667         test_mkdir -i0 -c1 $DIR/$tdir
12668         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12669                 skip_env "no early lock cancel on server"
12670
12671         lru_resize_disable mdc
12672         lru_resize_disable osc
12673         touch $DIR/$tdir
12674         cancel_lru_locks mdc
12675         stat $DIR/$tdir > /dev/null
12676         can1=$(do_facet mds1 \
12677                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12678                awk '/ldlm_cancel/ {print $2}')
12679         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12680                awk '/ldlm_bl_callback/ {print $2}')
12681         chmod a+x $DIR/$tdir
12682         can2=$(do_facet mds1 \
12683                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12684                awk '/ldlm_cancel/ {print $2}')
12685         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12686                awk '/ldlm_bl_callback/ {print $2}')
12687         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12688         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12689         lru_resize_enable mdc
12690         lru_resize_enable osc
12691 }
12692 run_test 120d "Early Lock Cancel: setattr test"
12693
12694 test_120e() {
12695         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12696         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12697                 skip_env "no early lock cancel on server"
12698         remote_mds_nodsh && skip "remote MDS with nodsh"
12699
12700         local dlmtrace_set=false
12701
12702         test_mkdir -i0 -c1 $DIR/$tdir
12703         lru_resize_disable mdc
12704         lru_resize_disable osc
12705         ! $LCTL get_param debug | grep -q dlmtrace &&
12706                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12707         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12708         cancel_lru_locks mdc
12709         cancel_lru_locks osc
12710         dd if=$DIR/$tdir/f1 of=/dev/null
12711         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12712         # XXX client can not do early lock cancel of OST lock
12713         # during unlink (LU-4206), so cancel osc lock now.
12714         sleep 2
12715         cancel_lru_locks osc
12716         can1=$(do_facet mds1 \
12717                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12718                awk '/ldlm_cancel/ {print $2}')
12719         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12720                awk '/ldlm_bl_callback/ {print $2}')
12721         unlink $DIR/$tdir/f1
12722         sleep 5
12723         can2=$(do_facet mds1 \
12724                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12725                awk '/ldlm_cancel/ {print $2}')
12726         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12727                awk '/ldlm_bl_callback/ {print $2}')
12728         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12729                 $LCTL dk $TMP/cancel.debug.txt
12730         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12731                 $LCTL dk $TMP/blocking.debug.txt
12732         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12733         lru_resize_enable mdc
12734         lru_resize_enable osc
12735 }
12736 run_test 120e "Early Lock Cancel: unlink test"
12737
12738 test_120f() {
12739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12740         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12741                 skip_env "no early lock cancel on server"
12742         remote_mds_nodsh && skip "remote MDS with nodsh"
12743
12744         test_mkdir -i0 -c1 $DIR/$tdir
12745         lru_resize_disable mdc
12746         lru_resize_disable osc
12747         test_mkdir -i0 -c1 $DIR/$tdir/d1
12748         test_mkdir -i0 -c1 $DIR/$tdir/d2
12749         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12750         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12751         cancel_lru_locks mdc
12752         cancel_lru_locks osc
12753         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12754         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12755         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12756         # XXX client can not do early lock cancel of OST lock
12757         # during rename (LU-4206), so cancel osc lock now.
12758         sleep 2
12759         cancel_lru_locks osc
12760         can1=$(do_facet mds1 \
12761                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12762                awk '/ldlm_cancel/ {print $2}')
12763         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12764                awk '/ldlm_bl_callback/ {print $2}')
12765         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12766         sleep 5
12767         can2=$(do_facet mds1 \
12768                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12769                awk '/ldlm_cancel/ {print $2}')
12770         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12771                awk '/ldlm_bl_callback/ {print $2}')
12772         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12773         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12774         lru_resize_enable mdc
12775         lru_resize_enable osc
12776 }
12777 run_test 120f "Early Lock Cancel: rename test"
12778
12779 test_120g() {
12780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12781         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12782                 skip_env "no early lock cancel on server"
12783         remote_mds_nodsh && skip "remote MDS with nodsh"
12784
12785         lru_resize_disable mdc
12786         lru_resize_disable osc
12787         count=10000
12788         echo create $count files
12789         test_mkdir $DIR/$tdir
12790         cancel_lru_locks mdc
12791         cancel_lru_locks osc
12792         t0=$(date +%s)
12793
12794         can0=$(do_facet $SINGLEMDS \
12795                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12796                awk '/ldlm_cancel/ {print $2}')
12797         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12798                awk '/ldlm_bl_callback/ {print $2}')
12799         createmany -o $DIR/$tdir/f $count
12800         sync
12801         can1=$(do_facet $SINGLEMDS \
12802                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12803                awk '/ldlm_cancel/ {print $2}')
12804         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12805                awk '/ldlm_bl_callback/ {print $2}')
12806         t1=$(date +%s)
12807         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12808         echo rm $count files
12809         rm -r $DIR/$tdir
12810         sync
12811         can2=$(do_facet $SINGLEMDS \
12812                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12813                awk '/ldlm_cancel/ {print $2}')
12814         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12815                awk '/ldlm_bl_callback/ {print $2}')
12816         t2=$(date +%s)
12817         echo total: $count removes in $((t2-t1))
12818         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12819         sleep 2
12820         # wait for commitment of removal
12821         lru_resize_enable mdc
12822         lru_resize_enable osc
12823 }
12824 run_test 120g "Early Lock Cancel: performance test"
12825
12826 test_121() { #bug #10589
12827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12828
12829         rm -rf $DIR/$tfile
12830         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12831 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12832         lctl set_param fail_loc=0x310
12833         cancel_lru_locks osc > /dev/null
12834         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12835         lctl set_param fail_loc=0
12836         [[ $reads -eq $writes ]] ||
12837                 error "read $reads blocks, must be $writes blocks"
12838 }
12839 run_test 121 "read cancel race ========="
12840
12841 test_123a_base() { # was test 123, statahead(bug 11401)
12842         local lsx="$1"
12843
12844         SLOWOK=0
12845         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12846                 log "testing UP system. Performance may be lower than expected."
12847                 SLOWOK=1
12848         fi
12849
12850         rm -rf $DIR/$tdir
12851         test_mkdir $DIR/$tdir
12852         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12853         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12854         MULT=10
12855         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12856                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12857
12858                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12859                 lctl set_param -n llite.*.statahead_max 0
12860                 lctl get_param llite.*.statahead_max
12861                 cancel_lru_locks mdc
12862                 cancel_lru_locks osc
12863                 stime=$(date +%s)
12864                 time $lsx $DIR/$tdir | wc -l
12865                 etime=$(date +%s)
12866                 delta=$((etime - stime))
12867                 log "$lsx $i files without statahead: $delta sec"
12868                 lctl set_param llite.*.statahead_max=$max
12869
12870                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12871                         grep "statahead wrong:" | awk '{print $3}')
12872                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12873                 cancel_lru_locks mdc
12874                 cancel_lru_locks osc
12875                 stime=$(date +%s)
12876                 time $lsx $DIR/$tdir | wc -l
12877                 etime=$(date +%s)
12878                 delta_sa=$((etime - stime))
12879                 log "$lsx $i files with statahead: $delta_sa sec"
12880                 lctl get_param -n llite.*.statahead_stats
12881                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12882                         grep "statahead wrong:" | awk '{print $3}')
12883
12884                 [[ $swrong -lt $ewrong ]] &&
12885                         log "statahead was stopped, maybe too many locks held!"
12886                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12887
12888                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12889                         max=$(lctl get_param -n llite.*.statahead_max |
12890                                 head -n 1)
12891                         lctl set_param -n llite.*.statahead_max 0
12892                         lctl get_param llite.*.statahead_max
12893                         cancel_lru_locks mdc
12894                         cancel_lru_locks osc
12895                         stime=$(date +%s)
12896                         time $lsx $DIR/$tdir | wc -l
12897                         etime=$(date +%s)
12898                         delta=$((etime - stime))
12899                         log "$lsx $i files again without statahead: $delta sec"
12900                         lctl set_param llite.*.statahead_max=$max
12901                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12902                                 if [  $SLOWOK -eq 0 ]; then
12903                                         error "$lsx $i files is slower with statahead!"
12904                                 else
12905                                         log "$lsx $i files is slower with statahead!"
12906                                 fi
12907                                 break
12908                         fi
12909                 fi
12910
12911                 [ $delta -gt 20 ] && break
12912                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12913                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12914         done
12915         log "$lsx done"
12916
12917         stime=$(date +%s)
12918         rm -r $DIR/$tdir
12919         sync
12920         etime=$(date +%s)
12921         delta=$((etime - stime))
12922         log "rm -r $DIR/$tdir/: $delta seconds"
12923         log "rm done"
12924         lctl get_param -n llite.*.statahead_stats
12925 }
12926
12927 test_123aa() {
12928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12929
12930         test_123a_base "ls -l"
12931 }
12932 run_test 123aa "verify statahead work"
12933
12934 test_123ab() {
12935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12936
12937         statx_supported || skip_env "Test must be statx() syscall supported"
12938
12939         test_123a_base "$STATX -l"
12940 }
12941 run_test 123ab "verify statahead work by using statx"
12942
12943 test_123ac() {
12944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12945
12946         statx_supported || skip_env "Test must be statx() syscall supported"
12947
12948         local rpcs_before
12949         local rpcs_after
12950         local agl_before
12951         local agl_after
12952
12953         cancel_lru_locks $OSC
12954         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12955         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12956                 awk '/agl.total:/ {print $3}')
12957         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12958         test_123a_base "$STATX --cached=always -D"
12959         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12960                 awk '/agl.total:/ {print $3}')
12961         [ $agl_before -eq $agl_after ] ||
12962                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12963         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12964         [ $rpcs_after -eq $rpcs_before ] ||
12965                 error "$STATX should not send glimpse RPCs to $OSC"
12966 }
12967 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12968
12969 test_123b () { # statahead(bug 15027)
12970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12971
12972         test_mkdir $DIR/$tdir
12973         createmany -o $DIR/$tdir/$tfile-%d 1000
12974
12975         cancel_lru_locks mdc
12976         cancel_lru_locks osc
12977
12978 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12979         lctl set_param fail_loc=0x80000803
12980         ls -lR $DIR/$tdir > /dev/null
12981         log "ls done"
12982         lctl set_param fail_loc=0x0
12983         lctl get_param -n llite.*.statahead_stats
12984         rm -r $DIR/$tdir
12985         sync
12986
12987 }
12988 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12989
12990 test_123c() {
12991         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12992
12993         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12994         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12995         touch $DIR/$tdir.1/{1..3}
12996         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12997
12998         remount_client $MOUNT
12999
13000         $MULTIOP $DIR/$tdir.0 Q
13001
13002         # let statahead to complete
13003         ls -l $DIR/$tdir.0 > /dev/null
13004
13005         testid=$(echo $TESTNAME | tr '_' ' ')
13006         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13007                 error "statahead warning" || true
13008 }
13009 run_test 123c "Can not initialize inode warning on DNE statahead"
13010
13011 test_124a() {
13012         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13013         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13014                 skip_env "no lru resize on server"
13015
13016         local NR=2000
13017
13018         test_mkdir $DIR/$tdir
13019
13020         log "create $NR files at $DIR/$tdir"
13021         createmany -o $DIR/$tdir/f $NR ||
13022                 error "failed to create $NR files in $DIR/$tdir"
13023
13024         cancel_lru_locks mdc
13025         ls -l $DIR/$tdir > /dev/null
13026
13027         local NSDIR=""
13028         local LRU_SIZE=0
13029         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13030                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13031                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13032                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13033                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13034                         log "NSDIR=$NSDIR"
13035                         log "NS=$(basename $NSDIR)"
13036                         break
13037                 fi
13038         done
13039
13040         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13041                 skip "Not enough cached locks created!"
13042         fi
13043         log "LRU=$LRU_SIZE"
13044
13045         local SLEEP=30
13046
13047         # We know that lru resize allows one client to hold $LIMIT locks
13048         # for 10h. After that locks begin to be killed by client.
13049         local MAX_HRS=10
13050         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13051         log "LIMIT=$LIMIT"
13052         if [ $LIMIT -lt $LRU_SIZE ]; then
13053                 skip "Limit is too small $LIMIT"
13054         fi
13055
13056         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13057         # killing locks. Some time was spent for creating locks. This means
13058         # that up to the moment of sleep finish we must have killed some of
13059         # them (10-100 locks). This depends on how fast ther were created.
13060         # Many of them were touched in almost the same moment and thus will
13061         # be killed in groups.
13062         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13063
13064         # Use $LRU_SIZE_B here to take into account real number of locks
13065         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13066         local LRU_SIZE_B=$LRU_SIZE
13067         log "LVF=$LVF"
13068         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13069         log "OLD_LVF=$OLD_LVF"
13070         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13071
13072         # Let's make sure that we really have some margin. Client checks
13073         # cached locks every 10 sec.
13074         SLEEP=$((SLEEP+20))
13075         log "Sleep ${SLEEP} sec"
13076         local SEC=0
13077         while ((SEC<$SLEEP)); do
13078                 echo -n "..."
13079                 sleep 5
13080                 SEC=$((SEC+5))
13081                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13082                 echo -n "$LRU_SIZE"
13083         done
13084         echo ""
13085         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13086         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13087
13088         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13089                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13090                 unlinkmany $DIR/$tdir/f $NR
13091                 return
13092         }
13093
13094         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13095         log "unlink $NR files at $DIR/$tdir"
13096         unlinkmany $DIR/$tdir/f $NR
13097 }
13098 run_test 124a "lru resize ======================================="
13099
13100 get_max_pool_limit()
13101 {
13102         local limit=$($LCTL get_param \
13103                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13104         local max=0
13105         for l in $limit; do
13106                 if [[ $l -gt $max ]]; then
13107                         max=$l
13108                 fi
13109         done
13110         echo $max
13111 }
13112
13113 test_124b() {
13114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13115         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13116                 skip_env "no lru resize on server"
13117
13118         LIMIT=$(get_max_pool_limit)
13119
13120         NR=$(($(default_lru_size)*20))
13121         if [[ $NR -gt $LIMIT ]]; then
13122                 log "Limit lock number by $LIMIT locks"
13123                 NR=$LIMIT
13124         fi
13125
13126         IFree=$(mdsrate_inodes_available)
13127         if [ $IFree -lt $NR ]; then
13128                 log "Limit lock number by $IFree inodes"
13129                 NR=$IFree
13130         fi
13131
13132         lru_resize_disable mdc
13133         test_mkdir -p $DIR/$tdir/disable_lru_resize
13134
13135         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13136         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13137         cancel_lru_locks mdc
13138         stime=`date +%s`
13139         PID=""
13140         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13141         PID="$PID $!"
13142         sleep 2
13143         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13144         PID="$PID $!"
13145         sleep 2
13146         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13147         PID="$PID $!"
13148         wait $PID
13149         etime=`date +%s`
13150         nolruresize_delta=$((etime-stime))
13151         log "ls -la time: $nolruresize_delta seconds"
13152         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13153         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13154
13155         lru_resize_enable mdc
13156         test_mkdir -p $DIR/$tdir/enable_lru_resize
13157
13158         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13159         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13160         cancel_lru_locks mdc
13161         stime=`date +%s`
13162         PID=""
13163         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13164         PID="$PID $!"
13165         sleep 2
13166         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13167         PID="$PID $!"
13168         sleep 2
13169         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13170         PID="$PID $!"
13171         wait $PID
13172         etime=`date +%s`
13173         lruresize_delta=$((etime-stime))
13174         log "ls -la time: $lruresize_delta seconds"
13175         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13176
13177         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13178                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13179         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13180                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13181         else
13182                 log "lru resize performs the same with no lru resize"
13183         fi
13184         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13185 }
13186 run_test 124b "lru resize (performance test) ======================="
13187
13188 test_124c() {
13189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13190         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13191                 skip_env "no lru resize on server"
13192
13193         # cache ununsed locks on client
13194         local nr=100
13195         cancel_lru_locks mdc
13196         test_mkdir $DIR/$tdir
13197         createmany -o $DIR/$tdir/f $nr ||
13198                 error "failed to create $nr files in $DIR/$tdir"
13199         ls -l $DIR/$tdir > /dev/null
13200
13201         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13202         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13203         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13204         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13205         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13206
13207         # set lru_max_age to 1 sec
13208         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13209         echo "sleep $((recalc_p * 2)) seconds..."
13210         sleep $((recalc_p * 2))
13211
13212         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13213         # restore lru_max_age
13214         $LCTL set_param -n $nsdir.lru_max_age $max_age
13215         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13216         unlinkmany $DIR/$tdir/f $nr
13217 }
13218 run_test 124c "LRUR cancel very aged locks"
13219
13220 test_124d() {
13221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13222         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13223                 skip_env "no lru resize on server"
13224
13225         # cache ununsed locks on client
13226         local nr=100
13227
13228         lru_resize_disable mdc
13229         stack_trap "lru_resize_enable mdc" EXIT
13230
13231         cancel_lru_locks mdc
13232
13233         # asynchronous object destroy at MDT could cause bl ast to client
13234         test_mkdir $DIR/$tdir
13235         createmany -o $DIR/$tdir/f $nr ||
13236                 error "failed to create $nr files in $DIR/$tdir"
13237         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13238
13239         ls -l $DIR/$tdir > /dev/null
13240
13241         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13242         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13243         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13244         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13245
13246         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13247
13248         # set lru_max_age to 1 sec
13249         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13250         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13251
13252         echo "sleep $((recalc_p * 2)) seconds..."
13253         sleep $((recalc_p * 2))
13254
13255         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13256
13257         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13258 }
13259 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13260
13261 test_125() { # 13358
13262         $LCTL get_param -n llite.*.client_type | grep -q local ||
13263                 skip "must run as local client"
13264         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13265                 skip_env "must have acl enabled"
13266         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13267
13268         test_mkdir $DIR/$tdir
13269         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13270         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13271         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13272 }
13273 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13274
13275 test_126() { # bug 12829/13455
13276         $GSS && skip_env "must run as gss disabled"
13277         $LCTL get_param -n llite.*.client_type | grep -q local ||
13278                 skip "must run as local client"
13279         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13280
13281         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13282         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13283         rm -f $DIR/$tfile
13284         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13285 }
13286 run_test 126 "check that the fsgid provided by the client is taken into account"
13287
13288 test_127a() { # bug 15521
13289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13290         local name count samp unit min max sum sumsq
13291
13292         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13293         echo "stats before reset"
13294         $LCTL get_param osc.*.stats
13295         $LCTL set_param osc.*.stats=0
13296         local fsize=$((2048 * 1024))
13297
13298         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13299         cancel_lru_locks osc
13300         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13301
13302         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13303         stack_trap "rm -f $TMP/$tfile.tmp"
13304         while read name count samp unit min max sum sumsq; do
13305                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13306                 [ ! $min ] && error "Missing min value for $name proc entry"
13307                 eval $name=$count || error "Wrong proc format"
13308
13309                 case $name in
13310                 read_bytes|write_bytes)
13311                         [[ "$unit" =~ "bytes" ]] ||
13312                                 error "unit is not 'bytes': $unit"
13313                         (( $min >= 4096 )) || error "min is too small: $min"
13314                         (( $min <= $fsize )) || error "min is too big: $min"
13315                         (( $max >= 4096 )) || error "max is too small: $max"
13316                         (( $max <= $fsize )) || error "max is too big: $max"
13317                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13318                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13319                                 error "sumsquare is too small: $sumsq"
13320                         (( $sumsq <= $fsize * $fsize )) ||
13321                                 error "sumsquare is too big: $sumsq"
13322                         ;;
13323                 ost_read|ost_write)
13324                         [[ "$unit" =~ "usec" ]] ||
13325                                 error "unit is not 'usec': $unit"
13326                         ;;
13327                 *)      ;;
13328                 esac
13329         done < $DIR/$tfile.tmp
13330
13331         #check that we actually got some stats
13332         [ "$read_bytes" ] || error "Missing read_bytes stats"
13333         [ "$write_bytes" ] || error "Missing write_bytes stats"
13334         [ "$read_bytes" != 0 ] || error "no read done"
13335         [ "$write_bytes" != 0 ] || error "no write done"
13336 }
13337 run_test 127a "verify the client stats are sane"
13338
13339 test_127b() { # bug LU-333
13340         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13341         local name count samp unit min max sum sumsq
13342
13343         echo "stats before reset"
13344         $LCTL get_param llite.*.stats
13345         $LCTL set_param llite.*.stats=0
13346
13347         # perform 2 reads and writes so MAX is different from SUM.
13348         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13349         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13350         cancel_lru_locks osc
13351         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13352         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13353
13354         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13355         stack_trap "rm -f $TMP/$tfile.tmp"
13356         while read name count samp unit min max sum sumsq; do
13357                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13358                 eval $name=$count || error "Wrong proc format"
13359
13360                 case $name in
13361                 read_bytes|write_bytes)
13362                         [[ "$unit" =~ "bytes" ]] ||
13363                                 error "unit is not 'bytes': $unit"
13364                         (( $count == 2 )) || error "count is not 2: $count"
13365                         (( $min == $PAGE_SIZE )) ||
13366                                 error "min is not $PAGE_SIZE: $min"
13367                         (( $max == $PAGE_SIZE )) ||
13368                                 error "max is not $PAGE_SIZE: $max"
13369                         (( $sum == $PAGE_SIZE * 2 )) ||
13370                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13371                         ;;
13372                 read|write)
13373                         [[ "$unit" =~ "usec" ]] ||
13374                                 error "unit is not 'usec': $unit"
13375                         ;;
13376                 *)      ;;
13377                 esac
13378         done < $TMP/$tfile.tmp
13379
13380         #check that we actually got some stats
13381         [ "$read_bytes" ] || error "Missing read_bytes stats"
13382         [ "$write_bytes" ] || error "Missing write_bytes stats"
13383         [ "$read_bytes" != 0 ] || error "no read done"
13384         [ "$write_bytes" != 0 ] || error "no write done"
13385 }
13386 run_test 127b "verify the llite client stats are sane"
13387
13388 test_127c() { # LU-12394
13389         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13390         local size
13391         local bsize
13392         local reads
13393         local writes
13394         local count
13395
13396         $LCTL set_param llite.*.extents_stats=1
13397         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13398
13399         # Use two stripes so there is enough space in default config
13400         $LFS setstripe -c 2 $DIR/$tfile
13401
13402         # Extent stats start at 0-4K and go in power of two buckets
13403         # LL_HIST_START = 12 --> 2^12 = 4K
13404         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13405         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13406         # small configs
13407         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13408                 do
13409                 # Write and read, 2x each, second time at a non-zero offset
13410                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13411                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13412                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13413                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13414                 rm -f $DIR/$tfile
13415         done
13416
13417         $LCTL get_param llite.*.extents_stats
13418
13419         count=2
13420         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13421                 do
13422                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13423                                 grep -m 1 $bsize)
13424                 reads=$(echo $bucket | awk '{print $5}')
13425                 writes=$(echo $bucket | awk '{print $9}')
13426                 [ "$reads" -eq $count ] ||
13427                         error "$reads reads in < $bsize bucket, expect $count"
13428                 [ "$writes" -eq $count ] ||
13429                         error "$writes writes in < $bsize bucket, expect $count"
13430         done
13431
13432         # Test mmap write and read
13433         $LCTL set_param llite.*.extents_stats=c
13434         size=512
13435         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13436         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13437         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13438
13439         $LCTL get_param llite.*.extents_stats
13440
13441         count=$(((size*1024) / PAGE_SIZE))
13442
13443         bsize=$((2 * PAGE_SIZE / 1024))K
13444
13445         bucket=$($LCTL get_param -n llite.*.extents_stats |
13446                         grep -m 1 $bsize)
13447         reads=$(echo $bucket | awk '{print $5}')
13448         writes=$(echo $bucket | awk '{print $9}')
13449         # mmap writes fault in the page first, creating an additonal read
13450         [ "$reads" -eq $((2 * count)) ] ||
13451                 error "$reads reads in < $bsize bucket, expect $count"
13452         [ "$writes" -eq $count ] ||
13453                 error "$writes writes in < $bsize bucket, expect $count"
13454 }
13455 run_test 127c "test llite extent stats with regular & mmap i/o"
13456
13457 test_128() { # bug 15212
13458         touch $DIR/$tfile
13459         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13460                 find $DIR/$tfile
13461                 find $DIR/$tfile
13462         EOF
13463
13464         result=$(grep error $TMP/$tfile.log)
13465         rm -f $DIR/$tfile $TMP/$tfile.log
13466         [ -z "$result" ] ||
13467                 error "consecutive find's under interactive lfs failed"
13468 }
13469 run_test 128 "interactive lfs for 2 consecutive find's"
13470
13471 set_dir_limits () {
13472         local mntdev
13473         local canondev
13474         local node
13475
13476         local ldproc=/proc/fs/ldiskfs
13477         local facets=$(get_facets MDS)
13478
13479         for facet in ${facets//,/ }; do
13480                 canondev=$(ldiskfs_canon \
13481                            *.$(convert_facet2label $facet).mntdev $facet)
13482                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13483                         ldproc=/sys/fs/ldiskfs
13484                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13485                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13486         done
13487 }
13488
13489 check_mds_dmesg() {
13490         local facets=$(get_facets MDS)
13491         for facet in ${facets//,/ }; do
13492                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13493         done
13494         return 1
13495 }
13496
13497 test_129() {
13498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13499         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13500                 skip "Need MDS version with at least 2.5.56"
13501         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13502                 skip_env "ldiskfs only test"
13503         fi
13504         remote_mds_nodsh && skip "remote MDS with nodsh"
13505
13506         local ENOSPC=28
13507         local has_warning=false
13508
13509         rm -rf $DIR/$tdir
13510         mkdir -p $DIR/$tdir
13511
13512         # block size of mds1
13513         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13514         set_dir_limits $maxsize $((maxsize * 6 / 8))
13515         stack_trap "set_dir_limits 0 0"
13516         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13517         local dirsize=$(stat -c%s "$DIR/$tdir")
13518         local nfiles=0
13519         while (( $dirsize <= $maxsize )); do
13520                 $MCREATE $DIR/$tdir/file_base_$nfiles
13521                 rc=$?
13522                 # check two errors:
13523                 # ENOSPC for ext4 max_dir_size, which has been used since
13524                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13525                 if (( rc == ENOSPC )); then
13526                         set_dir_limits 0 0
13527                         echo "rc=$rc returned as expected after $nfiles files"
13528
13529                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13530                                 error "create failed w/o dir size limit"
13531
13532                         # messages may be rate limited if test is run repeatedly
13533                         check_mds_dmesg '"is approaching max"' ||
13534                                 echo "warning message should be output"
13535                         check_mds_dmesg '"has reached max"' ||
13536                                 echo "reached message should be output"
13537
13538                         dirsize=$(stat -c%s "$DIR/$tdir")
13539
13540                         [[ $dirsize -ge $maxsize ]] && return 0
13541                         error "dirsize $dirsize < $maxsize after $nfiles files"
13542                 elif (( rc != 0 )); then
13543                         break
13544                 fi
13545                 nfiles=$((nfiles + 1))
13546                 dirsize=$(stat -c%s "$DIR/$tdir")
13547         done
13548
13549         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13550 }
13551 run_test 129 "test directory size limit ========================"
13552
13553 OLDIFS="$IFS"
13554 cleanup_130() {
13555         trap 0
13556         IFS="$OLDIFS"
13557 }
13558
13559 test_130a() {
13560         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13561         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13562
13563         trap cleanup_130 EXIT RETURN
13564
13565         local fm_file=$DIR/$tfile
13566         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13567         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13568                 error "dd failed for $fm_file"
13569
13570         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13571         filefrag -ves $fm_file
13572         RC=$?
13573         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13574                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13575         [ $RC != 0 ] && error "filefrag $fm_file failed"
13576
13577         filefrag_op=$(filefrag -ve -k $fm_file |
13578                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13579         lun=$($LFS getstripe -i $fm_file)
13580
13581         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13582         IFS=$'\n'
13583         tot_len=0
13584         for line in $filefrag_op
13585         do
13586                 frag_lun=`echo $line | cut -d: -f5`
13587                 ext_len=`echo $line | cut -d: -f4`
13588                 if (( $frag_lun != $lun )); then
13589                         cleanup_130
13590                         error "FIEMAP on 1-stripe file($fm_file) failed"
13591                         return
13592                 fi
13593                 (( tot_len += ext_len ))
13594         done
13595
13596         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13597                 cleanup_130
13598                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13599                 return
13600         fi
13601
13602         cleanup_130
13603
13604         echo "FIEMAP on single striped file succeeded"
13605 }
13606 run_test 130a "FIEMAP (1-stripe file)"
13607
13608 test_130b() {
13609         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13610
13611         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13612         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13613
13614         trap cleanup_130 EXIT RETURN
13615
13616         local fm_file=$DIR/$tfile
13617         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13618                         error "setstripe on $fm_file"
13619         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13620                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13621
13622         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13623                 error "dd failed on $fm_file"
13624
13625         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13626         filefrag_op=$(filefrag -ve -k $fm_file |
13627                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13628
13629         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13630                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13631
13632         IFS=$'\n'
13633         tot_len=0
13634         num_luns=1
13635         for line in $filefrag_op
13636         do
13637                 frag_lun=$(echo $line | cut -d: -f5 |
13638                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13639                 ext_len=$(echo $line | cut -d: -f4)
13640                 if (( $frag_lun != $last_lun )); then
13641                         if (( tot_len != 1024 )); then
13642                                 cleanup_130
13643                                 error "FIEMAP on $fm_file failed; returned " \
13644                                 "len $tot_len for OST $last_lun instead of 1024"
13645                                 return
13646                         else
13647                                 (( num_luns += 1 ))
13648                                 tot_len=0
13649                         fi
13650                 fi
13651                 (( tot_len += ext_len ))
13652                 last_lun=$frag_lun
13653         done
13654         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13655                 cleanup_130
13656                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13657                         "luns or wrong len for OST $last_lun"
13658                 return
13659         fi
13660
13661         cleanup_130
13662
13663         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13664 }
13665 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13666
13667 test_130c() {
13668         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13669
13670         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13671         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13672
13673         trap cleanup_130 EXIT RETURN
13674
13675         local fm_file=$DIR/$tfile
13676         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13677         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13678                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13679
13680         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13681                         error "dd failed on $fm_file"
13682
13683         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13684         filefrag_op=$(filefrag -ve -k $fm_file |
13685                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13686
13687         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13688                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13689
13690         IFS=$'\n'
13691         tot_len=0
13692         num_luns=1
13693         for line in $filefrag_op
13694         do
13695                 frag_lun=$(echo $line | cut -d: -f5 |
13696                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13697                 ext_len=$(echo $line | cut -d: -f4)
13698                 if (( $frag_lun != $last_lun )); then
13699                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13700                         if (( logical != 512 )); then
13701                                 cleanup_130
13702                                 error "FIEMAP on $fm_file failed; returned " \
13703                                 "logical start for lun $logical instead of 512"
13704                                 return
13705                         fi
13706                         if (( tot_len != 512 )); then
13707                                 cleanup_130
13708                                 error "FIEMAP on $fm_file failed; returned " \
13709                                 "len $tot_len for OST $last_lun instead of 1024"
13710                                 return
13711                         else
13712                                 (( num_luns += 1 ))
13713                                 tot_len=0
13714                         fi
13715                 fi
13716                 (( tot_len += ext_len ))
13717                 last_lun=$frag_lun
13718         done
13719         if (( num_luns != 2 || tot_len != 512 )); then
13720                 cleanup_130
13721                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13722                         "luns or wrong len for OST $last_lun"
13723                 return
13724         fi
13725
13726         cleanup_130
13727
13728         echo "FIEMAP on 2-stripe file with hole succeeded"
13729 }
13730 run_test 130c "FIEMAP (2-stripe file with hole)"
13731
13732 test_130d() {
13733         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13734
13735         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13736         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13737
13738         trap cleanup_130 EXIT RETURN
13739
13740         local fm_file=$DIR/$tfile
13741         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13742                         error "setstripe on $fm_file"
13743         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13744                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13745
13746         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13747         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13748                 error "dd failed on $fm_file"
13749
13750         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13751         filefrag_op=$(filefrag -ve -k $fm_file |
13752                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13753
13754         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13755                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13756
13757         IFS=$'\n'
13758         tot_len=0
13759         num_luns=1
13760         for line in $filefrag_op
13761         do
13762                 frag_lun=$(echo $line | cut -d: -f5 |
13763                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13764                 ext_len=$(echo $line | cut -d: -f4)
13765                 if (( $frag_lun != $last_lun )); then
13766                         if (( tot_len != 1024 )); then
13767                                 cleanup_130
13768                                 error "FIEMAP on $fm_file failed; returned " \
13769                                 "len $tot_len for OST $last_lun instead of 1024"
13770                                 return
13771                         else
13772                                 (( num_luns += 1 ))
13773                                 tot_len=0
13774                         fi
13775                 fi
13776                 (( tot_len += ext_len ))
13777                 last_lun=$frag_lun
13778         done
13779         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13780                 cleanup_130
13781                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13782                         "luns or wrong len for OST $last_lun"
13783                 return
13784         fi
13785
13786         cleanup_130
13787
13788         echo "FIEMAP on N-stripe file succeeded"
13789 }
13790 run_test 130d "FIEMAP (N-stripe file)"
13791
13792 test_130e() {
13793         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13794
13795         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13796         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13797
13798         trap cleanup_130 EXIT RETURN
13799
13800         local fm_file=$DIR/$tfile
13801         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13802
13803         NUM_BLKS=512
13804         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13805         for ((i = 0; i < $NUM_BLKS; i++)); do
13806                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13807                         conv=notrunc > /dev/null 2>&1
13808         done
13809
13810         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13811         filefrag_op=$(filefrag -ve -k $fm_file |
13812                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13813
13814         last_lun=$(echo $filefrag_op | cut -d: -f5)
13815
13816         IFS=$'\n'
13817         tot_len=0
13818         num_luns=1
13819         for line in $filefrag_op; do
13820                 frag_lun=$(echo $line | cut -d: -f5)
13821                 ext_len=$(echo $line | cut -d: -f4)
13822                 if [[ "$frag_lun" != "$last_lun" ]]; then
13823                         if (( tot_len != $EXPECTED_LEN )); then
13824                                 cleanup_130
13825                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13826                         else
13827                                 (( num_luns += 1 ))
13828                                 tot_len=0
13829                         fi
13830                 fi
13831                 (( tot_len += ext_len ))
13832                 last_lun=$frag_lun
13833         done
13834         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13835                 cleanup_130
13836                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13837         fi
13838
13839         echo "FIEMAP with continuation calls succeeded"
13840 }
13841 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13842
13843 test_130f() {
13844         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13845         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13846
13847         local fm_file=$DIR/$tfile
13848         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13849                 error "multiop create with lov_delay_create on $fm_file"
13850
13851         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13852         filefrag_extents=$(filefrag -vek $fm_file |
13853                            awk '/extents? found/ { print $2 }')
13854         if [[ "$filefrag_extents" != "0" ]]; then
13855                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13856         fi
13857
13858         rm -f $fm_file
13859 }
13860 run_test 130f "FIEMAP (unstriped file)"
13861
13862 test_130g() {
13863         local file=$DIR/$tfile
13864         local nr=$((OSTCOUNT * 100))
13865
13866         $LFS setstripe -C $nr $file ||
13867                 error "failed to setstripe -C $nr $file"
13868
13869         dd if=/dev/zero of=$file count=$nr bs=1M
13870         sync
13871         nr=$($LFS getstripe -c $file)
13872
13873         local extents=$(filefrag -v $file |
13874                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13875
13876         echo "filefrag list $extents extents in file with stripecount $nr"
13877         if (( extents < nr )); then
13878                 $LFS getstripe $file
13879                 filefrag -v $file
13880                 error "filefrag printed $extents < $nr extents"
13881         fi
13882
13883         rm -f $file
13884 }
13885 run_test 130g "FIEMAP (overstripe file)"
13886
13887 # Test for writev/readv
13888 test_131a() {
13889         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13890                 error "writev test failed"
13891         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13892                 error "readv failed"
13893         rm -f $DIR/$tfile
13894 }
13895 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13896
13897 test_131b() {
13898         local fsize=$((524288 + 1048576 + 1572864))
13899         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13900                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13901                         error "append writev test failed"
13902
13903         ((fsize += 1572864 + 1048576))
13904         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13905                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13906                         error "append writev test failed"
13907         rm -f $DIR/$tfile
13908 }
13909 run_test 131b "test append writev"
13910
13911 test_131c() {
13912         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13913         error "NOT PASS"
13914 }
13915 run_test 131c "test read/write on file w/o objects"
13916
13917 test_131d() {
13918         rwv -f $DIR/$tfile -w -n 1 1572864
13919         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13920         if [ "$NOB" != 1572864 ]; then
13921                 error "Short read filed: read $NOB bytes instead of 1572864"
13922         fi
13923         rm -f $DIR/$tfile
13924 }
13925 run_test 131d "test short read"
13926
13927 test_131e() {
13928         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13929         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13930         error "read hitting hole failed"
13931         rm -f $DIR/$tfile
13932 }
13933 run_test 131e "test read hitting hole"
13934
13935 check_stats() {
13936         local facet=$1
13937         local op=$2
13938         local want=${3:-0}
13939         local res
13940
13941         case $facet in
13942         mds*) res=$(do_facet $facet \
13943                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13944                  ;;
13945         ost*) res=$(do_facet $facet \
13946                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13947                  ;;
13948         *) error "Wrong facet '$facet'" ;;
13949         esac
13950         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13951         # if the argument $3 is zero, it means any stat increment is ok.
13952         if [[ $want -gt 0 ]]; then
13953                 local count=$(echo $res | awk '{ print $2 }')
13954                 [[ $count -ne $want ]] &&
13955                         error "The $op counter on $facet is $count, not $want"
13956         fi
13957 }
13958
13959 test_133a() {
13960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13961         remote_ost_nodsh && skip "remote OST with nodsh"
13962         remote_mds_nodsh && skip "remote MDS with nodsh"
13963         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13964                 skip_env "MDS doesn't support rename stats"
13965
13966         local testdir=$DIR/${tdir}/stats_testdir
13967
13968         mkdir -p $DIR/${tdir}
13969
13970         # clear stats.
13971         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13972         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13973
13974         # verify mdt stats first.
13975         mkdir ${testdir} || error "mkdir failed"
13976         check_stats $SINGLEMDS "mkdir" 1
13977         touch ${testdir}/${tfile} || error "touch failed"
13978         check_stats $SINGLEMDS "open" 1
13979         check_stats $SINGLEMDS "close" 1
13980         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13981                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13982                 check_stats $SINGLEMDS "mknod" 2
13983         }
13984         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13985         check_stats $SINGLEMDS "unlink" 1
13986         rm -f ${testdir}/${tfile} || error "file remove failed"
13987         check_stats $SINGLEMDS "unlink" 2
13988
13989         # remove working dir and check mdt stats again.
13990         rmdir ${testdir} || error "rmdir failed"
13991         check_stats $SINGLEMDS "rmdir" 1
13992
13993         local testdir1=$DIR/${tdir}/stats_testdir1
13994         mkdir -p ${testdir}
13995         mkdir -p ${testdir1}
13996         touch ${testdir1}/test1
13997         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13998         check_stats $SINGLEMDS "crossdir_rename" 1
13999
14000         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14001         check_stats $SINGLEMDS "samedir_rename" 1
14002
14003         rm -rf $DIR/${tdir}
14004 }
14005 run_test 133a "Verifying MDT stats ========================================"
14006
14007 test_133b() {
14008         local res
14009
14010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14011         remote_ost_nodsh && skip "remote OST with nodsh"
14012         remote_mds_nodsh && skip "remote MDS with nodsh"
14013
14014         local testdir=$DIR/${tdir}/stats_testdir
14015
14016         mkdir -p ${testdir} || error "mkdir failed"
14017         touch ${testdir}/${tfile} || error "touch failed"
14018         cancel_lru_locks mdc
14019
14020         # clear stats.
14021         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14022         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14023
14024         # extra mdt stats verification.
14025         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14026         check_stats $SINGLEMDS "setattr" 1
14027         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14028         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14029         then            # LU-1740
14030                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14031                 check_stats $SINGLEMDS "getattr" 1
14032         fi
14033         rm -rf $DIR/${tdir}
14034
14035         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14036         # so the check below is not reliable
14037         [ $MDSCOUNT -eq 1 ] || return 0
14038
14039         # Sleep to avoid a cached response.
14040         #define OBD_STATFS_CACHE_SECONDS 1
14041         sleep 2
14042         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14043         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14044         $LFS df || error "lfs failed"
14045         check_stats $SINGLEMDS "statfs" 1
14046
14047         # check aggregated statfs (LU-10018)
14048         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14049                 return 0
14050         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14051                 return 0
14052         sleep 2
14053         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14054         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14055         df $DIR
14056         check_stats $SINGLEMDS "statfs" 1
14057
14058         # We want to check that the client didn't send OST_STATFS to
14059         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14060         # extra care is needed here.
14061         if remote_mds; then
14062                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14063                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14064
14065                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14066                 [ "$res" ] && error "OST got STATFS"
14067         fi
14068
14069         return 0
14070 }
14071 run_test 133b "Verifying extra MDT stats =================================="
14072
14073 test_133c() {
14074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14075         remote_ost_nodsh && skip "remote OST with nodsh"
14076         remote_mds_nodsh && skip "remote MDS with nodsh"
14077
14078         local testdir=$DIR/$tdir/stats_testdir
14079
14080         test_mkdir -p $testdir
14081
14082         # verify obdfilter stats.
14083         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14084         sync
14085         cancel_lru_locks osc
14086         wait_delete_completed
14087
14088         # clear stats.
14089         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14090         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14091
14092         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14093                 error "dd failed"
14094         sync
14095         cancel_lru_locks osc
14096         check_stats ost1 "write" 1
14097
14098         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14099         check_stats ost1 "read" 1
14100
14101         > $testdir/$tfile || error "truncate failed"
14102         check_stats ost1 "punch" 1
14103
14104         rm -f $testdir/$tfile || error "file remove failed"
14105         wait_delete_completed
14106         check_stats ost1 "destroy" 1
14107
14108         rm -rf $DIR/$tdir
14109 }
14110 run_test 133c "Verifying OST stats ========================================"
14111
14112 order_2() {
14113         local value=$1
14114         local orig=$value
14115         local order=1
14116
14117         while [ $value -ge 2 ]; do
14118                 order=$((order*2))
14119                 value=$((value/2))
14120         done
14121
14122         if [ $orig -gt $order ]; then
14123                 order=$((order*2))
14124         fi
14125         echo $order
14126 }
14127
14128 size_in_KMGT() {
14129     local value=$1
14130     local size=('K' 'M' 'G' 'T');
14131     local i=0
14132     local size_string=$value
14133
14134     while [ $value -ge 1024 ]; do
14135         if [ $i -gt 3 ]; then
14136             #T is the biggest unit we get here, if that is bigger,
14137             #just return XXXT
14138             size_string=${value}T
14139             break
14140         fi
14141         value=$((value >> 10))
14142         if [ $value -lt 1024 ]; then
14143             size_string=${value}${size[$i]}
14144             break
14145         fi
14146         i=$((i + 1))
14147     done
14148
14149     echo $size_string
14150 }
14151
14152 get_rename_size() {
14153         local size=$1
14154         local context=${2:-.}
14155         local sample=$(do_facet $SINGLEMDS $LCTL \
14156                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14157                 grep -A1 $context |
14158                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14159         echo $sample
14160 }
14161
14162 test_133d() {
14163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14164         remote_ost_nodsh && skip "remote OST with nodsh"
14165         remote_mds_nodsh && skip "remote MDS with nodsh"
14166         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14167                 skip_env "MDS doesn't support rename stats"
14168
14169         local testdir1=$DIR/${tdir}/stats_testdir1
14170         local testdir2=$DIR/${tdir}/stats_testdir2
14171         mkdir -p $DIR/${tdir}
14172
14173         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14174
14175         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14176         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14177
14178         createmany -o $testdir1/test 512 || error "createmany failed"
14179
14180         # check samedir rename size
14181         mv ${testdir1}/test0 ${testdir1}/test_0
14182
14183         local testdir1_size=$(ls -l $DIR/${tdir} |
14184                 awk '/stats_testdir1/ {print $5}')
14185         local testdir2_size=$(ls -l $DIR/${tdir} |
14186                 awk '/stats_testdir2/ {print $5}')
14187
14188         testdir1_size=$(order_2 $testdir1_size)
14189         testdir2_size=$(order_2 $testdir2_size)
14190
14191         testdir1_size=$(size_in_KMGT $testdir1_size)
14192         testdir2_size=$(size_in_KMGT $testdir2_size)
14193
14194         echo "source rename dir size: ${testdir1_size}"
14195         echo "target rename dir size: ${testdir2_size}"
14196
14197         local cmd="do_facet $SINGLEMDS $LCTL "
14198         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14199
14200         eval $cmd || error "$cmd failed"
14201         local samedir=$($cmd | grep 'same_dir')
14202         local same_sample=$(get_rename_size $testdir1_size)
14203         [ -z "$samedir" ] && error "samedir_rename_size count error"
14204         [[ $same_sample -eq 1 ]] ||
14205                 error "samedir_rename_size error $same_sample"
14206         echo "Check same dir rename stats success"
14207
14208         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14209
14210         # check crossdir rename size
14211         mv ${testdir1}/test_0 ${testdir2}/test_0
14212
14213         testdir1_size=$(ls -l $DIR/${tdir} |
14214                 awk '/stats_testdir1/ {print $5}')
14215         testdir2_size=$(ls -l $DIR/${tdir} |
14216                 awk '/stats_testdir2/ {print $5}')
14217
14218         testdir1_size=$(order_2 $testdir1_size)
14219         testdir2_size=$(order_2 $testdir2_size)
14220
14221         testdir1_size=$(size_in_KMGT $testdir1_size)
14222         testdir2_size=$(size_in_KMGT $testdir2_size)
14223
14224         echo "source rename dir size: ${testdir1_size}"
14225         echo "target rename dir size: ${testdir2_size}"
14226
14227         eval $cmd || error "$cmd failed"
14228         local crossdir=$($cmd | grep 'crossdir')
14229         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14230         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14231         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14232         [[ $src_sample -eq 1 ]] ||
14233                 error "crossdir_rename_size error $src_sample"
14234         [[ $tgt_sample -eq 1 ]] ||
14235                 error "crossdir_rename_size error $tgt_sample"
14236         echo "Check cross dir rename stats success"
14237         rm -rf $DIR/${tdir}
14238 }
14239 run_test 133d "Verifying rename_stats ========================================"
14240
14241 test_133e() {
14242         remote_mds_nodsh && skip "remote MDS with nodsh"
14243         remote_ost_nodsh && skip "remote OST with nodsh"
14244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14245
14246         local testdir=$DIR/${tdir}/stats_testdir
14247         local ctr f0 f1 bs=32768 count=42 sum
14248
14249         mkdir -p ${testdir} || error "mkdir failed"
14250
14251         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14252
14253         for ctr in {write,read}_bytes; do
14254                 sync
14255                 cancel_lru_locks osc
14256
14257                 do_facet ost1 $LCTL set_param -n \
14258                         "obdfilter.*.exports.clear=clear"
14259
14260                 if [ $ctr = write_bytes ]; then
14261                         f0=/dev/zero
14262                         f1=${testdir}/${tfile}
14263                 else
14264                         f0=${testdir}/${tfile}
14265                         f1=/dev/null
14266                 fi
14267
14268                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14269                         error "dd failed"
14270                 sync
14271                 cancel_lru_locks osc
14272
14273                 sum=$(do_facet ost1 $LCTL get_param \
14274                         "obdfilter.*.exports.*.stats" |
14275                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14276                                 $1 == ctr { sum += $7 }
14277                                 END { printf("%0.0f", sum) }')
14278
14279                 if ((sum != bs * count)); then
14280                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14281                 fi
14282         done
14283
14284         rm -rf $DIR/${tdir}
14285 }
14286 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14287
14288 test_133f() {
14289         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14290                 skip "too old lustre for get_param -R ($facet_ver)"
14291
14292         # verifying readability.
14293         $LCTL get_param -R '*' &> /dev/null
14294
14295         # Verifing writability with badarea_io.
14296         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14297         local skipped_params='force_lbug|changelog_mask|daemon_file'
14298         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14299                 egrep -v "$skipped_params" |
14300                 xargs -n 1 find $proc_dirs -name |
14301                 xargs -n 1 badarea_io ||
14302                 error "client badarea_io failed"
14303
14304         # remount the FS in case writes/reads /proc break the FS
14305         cleanup || error "failed to unmount"
14306         setup || error "failed to setup"
14307 }
14308 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14309
14310 test_133g() {
14311         remote_mds_nodsh && skip "remote MDS with nodsh"
14312         remote_ost_nodsh && skip "remote OST with nodsh"
14313
14314         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14315         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14316         local facet
14317         for facet in mds1 ost1; do
14318                 local facet_ver=$(lustre_version_code $facet)
14319                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14320                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14321                 else
14322                         log "$facet: too old lustre for get_param -R"
14323                 fi
14324                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14325                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14326                                 tr -d = | egrep -v $skipped_params |
14327                                 xargs -n 1 find $proc_dirs -name |
14328                                 xargs -n 1 badarea_io" ||
14329                                         error "$facet badarea_io failed"
14330                 else
14331                         skip_noexit "$facet: too old lustre for get_param -R"
14332                 fi
14333         done
14334
14335         # remount the FS in case writes/reads /proc break the FS
14336         cleanup || error "failed to unmount"
14337         setup || error "failed to setup"
14338 }
14339 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14340
14341 test_133h() {
14342         remote_mds_nodsh && skip "remote MDS with nodsh"
14343         remote_ost_nodsh && skip "remote OST with nodsh"
14344         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14345                 skip "Need MDS version at least 2.9.54"
14346
14347         local facet
14348         for facet in client mds1 ost1; do
14349                 # Get the list of files that are missing the terminating newline
14350                 local plist=$(do_facet $facet
14351                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14352                 local ent
14353                 for ent in $plist; do
14354                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14355                                 awk -v FS='\v' -v RS='\v\v' \
14356                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14357                                         print FILENAME}'" 2>/dev/null)
14358                         [ -z $missing ] || {
14359                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14360                                 error "file does not end with newline: $facet-$ent"
14361                         }
14362                 done
14363         done
14364 }
14365 run_test 133h "Proc files should end with newlines"
14366
14367 test_134a() {
14368         remote_mds_nodsh && skip "remote MDS with nodsh"
14369         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14370                 skip "Need MDS version at least 2.7.54"
14371
14372         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14373         cancel_lru_locks mdc
14374
14375         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14376         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14377         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14378
14379         local nr=1000
14380         createmany -o $DIR/$tdir/f $nr ||
14381                 error "failed to create $nr files in $DIR/$tdir"
14382         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14383
14384         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14385         do_facet mds1 $LCTL set_param fail_loc=0x327
14386         do_facet mds1 $LCTL set_param fail_val=500
14387         touch $DIR/$tdir/m
14388
14389         echo "sleep 10 seconds ..."
14390         sleep 10
14391         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14392
14393         do_facet mds1 $LCTL set_param fail_loc=0
14394         do_facet mds1 $LCTL set_param fail_val=0
14395         [ $lck_cnt -lt $unused ] ||
14396                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14397
14398         rm $DIR/$tdir/m
14399         unlinkmany $DIR/$tdir/f $nr
14400 }
14401 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14402
14403 test_134b() {
14404         remote_mds_nodsh && skip "remote MDS with nodsh"
14405         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14406                 skip "Need MDS version at least 2.7.54"
14407
14408         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14409         cancel_lru_locks mdc
14410
14411         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14412                         ldlm.lock_reclaim_threshold_mb)
14413         # disable reclaim temporarily
14414         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14415
14416         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14417         do_facet mds1 $LCTL set_param fail_loc=0x328
14418         do_facet mds1 $LCTL set_param fail_val=500
14419
14420         $LCTL set_param debug=+trace
14421
14422         local nr=600
14423         createmany -o $DIR/$tdir/f $nr &
14424         local create_pid=$!
14425
14426         echo "Sleep $TIMEOUT seconds ..."
14427         sleep $TIMEOUT
14428         if ! ps -p $create_pid  > /dev/null 2>&1; then
14429                 do_facet mds1 $LCTL set_param fail_loc=0
14430                 do_facet mds1 $LCTL set_param fail_val=0
14431                 do_facet mds1 $LCTL set_param \
14432                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14433                 error "createmany finished incorrectly!"
14434         fi
14435         do_facet mds1 $LCTL set_param fail_loc=0
14436         do_facet mds1 $LCTL set_param fail_val=0
14437         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14438         wait $create_pid || return 1
14439
14440         unlinkmany $DIR/$tdir/f $nr
14441 }
14442 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14443
14444 test_135() {
14445         remote_mds_nodsh && skip "remote MDS with nodsh"
14446         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14447                 skip "Need MDS version at least 2.13.50"
14448         local fname
14449
14450         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14451
14452 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14453         #set only one record at plain llog
14454         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14455
14456         #fill already existed plain llog each 64767
14457         #wrapping whole catalog
14458         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14459
14460         createmany -o $DIR/$tdir/$tfile_ 64700
14461         for (( i = 0; i < 64700; i = i + 2 ))
14462         do
14463                 rm $DIR/$tdir/$tfile_$i &
14464                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14465                 local pid=$!
14466                 wait $pid
14467         done
14468
14469         #waiting osp synchronization
14470         wait_delete_completed
14471 }
14472 run_test 135 "Race catalog processing"
14473
14474 test_136() {
14475         remote_mds_nodsh && skip "remote MDS with nodsh"
14476         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14477                 skip "Need MDS version at least 2.13.50"
14478         local fname
14479
14480         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14481         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14482         #set only one record at plain llog
14483 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14484         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14485
14486         #fill already existed 2 plain llogs each 64767
14487         #wrapping whole catalog
14488         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14489         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14490         wait_delete_completed
14491
14492         createmany -o $DIR/$tdir/$tfile_ 10
14493         sleep 25
14494
14495         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14496         for (( i = 0; i < 10; i = i + 3 ))
14497         do
14498                 rm $DIR/$tdir/$tfile_$i &
14499                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14500                 local pid=$!
14501                 wait $pid
14502                 sleep 7
14503                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14504         done
14505
14506         #waiting osp synchronization
14507         wait_delete_completed
14508 }
14509 run_test 136 "Race catalog processing 2"
14510
14511 test_140() { #bug-17379
14512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14513
14514         test_mkdir $DIR/$tdir
14515         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14516         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14517
14518         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14519         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14520         local i=0
14521         while i=$((i + 1)); do
14522                 test_mkdir $i
14523                 cd $i || error "Changing to $i"
14524                 ln -s ../stat stat || error "Creating stat symlink"
14525                 # Read the symlink until ELOOP present,
14526                 # not LBUGing the system is considered success,
14527                 # we didn't overrun the stack.
14528                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14529                 if [ $ret -ne 0 ]; then
14530                         if [ $ret -eq 40 ]; then
14531                                 break  # -ELOOP
14532                         else
14533                                 error "Open stat symlink"
14534                                         return
14535                         fi
14536                 fi
14537         done
14538         i=$((i - 1))
14539         echo "The symlink depth = $i"
14540         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14541                 error "Invalid symlink depth"
14542
14543         # Test recursive symlink
14544         ln -s symlink_self symlink_self
14545         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14546         echo "open symlink_self returns $ret"
14547         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14548 }
14549 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14550
14551 test_150a() {
14552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14553
14554         local TF="$TMP/$tfile"
14555
14556         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14557         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14558         cp $TF $DIR/$tfile
14559         cancel_lru_locks $OSC
14560         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14561         remount_client $MOUNT
14562         df -P $MOUNT
14563         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14564
14565         $TRUNCATE $TF 6000
14566         $TRUNCATE $DIR/$tfile 6000
14567         cancel_lru_locks $OSC
14568         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14569
14570         echo "12345" >>$TF
14571         echo "12345" >>$DIR/$tfile
14572         cancel_lru_locks $OSC
14573         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14574
14575         echo "12345" >>$TF
14576         echo "12345" >>$DIR/$tfile
14577         cancel_lru_locks $OSC
14578         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14579 }
14580 run_test 150a "truncate/append tests"
14581
14582 test_150b() {
14583         check_set_fallocate_or_skip
14584
14585         touch $DIR/$tfile
14586         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14587         check_fallocate $DIR/$tfile || error "fallocate failed"
14588 }
14589 run_test 150b "Verify fallocate (prealloc) functionality"
14590
14591 test_150bb() {
14592         check_set_fallocate_or_skip
14593
14594         touch $DIR/$tfile
14595         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14596         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14597         > $DIR/$tfile
14598         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14599         # precomputed md5sum for 20MB of zeroes
14600         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14601         local sum=($(md5sum $DIR/$tfile))
14602
14603         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14604
14605         check_set_fallocate 1
14606
14607         > $DIR/$tfile
14608         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14609         sum=($(md5sum $DIR/$tfile))
14610
14611         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14612 }
14613 run_test 150bb "Verify fallocate modes both zero space"
14614
14615 test_150c() {
14616         check_set_fallocate_or_skip
14617         local striping="-c2"
14618
14619         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14620         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14621         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14622         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14623         local want=$((OSTCOUNT * 1048576))
14624
14625         # Must allocate all requested space, not more than 5% extra
14626         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14627                 error "bytes $bytes is not $want"
14628
14629         rm -f $DIR/$tfile
14630
14631         echo "verify fallocate on PFL file"
14632
14633         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14634
14635         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14636                 error "Create $DIR/$tfile failed"
14637         fallocate -l $((1048576 * 512)) $DIR/$tfile ||
14638                         error "fallocate failed"
14639         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14640         want=$((512 * 1048576))
14641
14642         # Must allocate all requested space, not more than 5% extra
14643         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14644                 error "bytes $bytes is not $want"
14645 }
14646 run_test 150c "Verify fallocate Size and Blocks"
14647
14648 test_150d() {
14649         check_set_fallocate_or_skip
14650         local striping="-c2"
14651
14652         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14653
14654         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14655         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14656                 error "setstripe failed"
14657         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14658         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14659         local want=$((OSTCOUNT * 1048576))
14660
14661         # Must allocate all requested space, not more than 5% extra
14662         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14663                 error "bytes $bytes is not $want"
14664 }
14665 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14666
14667 test_150e() {
14668         check_set_fallocate_or_skip
14669
14670         echo "df before:"
14671         $LFS df
14672         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14673         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14674                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14675
14676         # Find OST with Minimum Size
14677         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14678                        sort -un | head -1)
14679
14680         # Get 100MB per OST of the available space to reduce run time
14681         # else 60% of the available space if we are running SLOW tests
14682         if [ $SLOW == "no" ]; then
14683                 local space=$((1024 * 100 * OSTCOUNT))
14684         else
14685                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14686         fi
14687
14688         fallocate -l${space}k $DIR/$tfile ||
14689                 error "fallocate ${space}k $DIR/$tfile failed"
14690         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14691
14692         # get size immediately after fallocate. This should be correctly
14693         # updated
14694         local size=$(stat -c '%s' $DIR/$tfile)
14695         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14696
14697         # Sleep for a while for statfs to get updated. And not pull from cache.
14698         sleep 2
14699
14700         echo "df after fallocate:"
14701         $LFS df
14702
14703         (( size / 1024 == space )) || error "size $size != requested $space"
14704         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14705                 error "used $used < space $space"
14706
14707         rm $DIR/$tfile || error "rm failed"
14708         sync
14709         wait_delete_completed
14710
14711         echo "df after unlink:"
14712         $LFS df
14713 }
14714 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14715
14716 test_150f() {
14717         local size
14718         local blocks
14719         local want_size_before=20480 # in bytes
14720         local want_blocks_before=40 # 512 sized blocks
14721         local want_blocks_after=24  # 512 sized blocks
14722         local length=$(((want_blocks_before - want_blocks_after) * 512))
14723
14724         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14725                 skip "need at least 2.14.0 for fallocate punch"
14726
14727         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14728                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14729         fi
14730
14731         check_set_fallocate_or_skip
14732         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14733
14734         [[ "x$DOM" == "xyes" ]] &&
14735                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14736
14737         echo "Verify fallocate punch: Range within the file range"
14738         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14739                 error "dd failed for bs 4096 and count 5"
14740
14741         # Call fallocate with punch range which is within the file range
14742         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
14743                 error "fallocate failed: offset 4096 and length $length"
14744         # client must see changes immediately after fallocate
14745         size=$(stat -c '%s' $DIR/$tfile)
14746         blocks=$(stat -c '%b' $DIR/$tfile)
14747
14748         # Verify punch worked.
14749         (( blocks == want_blocks_after )) ||
14750                 error "punch failed: blocks $blocks != $want_blocks_after"
14751
14752         (( size == want_size_before )) ||
14753                 error "punch failed: size $size != $want_size_before"
14754
14755         # Verify there is hole in file
14756         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14757         # precomputed md5sum
14758         local expect="4a9a834a2db02452929c0a348273b4aa"
14759
14760         cksum=($(md5sum $DIR/$tfile))
14761         [[ "${cksum[0]}" == "$expect" ]] ||
14762                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14763
14764         # Start second sub-case for fallocate punch.
14765         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14766         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14767                 error "dd failed for bs 4096 and count 5"
14768
14769         # Punch range less than block size will have no change in block count
14770         want_blocks_after=40  # 512 sized blocks
14771
14772         # Punch overlaps two blocks and less than blocksize
14773         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
14774                 error "fallocate failed: offset 4000 length 3000"
14775         size=$(stat -c '%s' $DIR/$tfile)
14776         blocks=$(stat -c '%b' $DIR/$tfile)
14777
14778         # Verify punch worked.
14779         (( blocks == want_blocks_after )) ||
14780                 error "punch failed: blocks $blocks != $want_blocks_after"
14781
14782         (( size == want_size_before )) ||
14783                 error "punch failed: size $size != $want_size_before"
14784
14785         # Verify if range is really zero'ed out. We expect Zeros.
14786         # precomputed md5sum
14787         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14788         cksum=($(md5sum $DIR/$tfile))
14789         [[ "${cksum[0]}" == "$expect" ]] ||
14790                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14791 }
14792 run_test 150f "Verify fallocate punch functionality"
14793
14794 test_150g() {
14795         local space
14796         local size
14797         local blocks
14798         local blocks_after
14799         local size_after
14800         local BS=4096 # Block size in bytes
14801
14802         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14803                 skip "need at least 2.14.0 for fallocate punch"
14804
14805         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14806                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14807         fi
14808
14809         check_set_fallocate_or_skip
14810         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14811
14812         if [[ "x$DOM" == "xyes" ]]; then
14813                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
14814                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
14815         else
14816                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14817                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14818         fi
14819
14820         # Get 100MB per OST of the available space to reduce run time
14821         # else 60% of the available space if we are running SLOW tests
14822         if [ $SLOW == "no" ]; then
14823                 space=$((1024 * 100 * OSTCOUNT))
14824         else
14825                 # Find OST with Minimum Size
14826                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14827                         sort -un | head -1)
14828                 echo "min size OST: $space"
14829                 space=$(((space * 60)/100 * OSTCOUNT))
14830         fi
14831         # space in 1k units, round to 4k blocks
14832         local blkcount=$((space * 1024 / $BS))
14833
14834         echo "Verify fallocate punch: Very large Range"
14835         fallocate -l${space}k $DIR/$tfile ||
14836                 error "fallocate ${space}k $DIR/$tfile failed"
14837         # write 1M at the end, start and in the middle
14838         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14839                 error "dd failed: bs $BS count 256"
14840         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14841                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14842         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14843                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14844
14845         # Gather stats.
14846         size=$(stat -c '%s' $DIR/$tfile)
14847
14848         # gather punch length.
14849         local punch_size=$((size - (BS * 2)))
14850
14851         echo "punch_size = $punch_size"
14852         echo "size - punch_size: $((size - punch_size))"
14853         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14854
14855         # Call fallocate to punch all except 2 blocks. We leave the
14856         # first and the last block
14857         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14858         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14859                 error "fallocate failed: offset $BS length $punch_size"
14860
14861         size_after=$(stat -c '%s' $DIR/$tfile)
14862         blocks_after=$(stat -c '%b' $DIR/$tfile)
14863
14864         # Verify punch worked.
14865         # Size should be kept
14866         (( size == size_after )) ||
14867                 error "punch failed: size $size != $size_after"
14868
14869         # two 4k data blocks to remain plus possible 1 extra extent block
14870         (( blocks_after <= ((BS / 512) * 3) )) ||
14871                 error "too many blocks remains: $blocks_after"
14872
14873         # Verify that file has hole between the first and the last blocks
14874         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14875         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14876
14877         echo "Hole at [$hole_start, $hole_end)"
14878         (( hole_start == BS )) ||
14879                 error "no hole at offset $BS after punch"
14880
14881         (( hole_end == BS + punch_size )) ||
14882                 error "data at offset $hole_end < $((BS + punch_size))"
14883 }
14884 run_test 150g "Verify fallocate punch on large range"
14885
14886 #LU-2902 roc_hit was not able to read all values from lproc
14887 function roc_hit_init() {
14888         local list=$(comma_list $(osts_nodes))
14889         local dir=$DIR/$tdir-check
14890         local file=$dir/$tfile
14891         local BEFORE
14892         local AFTER
14893         local idx
14894
14895         test_mkdir $dir
14896         #use setstripe to do a write to every ost
14897         for i in $(seq 0 $((OSTCOUNT-1))); do
14898                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14899                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14900                 idx=$(printf %04x $i)
14901                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14902                         awk '$1 == "cache_access" {sum += $7}
14903                                 END { printf("%0.0f", sum) }')
14904
14905                 cancel_lru_locks osc
14906                 cat $file >/dev/null
14907
14908                 AFTER=$(get_osd_param $list *OST*$idx stats |
14909                         awk '$1 == "cache_access" {sum += $7}
14910                                 END { printf("%0.0f", sum) }')
14911
14912                 echo BEFORE:$BEFORE AFTER:$AFTER
14913                 if ! let "AFTER - BEFORE == 4"; then
14914                         rm -rf $dir
14915                         error "roc_hit is not safe to use"
14916                 fi
14917                 rm $file
14918         done
14919
14920         rm -rf $dir
14921 }
14922
14923 function roc_hit() {
14924         local list=$(comma_list $(osts_nodes))
14925         echo $(get_osd_param $list '' stats |
14926                 awk '$1 == "cache_hit" {sum += $7}
14927                         END { printf("%0.0f", sum) }')
14928 }
14929
14930 function set_cache() {
14931         local on=1
14932
14933         if [ "$2" == "off" ]; then
14934                 on=0;
14935         fi
14936         local list=$(comma_list $(osts_nodes))
14937         set_osd_param $list '' $1_cache_enable $on
14938
14939         cancel_lru_locks osc
14940 }
14941
14942 test_151() {
14943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14944         remote_ost_nodsh && skip "remote OST with nodsh"
14945
14946         local CPAGES=3
14947         local list=$(comma_list $(osts_nodes))
14948
14949         # check whether obdfilter is cache capable at all
14950         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14951                 skip "not cache-capable obdfilter"
14952         fi
14953
14954         # check cache is enabled on all obdfilters
14955         if get_osd_param $list '' read_cache_enable | grep 0; then
14956                 skip "oss cache is disabled"
14957         fi
14958
14959         set_osd_param $list '' writethrough_cache_enable 1
14960
14961         # check write cache is enabled on all obdfilters
14962         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14963                 skip "oss write cache is NOT enabled"
14964         fi
14965
14966         roc_hit_init
14967
14968         #define OBD_FAIL_OBD_NO_LRU  0x609
14969         do_nodes $list $LCTL set_param fail_loc=0x609
14970
14971         # pages should be in the case right after write
14972         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14973                 error "dd failed"
14974
14975         local BEFORE=$(roc_hit)
14976         cancel_lru_locks osc
14977         cat $DIR/$tfile >/dev/null
14978         local AFTER=$(roc_hit)
14979
14980         do_nodes $list $LCTL set_param fail_loc=0
14981
14982         if ! let "AFTER - BEFORE == CPAGES"; then
14983                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
14984         fi
14985
14986         cancel_lru_locks osc
14987         # invalidates OST cache
14988         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
14989         set_osd_param $list '' read_cache_enable 0
14990         cat $DIR/$tfile >/dev/null
14991
14992         # now data shouldn't be found in the cache
14993         BEFORE=$(roc_hit)
14994         cancel_lru_locks osc
14995         cat $DIR/$tfile >/dev/null
14996         AFTER=$(roc_hit)
14997         if let "AFTER - BEFORE != 0"; then
14998                 error "IN CACHE: before: $BEFORE, after: $AFTER"
14999         fi
15000
15001         set_osd_param $list '' read_cache_enable 1
15002         rm -f $DIR/$tfile
15003 }
15004 run_test 151 "test cache on oss and controls ==============================="
15005
15006 test_152() {
15007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15008
15009         local TF="$TMP/$tfile"
15010
15011         # simulate ENOMEM during write
15012 #define OBD_FAIL_OST_NOMEM      0x226
15013         lctl set_param fail_loc=0x80000226
15014         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15015         cp $TF $DIR/$tfile
15016         sync || error "sync failed"
15017         lctl set_param fail_loc=0
15018
15019         # discard client's cache
15020         cancel_lru_locks osc
15021
15022         # simulate ENOMEM during read
15023         lctl set_param fail_loc=0x80000226
15024         cmp $TF $DIR/$tfile || error "cmp failed"
15025         lctl set_param fail_loc=0
15026
15027         rm -f $TF
15028 }
15029 run_test 152 "test read/write with enomem ============================"
15030
15031 test_153() {
15032         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15033 }
15034 run_test 153 "test if fdatasync does not crash ======================="
15035
15036 dot_lustre_fid_permission_check() {
15037         local fid=$1
15038         local ffid=$MOUNT/.lustre/fid/$fid
15039         local test_dir=$2
15040
15041         echo "stat fid $fid"
15042         stat $ffid > /dev/null || error "stat $ffid failed."
15043         echo "touch fid $fid"
15044         touch $ffid || error "touch $ffid failed."
15045         echo "write to fid $fid"
15046         cat /etc/hosts > $ffid || error "write $ffid failed."
15047         echo "read fid $fid"
15048         diff /etc/hosts $ffid || error "read $ffid failed."
15049         echo "append write to fid $fid"
15050         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15051         echo "rename fid $fid"
15052         mv $ffid $test_dir/$tfile.1 &&
15053                 error "rename $ffid to $tfile.1 should fail."
15054         touch $test_dir/$tfile.1
15055         mv $test_dir/$tfile.1 $ffid &&
15056                 error "rename $tfile.1 to $ffid should fail."
15057         rm -f $test_dir/$tfile.1
15058         echo "truncate fid $fid"
15059         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15060         echo "link fid $fid"
15061         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15062         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15063                 echo "setfacl fid $fid"
15064                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
15065                 echo "getfacl fid $fid"
15066                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
15067         fi
15068         echo "unlink fid $fid"
15069         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15070         echo "mknod fid $fid"
15071         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15072
15073         fid=[0xf00000400:0x1:0x0]
15074         ffid=$MOUNT/.lustre/fid/$fid
15075
15076         echo "stat non-exist fid $fid"
15077         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15078         echo "write to non-exist fid $fid"
15079         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15080         echo "link new fid $fid"
15081         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15082
15083         mkdir -p $test_dir/$tdir
15084         touch $test_dir/$tdir/$tfile
15085         fid=$($LFS path2fid $test_dir/$tdir)
15086         rc=$?
15087         [ $rc -ne 0 ] &&
15088                 error "error: could not get fid for $test_dir/$dir/$tfile."
15089
15090         ffid=$MOUNT/.lustre/fid/$fid
15091
15092         echo "ls $fid"
15093         ls $ffid > /dev/null || error "ls $ffid failed."
15094         echo "touch $fid/$tfile.1"
15095         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15096
15097         echo "touch $MOUNT/.lustre/fid/$tfile"
15098         touch $MOUNT/.lustre/fid/$tfile && \
15099                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15100
15101         echo "setxattr to $MOUNT/.lustre/fid"
15102         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15103
15104         echo "listxattr for $MOUNT/.lustre/fid"
15105         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15106
15107         echo "delxattr from $MOUNT/.lustre/fid"
15108         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15109
15110         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15111         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15112                 error "touch invalid fid should fail."
15113
15114         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15115         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15116                 error "touch non-normal fid should fail."
15117
15118         echo "rename $tdir to $MOUNT/.lustre/fid"
15119         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15120                 error "rename to $MOUNT/.lustre/fid should fail."
15121
15122         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15123         then            # LU-3547
15124                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15125                 local new_obf_mode=777
15126
15127                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15128                 chmod $new_obf_mode $DIR/.lustre/fid ||
15129                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15130
15131                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15132                 [ $obf_mode -eq $new_obf_mode ] ||
15133                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15134
15135                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15136                 chmod $old_obf_mode $DIR/.lustre/fid ||
15137                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15138         fi
15139
15140         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15141         fid=$($LFS path2fid $test_dir/$tfile-2)
15142
15143         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15144         then # LU-5424
15145                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15146                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15147                         error "create lov data thru .lustre failed"
15148         fi
15149         echo "cp /etc/passwd $test_dir/$tfile-2"
15150         cp /etc/passwd $test_dir/$tfile-2 ||
15151                 error "copy to $test_dir/$tfile-2 failed."
15152         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15153         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15154                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15155
15156         rm -rf $test_dir/tfile.lnk
15157         rm -rf $test_dir/$tfile-2
15158 }
15159
15160 test_154A() {
15161         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15162                 skip "Need MDS version at least 2.4.1"
15163
15164         local tf=$DIR/$tfile
15165         touch $tf
15166
15167         local fid=$($LFS path2fid $tf)
15168         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15169
15170         # check that we get the same pathname back
15171         local rootpath
15172         local found
15173         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15174                 echo "$rootpath $fid"
15175                 found=$($LFS fid2path $rootpath "$fid")
15176                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15177                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15178         done
15179
15180         # check wrong root path format
15181         rootpath=$MOUNT"_wrong"
15182         found=$($LFS fid2path $rootpath "$fid")
15183         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15184 }
15185 run_test 154A "lfs path2fid and fid2path basic checks"
15186
15187 test_154B() {
15188         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15189                 skip "Need MDS version at least 2.4.1"
15190
15191         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15192         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15193         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15194         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15195
15196         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15197         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15198
15199         # check that we get the same pathname
15200         echo "PFID: $PFID, name: $name"
15201         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15202         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15203         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15204                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15205
15206         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15207 }
15208 run_test 154B "verify the ll_decode_linkea tool"
15209
15210 test_154a() {
15211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15212         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15213         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15214                 skip "Need MDS version at least 2.2.51"
15215         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15216
15217         cp /etc/hosts $DIR/$tfile
15218
15219         fid=$($LFS path2fid $DIR/$tfile)
15220         rc=$?
15221         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15222
15223         dot_lustre_fid_permission_check "$fid" $DIR ||
15224                 error "dot lustre permission check $fid failed"
15225
15226         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15227
15228         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15229
15230         touch $MOUNT/.lustre/file &&
15231                 error "creation is not allowed under .lustre"
15232
15233         mkdir $MOUNT/.lustre/dir &&
15234                 error "mkdir is not allowed under .lustre"
15235
15236         rm -rf $DIR/$tfile
15237 }
15238 run_test 154a "Open-by-FID"
15239
15240 test_154b() {
15241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15242         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15243         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15244         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15245                 skip "Need MDS version at least 2.2.51"
15246
15247         local remote_dir=$DIR/$tdir/remote_dir
15248         local MDTIDX=1
15249         local rc=0
15250
15251         mkdir -p $DIR/$tdir
15252         $LFS mkdir -i $MDTIDX $remote_dir ||
15253                 error "create remote directory failed"
15254
15255         cp /etc/hosts $remote_dir/$tfile
15256
15257         fid=$($LFS path2fid $remote_dir/$tfile)
15258         rc=$?
15259         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15260
15261         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15262                 error "dot lustre permission check $fid failed"
15263         rm -rf $DIR/$tdir
15264 }
15265 run_test 154b "Open-by-FID for remote directory"
15266
15267 test_154c() {
15268         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15269                 skip "Need MDS version at least 2.4.1"
15270
15271         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15272         local FID1=$($LFS path2fid $DIR/$tfile.1)
15273         local FID2=$($LFS path2fid $DIR/$tfile.2)
15274         local FID3=$($LFS path2fid $DIR/$tfile.3)
15275
15276         local N=1
15277         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15278                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15279                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15280                 local want=FID$N
15281                 [ "$FID" = "${!want}" ] ||
15282                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15283                 N=$((N + 1))
15284         done
15285
15286         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15287         do
15288                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15289                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15290                 N=$((N + 1))
15291         done
15292 }
15293 run_test 154c "lfs path2fid and fid2path multiple arguments"
15294
15295 test_154d() {
15296         remote_mds_nodsh && skip "remote MDS with nodsh"
15297         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15298                 skip "Need MDS version at least 2.5.53"
15299
15300         if remote_mds; then
15301                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15302         else
15303                 nid="0@lo"
15304         fi
15305         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15306         local fd
15307         local cmd
15308
15309         rm -f $DIR/$tfile
15310         touch $DIR/$tfile
15311
15312         local fid=$($LFS path2fid $DIR/$tfile)
15313         # Open the file
15314         fd=$(free_fd)
15315         cmd="exec $fd<$DIR/$tfile"
15316         eval $cmd
15317         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15318         echo "$fid_list" | grep "$fid"
15319         rc=$?
15320
15321         cmd="exec $fd>/dev/null"
15322         eval $cmd
15323         if [ $rc -ne 0 ]; then
15324                 error "FID $fid not found in open files list $fid_list"
15325         fi
15326 }
15327 run_test 154d "Verify open file fid"
15328
15329 test_154e()
15330 {
15331         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15332                 skip "Need MDS version at least 2.6.50"
15333
15334         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15335                 error ".lustre returned by readdir"
15336         fi
15337 }
15338 run_test 154e ".lustre is not returned by readdir"
15339
15340 test_154f() {
15341         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15342
15343         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15344         mkdir_on_mdt0 $DIR/$tdir
15345         # test dirs inherit from its stripe
15346         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15347         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15348         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15349         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15350         touch $DIR/f
15351
15352         # get fid of parents
15353         local FID0=$($LFS path2fid $DIR/$tdir)
15354         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15355         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15356         local FID3=$($LFS path2fid $DIR)
15357
15358         # check that path2fid --parents returns expected <parent_fid>/name
15359         # 1) test for a directory (single parent)
15360         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15361         [ "$parent" == "$FID0/foo1" ] ||
15362                 error "expected parent: $FID0/foo1, got: $parent"
15363
15364         # 2) test for a file with nlink > 1 (multiple parents)
15365         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15366         echo "$parent" | grep -F "$FID1/$tfile" ||
15367                 error "$FID1/$tfile not returned in parent list"
15368         echo "$parent" | grep -F "$FID2/link" ||
15369                 error "$FID2/link not returned in parent list"
15370
15371         # 3) get parent by fid
15372         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15373         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15374         echo "$parent" | grep -F "$FID1/$tfile" ||
15375                 error "$FID1/$tfile not returned in parent list (by fid)"
15376         echo "$parent" | grep -F "$FID2/link" ||
15377                 error "$FID2/link not returned in parent list (by fid)"
15378
15379         # 4) test for entry in root directory
15380         parent=$($LFS path2fid --parents $DIR/f)
15381         echo "$parent" | grep -F "$FID3/f" ||
15382                 error "$FID3/f not returned in parent list"
15383
15384         # 5) test it on root directory
15385         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15386                 error "$MOUNT should not have parents"
15387
15388         # enable xattr caching and check that linkea is correctly updated
15389         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15390         save_lustre_params client "llite.*.xattr_cache" > $save
15391         lctl set_param llite.*.xattr_cache 1
15392
15393         # 6.1) linkea update on rename
15394         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15395
15396         # get parents by fid
15397         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15398         # foo1 should no longer be returned in parent list
15399         echo "$parent" | grep -F "$FID1" &&
15400                 error "$FID1 should no longer be in parent list"
15401         # the new path should appear
15402         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15403                 error "$FID2/$tfile.moved is not in parent list"
15404
15405         # 6.2) linkea update on unlink
15406         rm -f $DIR/$tdir/foo2/link
15407         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15408         # foo2/link should no longer be returned in parent list
15409         echo "$parent" | grep -F "$FID2/link" &&
15410                 error "$FID2/link should no longer be in parent list"
15411         true
15412
15413         rm -f $DIR/f
15414         restore_lustre_params < $save
15415         rm -f $save
15416 }
15417 run_test 154f "get parent fids by reading link ea"
15418
15419 test_154g()
15420 {
15421         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15422         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15423            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15424                 skip "Need MDS version at least 2.6.92"
15425
15426         mkdir_on_mdt0 $DIR/$tdir
15427         llapi_fid_test -d $DIR/$tdir
15428 }
15429 run_test 154g "various llapi FID tests"
15430
15431 test_155_small_load() {
15432     local temp=$TMP/$tfile
15433     local file=$DIR/$tfile
15434
15435     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15436         error "dd of=$temp bs=6096 count=1 failed"
15437     cp $temp $file
15438     cancel_lru_locks $OSC
15439     cmp $temp $file || error "$temp $file differ"
15440
15441     $TRUNCATE $temp 6000
15442     $TRUNCATE $file 6000
15443     cmp $temp $file || error "$temp $file differ (truncate1)"
15444
15445     echo "12345" >>$temp
15446     echo "12345" >>$file
15447     cmp $temp $file || error "$temp $file differ (append1)"
15448
15449     echo "12345" >>$temp
15450     echo "12345" >>$file
15451     cmp $temp $file || error "$temp $file differ (append2)"
15452
15453     rm -f $temp $file
15454     true
15455 }
15456
15457 test_155_big_load() {
15458         remote_ost_nodsh && skip "remote OST with nodsh"
15459
15460         local temp=$TMP/$tfile
15461         local file=$DIR/$tfile
15462
15463         free_min_max
15464         local cache_size=$(do_facet ost$((MAXI+1)) \
15465                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15466         local large_file_size=$((cache_size * 2))
15467
15468         echo "OSS cache size: $cache_size KB"
15469         echo "Large file size: $large_file_size KB"
15470
15471         [ $MAXV -le $large_file_size ] &&
15472                 skip_env "max available OST size needs > $large_file_size KB"
15473
15474         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15475
15476         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15477                 error "dd of=$temp bs=$large_file_size count=1k failed"
15478         cp $temp $file
15479         ls -lh $temp $file
15480         cancel_lru_locks osc
15481         cmp $temp $file || error "$temp $file differ"
15482
15483         rm -f $temp $file
15484         true
15485 }
15486
15487 save_writethrough() {
15488         local facets=$(get_facets OST)
15489
15490         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15491 }
15492
15493 test_155a() {
15494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15495
15496         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15497
15498         save_writethrough $p
15499
15500         set_cache read on
15501         set_cache writethrough on
15502         test_155_small_load
15503         restore_lustre_params < $p
15504         rm -f $p
15505 }
15506 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15507
15508 test_155b() {
15509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15510
15511         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15512
15513         save_writethrough $p
15514
15515         set_cache read on
15516         set_cache writethrough off
15517         test_155_small_load
15518         restore_lustre_params < $p
15519         rm -f $p
15520 }
15521 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15522
15523 test_155c() {
15524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15525
15526         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15527
15528         save_writethrough $p
15529
15530         set_cache read off
15531         set_cache writethrough on
15532         test_155_small_load
15533         restore_lustre_params < $p
15534         rm -f $p
15535 }
15536 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15537
15538 test_155d() {
15539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15540
15541         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15542
15543         save_writethrough $p
15544
15545         set_cache read off
15546         set_cache writethrough off
15547         test_155_small_load
15548         restore_lustre_params < $p
15549         rm -f $p
15550 }
15551 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15552
15553 test_155e() {
15554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15555
15556         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15557
15558         save_writethrough $p
15559
15560         set_cache read on
15561         set_cache writethrough on
15562         test_155_big_load
15563         restore_lustre_params < $p
15564         rm -f $p
15565 }
15566 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15567
15568 test_155f() {
15569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15570
15571         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15572
15573         save_writethrough $p
15574
15575         set_cache read on
15576         set_cache writethrough off
15577         test_155_big_load
15578         restore_lustre_params < $p
15579         rm -f $p
15580 }
15581 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15582
15583 test_155g() {
15584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15585
15586         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15587
15588         save_writethrough $p
15589
15590         set_cache read off
15591         set_cache writethrough on
15592         test_155_big_load
15593         restore_lustre_params < $p
15594         rm -f $p
15595 }
15596 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15597
15598 test_155h() {
15599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15600
15601         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15602
15603         save_writethrough $p
15604
15605         set_cache read off
15606         set_cache writethrough off
15607         test_155_big_load
15608         restore_lustre_params < $p
15609         rm -f $p
15610 }
15611 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15612
15613 test_156() {
15614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15615         remote_ost_nodsh && skip "remote OST with nodsh"
15616         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15617                 skip "stats not implemented on old servers"
15618         [ "$ost1_FSTYPE" = "zfs" ] &&
15619                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15620
15621         local CPAGES=3
15622         local BEFORE
15623         local AFTER
15624         local file="$DIR/$tfile"
15625         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15626
15627         save_writethrough $p
15628         roc_hit_init
15629
15630         log "Turn on read and write cache"
15631         set_cache read on
15632         set_cache writethrough on
15633
15634         log "Write data and read it back."
15635         log "Read should be satisfied from the cache."
15636         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15637         BEFORE=$(roc_hit)
15638         cancel_lru_locks osc
15639         cat $file >/dev/null
15640         AFTER=$(roc_hit)
15641         if ! let "AFTER - BEFORE == CPAGES"; then
15642                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15643         else
15644                 log "cache hits: before: $BEFORE, after: $AFTER"
15645         fi
15646
15647         log "Read again; it should be satisfied from the cache."
15648         BEFORE=$AFTER
15649         cancel_lru_locks osc
15650         cat $file >/dev/null
15651         AFTER=$(roc_hit)
15652         if ! let "AFTER - BEFORE == CPAGES"; then
15653                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15654         else
15655                 log "cache hits:: before: $BEFORE, after: $AFTER"
15656         fi
15657
15658         log "Turn off the read cache and turn on the write cache"
15659         set_cache read off
15660         set_cache writethrough on
15661
15662         log "Read again; it should be satisfied from the cache."
15663         BEFORE=$(roc_hit)
15664         cancel_lru_locks osc
15665         cat $file >/dev/null
15666         AFTER=$(roc_hit)
15667         if ! let "AFTER - BEFORE == CPAGES"; then
15668                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15669         else
15670                 log "cache hits:: before: $BEFORE, after: $AFTER"
15671         fi
15672
15673         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15674                 # > 2.12.56 uses pagecache if cached
15675                 log "Read again; it should not be satisfied from the cache."
15676                 BEFORE=$AFTER
15677                 cancel_lru_locks osc
15678                 cat $file >/dev/null
15679                 AFTER=$(roc_hit)
15680                 if ! let "AFTER - BEFORE == 0"; then
15681                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15682                 else
15683                         log "cache hits:: before: $BEFORE, after: $AFTER"
15684                 fi
15685         fi
15686
15687         log "Write data and read it back."
15688         log "Read should be satisfied from the cache."
15689         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15690         BEFORE=$(roc_hit)
15691         cancel_lru_locks osc
15692         cat $file >/dev/null
15693         AFTER=$(roc_hit)
15694         if ! let "AFTER - BEFORE == CPAGES"; then
15695                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15696         else
15697                 log "cache hits:: before: $BEFORE, after: $AFTER"
15698         fi
15699
15700         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15701                 # > 2.12.56 uses pagecache if cached
15702                 log "Read again; it should not be satisfied from the cache."
15703                 BEFORE=$AFTER
15704                 cancel_lru_locks osc
15705                 cat $file >/dev/null
15706                 AFTER=$(roc_hit)
15707                 if ! let "AFTER - BEFORE == 0"; then
15708                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15709                 else
15710                         log "cache hits:: before: $BEFORE, after: $AFTER"
15711                 fi
15712         fi
15713
15714         log "Turn off read and write cache"
15715         set_cache read off
15716         set_cache writethrough off
15717
15718         log "Write data and read it back"
15719         log "It should not be satisfied from the cache."
15720         rm -f $file
15721         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15722         cancel_lru_locks osc
15723         BEFORE=$(roc_hit)
15724         cat $file >/dev/null
15725         AFTER=$(roc_hit)
15726         if ! let "AFTER - BEFORE == 0"; then
15727                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15728         else
15729                 log "cache hits:: before: $BEFORE, after: $AFTER"
15730         fi
15731
15732         log "Turn on the read cache and turn off the write cache"
15733         set_cache read on
15734         set_cache writethrough off
15735
15736         log "Write data and read it back"
15737         log "It should not be satisfied from the cache."
15738         rm -f $file
15739         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15740         BEFORE=$(roc_hit)
15741         cancel_lru_locks osc
15742         cat $file >/dev/null
15743         AFTER=$(roc_hit)
15744         if ! let "AFTER - BEFORE == 0"; then
15745                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15746         else
15747                 log "cache hits:: before: $BEFORE, after: $AFTER"
15748         fi
15749
15750         log "Read again; it should be satisfied from the cache."
15751         BEFORE=$(roc_hit)
15752         cancel_lru_locks osc
15753         cat $file >/dev/null
15754         AFTER=$(roc_hit)
15755         if ! let "AFTER - BEFORE == CPAGES"; then
15756                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15757         else
15758                 log "cache hits:: before: $BEFORE, after: $AFTER"
15759         fi
15760
15761         restore_lustre_params < $p
15762         rm -f $p $file
15763 }
15764 run_test 156 "Verification of tunables"
15765
15766 test_160a() {
15767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15768         remote_mds_nodsh && skip "remote MDS with nodsh"
15769         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15770                 skip "Need MDS version at least 2.2.0"
15771
15772         changelog_register || error "changelog_register failed"
15773         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15774         changelog_users $SINGLEMDS | grep -q $cl_user ||
15775                 error "User $cl_user not found in changelog_users"
15776
15777         mkdir_on_mdt0 $DIR/$tdir
15778
15779         # change something
15780         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15781         changelog_clear 0 || error "changelog_clear failed"
15782         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15783         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15784         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15785         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15786         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15787         rm $DIR/$tdir/pics/desktop.jpg
15788
15789         echo "verifying changelog mask"
15790         changelog_chmask "-MKDIR"
15791         changelog_chmask "-CLOSE"
15792
15793         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15794         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15795
15796         changelog_chmask "+MKDIR"
15797         changelog_chmask "+CLOSE"
15798
15799         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15800         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15801
15802         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15803         CLOSES=$(changelog_dump | grep -c "CLOSE")
15804         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15805         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15806
15807         # verify contents
15808         echo "verifying target fid"
15809         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15810         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15811         [ "$fidc" == "$fidf" ] ||
15812                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15813         echo "verifying parent fid"
15814         # The FID returned from the Changelog may be the directory shard on
15815         # a different MDT, and not the FID returned by path2fid on the parent.
15816         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15817         # since this is what will matter when recreating this file in the tree.
15818         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15819         local pathp=$($LFS fid2path $MOUNT "$fidp")
15820         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15821                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15822
15823         echo "getting records for $cl_user"
15824         changelog_users $SINGLEMDS
15825         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15826         local nclr=3
15827         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15828                 error "changelog_clear failed"
15829         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15830         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15831         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15832                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15833
15834         local min0_rec=$(changelog_users $SINGLEMDS |
15835                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15836         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15837                           awk '{ print $1; exit; }')
15838
15839         changelog_dump | tail -n 5
15840         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15841         [ $first_rec == $((min0_rec + 1)) ] ||
15842                 error "first index should be $min0_rec + 1 not $first_rec"
15843
15844         # LU-3446 changelog index reset on MDT restart
15845         local cur_rec1=$(changelog_users $SINGLEMDS |
15846                          awk '/^current.index:/ { print $NF }')
15847         changelog_clear 0 ||
15848                 error "clear all changelog records for $cl_user failed"
15849         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15850         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15851                 error "Fail to start $SINGLEMDS"
15852         local cur_rec2=$(changelog_users $SINGLEMDS |
15853                          awk '/^current.index:/ { print $NF }')
15854         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15855         [ $cur_rec1 == $cur_rec2 ] ||
15856                 error "current index should be $cur_rec1 not $cur_rec2"
15857
15858         echo "verifying users from this test are deregistered"
15859         changelog_deregister || error "changelog_deregister failed"
15860         changelog_users $SINGLEMDS | grep -q $cl_user &&
15861                 error "User '$cl_user' still in changelog_users"
15862
15863         # lctl get_param -n mdd.*.changelog_users
15864         # current_index: 144
15865         # ID    index (idle seconds)
15866         # cl3   144   (2) mask=<list>
15867         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15868                 # this is the normal case where all users were deregistered
15869                 # make sure no new records are added when no users are present
15870                 local last_rec1=$(changelog_users $SINGLEMDS |
15871                                   awk '/^current.index:/ { print $NF }')
15872                 touch $DIR/$tdir/chloe
15873                 local last_rec2=$(changelog_users $SINGLEMDS |
15874                                   awk '/^current.index:/ { print $NF }')
15875                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15876                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15877         else
15878                 # any changelog users must be leftovers from a previous test
15879                 changelog_users $SINGLEMDS
15880                 echo "other changelog users; can't verify off"
15881         fi
15882 }
15883 run_test 160a "changelog sanity"
15884
15885 test_160b() { # LU-3587
15886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15887         remote_mds_nodsh && skip "remote MDS with nodsh"
15888         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15889                 skip "Need MDS version at least 2.2.0"
15890
15891         changelog_register || error "changelog_register failed"
15892         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15893         changelog_users $SINGLEMDS | grep -q $cl_user ||
15894                 error "User '$cl_user' not found in changelog_users"
15895
15896         local longname1=$(str_repeat a 255)
15897         local longname2=$(str_repeat b 255)
15898
15899         cd $DIR
15900         echo "creating very long named file"
15901         touch $longname1 || error "create of '$longname1' failed"
15902         echo "renaming very long named file"
15903         mv $longname1 $longname2
15904
15905         changelog_dump | grep RENME | tail -n 5
15906         rm -f $longname2
15907 }
15908 run_test 160b "Verify that very long rename doesn't crash in changelog"
15909
15910 test_160c() {
15911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15912         remote_mds_nodsh && skip "remote MDS with nodsh"
15913
15914         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15915                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15916                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15917                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15918
15919         local rc=0
15920
15921         # Registration step
15922         changelog_register || error "changelog_register failed"
15923
15924         rm -rf $DIR/$tdir
15925         mkdir -p $DIR/$tdir
15926         $MCREATE $DIR/$tdir/foo_160c
15927         changelog_chmask "-TRUNC"
15928         $TRUNCATE $DIR/$tdir/foo_160c 200
15929         changelog_chmask "+TRUNC"
15930         $TRUNCATE $DIR/$tdir/foo_160c 199
15931         changelog_dump | tail -n 5
15932         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15933         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15934 }
15935 run_test 160c "verify that changelog log catch the truncate event"
15936
15937 test_160d() {
15938         remote_mds_nodsh && skip "remote MDS with nodsh"
15939         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15941         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15942                 skip "Need MDS version at least 2.7.60"
15943
15944         # Registration step
15945         changelog_register || error "changelog_register failed"
15946
15947         mkdir -p $DIR/$tdir/migrate_dir
15948         changelog_clear 0 || error "changelog_clear failed"
15949
15950         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15951         changelog_dump | tail -n 5
15952         local migrates=$(changelog_dump | grep -c "MIGRT")
15953         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15954 }
15955 run_test 160d "verify that changelog log catch the migrate event"
15956
15957 test_160e() {
15958         remote_mds_nodsh && skip "remote MDS with nodsh"
15959
15960         # Create a user
15961         changelog_register || error "changelog_register failed"
15962
15963         local MDT0=$(facet_svc $SINGLEMDS)
15964         local rc
15965
15966         # No user (expect fail)
15967         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
15968         rc=$?
15969         if [ $rc -eq 0 ]; then
15970                 error "Should fail without user"
15971         elif [ $rc -ne 4 ]; then
15972                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
15973         fi
15974
15975         # Delete a future user (expect fail)
15976         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
15977         rc=$?
15978         if [ $rc -eq 0 ]; then
15979                 error "Deleted non-existant user cl77"
15980         elif [ $rc -ne 2 ]; then
15981                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
15982         fi
15983
15984         # Clear to a bad index (1 billion should be safe)
15985         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
15986         rc=$?
15987
15988         if [ $rc -eq 0 ]; then
15989                 error "Successfully cleared to invalid CL index"
15990         elif [ $rc -ne 22 ]; then
15991                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
15992         fi
15993 }
15994 run_test 160e "changelog negative testing (should return errors)"
15995
15996 test_160f() {
15997         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15998         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15999                 skip "Need MDS version at least 2.10.56"
16000
16001         local mdts=$(comma_list $(mdts_nodes))
16002
16003         # Create a user
16004         changelog_register || error "first changelog_register failed"
16005         changelog_register || error "second changelog_register failed"
16006         local cl_users
16007         declare -A cl_user1
16008         declare -A cl_user2
16009         local user_rec1
16010         local user_rec2
16011         local i
16012
16013         # generate some changelog records to accumulate on each MDT
16014         # use all_char because created files should be evenly distributed
16015         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16016                 error "test_mkdir $tdir failed"
16017         log "$(date +%s): creating first files"
16018         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16019                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16020                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16021         done
16022
16023         # check changelogs have been generated
16024         local start=$SECONDS
16025         local idle_time=$((MDSCOUNT * 5 + 5))
16026         local nbcl=$(changelog_dump | wc -l)
16027         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16028
16029         for param in "changelog_max_idle_time=$idle_time" \
16030                      "changelog_gc=1" \
16031                      "changelog_min_gc_interval=2" \
16032                      "changelog_min_free_cat_entries=3"; do
16033                 local MDT0=$(facet_svc $SINGLEMDS)
16034                 local var="${param%=*}"
16035                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16036
16037                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16038                 do_nodes $mdts $LCTL set_param mdd.*.$param
16039         done
16040
16041         # force cl_user2 to be idle (1st part), but also cancel the
16042         # cl_user1 records so that it is not evicted later in the test.
16043         local sleep1=$((idle_time / 2))
16044         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16045         sleep $sleep1
16046
16047         # simulate changelog catalog almost full
16048         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16049         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16050
16051         for i in $(seq $MDSCOUNT); do
16052                 cl_users=(${CL_USERS[mds$i]})
16053                 cl_user1[mds$i]="${cl_users[0]}"
16054                 cl_user2[mds$i]="${cl_users[1]}"
16055
16056                 [ -n "${cl_user1[mds$i]}" ] ||
16057                         error "mds$i: no user registered"
16058                 [ -n "${cl_user2[mds$i]}" ] ||
16059                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16060
16061                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16062                 [ -n "$user_rec1" ] ||
16063                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16064                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16065                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16066                 [ -n "$user_rec2" ] ||
16067                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16068                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16069                      "$user_rec1 + 2 == $user_rec2"
16070                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16071                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16072                               "$user_rec1 + 2, but is $user_rec2"
16073                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16074                 [ -n "$user_rec2" ] ||
16075                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16076                 [ $user_rec1 == $user_rec2 ] ||
16077                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16078                               "$user_rec1, but is $user_rec2"
16079         done
16080
16081         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16082         local sleep2=$((idle_time - (SECONDS - start) + 1))
16083         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16084         sleep $sleep2
16085
16086         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16087         # cl_user1 should be OK because it recently processed records.
16088         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16089         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16090                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16091                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16092         done
16093
16094         # ensure gc thread is done
16095         for i in $(mdts_nodes); do
16096                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16097                         error "$i: GC-thread not done"
16098         done
16099
16100         local first_rec
16101         for (( i = 1; i <= MDSCOUNT; i++ )); do
16102                 # check cl_user1 still registered
16103                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16104                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16105                 # check cl_user2 unregistered
16106                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16107                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16108
16109                 # check changelogs are present and starting at $user_rec1 + 1
16110                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16111                 [ -n "$user_rec1" ] ||
16112                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16113                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16114                             awk '{ print $1; exit; }')
16115
16116                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16117                 [ $((user_rec1 + 1)) == $first_rec ] ||
16118                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16119         done
16120 }
16121 run_test 160f "changelog garbage collect (timestamped users)"
16122
16123 test_160g() {
16124         remote_mds_nodsh && skip "remote MDS with nodsh"
16125         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16126                 skip "Need MDS version at least 2.14.55"
16127
16128         local mdts=$(comma_list $(mdts_nodes))
16129
16130         # Create a user
16131         changelog_register || error "first changelog_register failed"
16132         changelog_register || error "second changelog_register failed"
16133         local cl_users
16134         declare -A cl_user1
16135         declare -A cl_user2
16136         local user_rec1
16137         local user_rec2
16138         local i
16139
16140         # generate some changelog records to accumulate on each MDT
16141         # use all_char because created files should be evenly distributed
16142         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16143                 error "test_mkdir $tdir failed"
16144         for ((i = 0; i < MDSCOUNT; i++)); do
16145                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16146                         error "create $DIR/$tdir/d$i.1 failed"
16147         done
16148
16149         # check changelogs have been generated
16150         local nbcl=$(changelog_dump | wc -l)
16151         (( $nbcl > 0 )) || error "no changelogs found"
16152
16153         # reduce the max_idle_indexes value to make sure we exceed it
16154         for param in "changelog_max_idle_indexes=2" \
16155                      "changelog_gc=1" \
16156                      "changelog_min_gc_interval=2"; do
16157                 local MDT0=$(facet_svc $SINGLEMDS)
16158                 local var="${param%=*}"
16159                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16160
16161                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16162                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16163                         error "unable to set mdd.*.$param"
16164         done
16165
16166         local start=$SECONDS
16167         for i in $(seq $MDSCOUNT); do
16168                 cl_users=(${CL_USERS[mds$i]})
16169                 cl_user1[mds$i]="${cl_users[0]}"
16170                 cl_user2[mds$i]="${cl_users[1]}"
16171
16172                 [ -n "${cl_user1[mds$i]}" ] ||
16173                         error "mds$i: user1 is not registered"
16174                 [ -n "${cl_user2[mds$i]}" ] ||
16175                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16176
16177                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16178                 [ -n "$user_rec1" ] ||
16179                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16180                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16181                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16182                 [ -n "$user_rec2" ] ||
16183                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16184                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16185                      "$user_rec1 + 2 == $user_rec2"
16186                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16187                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16188                               "expected $user_rec1 + 2, but is $user_rec2"
16189                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16190                 [ -n "$user_rec2" ] ||
16191                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16192                 [ $user_rec1 == $user_rec2 ] ||
16193                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16194                               "expected $user_rec1, but is $user_rec2"
16195         done
16196
16197         # ensure we are past the previous changelog_min_gc_interval set above
16198         local sleep2=$((start + 2 - SECONDS))
16199         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16200         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16201         # cl_user1 should be OK because it recently processed records.
16202         for ((i = 0; i < MDSCOUNT; i++)); do
16203                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16204                         error "create $DIR/$tdir/d$i.3 failed"
16205         done
16206
16207         # ensure gc thread is done
16208         for i in $(mdts_nodes); do
16209                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16210                         error "$i: GC-thread not done"
16211         done
16212
16213         local first_rec
16214         for (( i = 1; i <= MDSCOUNT; i++ )); do
16215                 # check cl_user1 still registered
16216                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16217                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16218                 # check cl_user2 unregistered
16219                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16220                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16221
16222                 # check changelogs are present and starting at $user_rec1 + 1
16223                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16224                 [ -n "$user_rec1" ] ||
16225                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16226                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16227                             awk '{ print $1; exit; }')
16228
16229                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16230                 [ $((user_rec1 + 1)) == $first_rec ] ||
16231                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16232         done
16233 }
16234 run_test 160g "changelog garbage collect on idle records"
16235
16236 test_160h() {
16237         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16238         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16239                 skip "Need MDS version at least 2.10.56"
16240
16241         local mdts=$(comma_list $(mdts_nodes))
16242
16243         # Create a user
16244         changelog_register || error "first changelog_register failed"
16245         changelog_register || error "second changelog_register failed"
16246         local cl_users
16247         declare -A cl_user1
16248         declare -A cl_user2
16249         local user_rec1
16250         local user_rec2
16251         local i
16252
16253         # generate some changelog records to accumulate on each MDT
16254         # use all_char because created files should be evenly distributed
16255         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16256                 error "test_mkdir $tdir failed"
16257         for ((i = 0; i < MDSCOUNT; i++)); do
16258                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16259                         error "create $DIR/$tdir/d$i.1 failed"
16260         done
16261
16262         # check changelogs have been generated
16263         local nbcl=$(changelog_dump | wc -l)
16264         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16265
16266         for param in "changelog_max_idle_time=10" \
16267                      "changelog_gc=1" \
16268                      "changelog_min_gc_interval=2"; do
16269                 local MDT0=$(facet_svc $SINGLEMDS)
16270                 local var="${param%=*}"
16271                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16272
16273                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16274                 do_nodes $mdts $LCTL set_param mdd.*.$param
16275         done
16276
16277         # force cl_user2 to be idle (1st part)
16278         sleep 9
16279
16280         for i in $(seq $MDSCOUNT); do
16281                 cl_users=(${CL_USERS[mds$i]})
16282                 cl_user1[mds$i]="${cl_users[0]}"
16283                 cl_user2[mds$i]="${cl_users[1]}"
16284
16285                 [ -n "${cl_user1[mds$i]}" ] ||
16286                         error "mds$i: no user registered"
16287                 [ -n "${cl_user2[mds$i]}" ] ||
16288                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16289
16290                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16291                 [ -n "$user_rec1" ] ||
16292                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16293                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16294                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16295                 [ -n "$user_rec2" ] ||
16296                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16297                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16298                      "$user_rec1 + 2 == $user_rec2"
16299                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16300                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16301                               "$user_rec1 + 2, but is $user_rec2"
16302                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16303                 [ -n "$user_rec2" ] ||
16304                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16305                 [ $user_rec1 == $user_rec2 ] ||
16306                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16307                               "$user_rec1, but is $user_rec2"
16308         done
16309
16310         # force cl_user2 to be idle (2nd part) and to reach
16311         # changelog_max_idle_time
16312         sleep 2
16313
16314         # force each GC-thread start and block then
16315         # one per MDT/MDD, set fail_val accordingly
16316         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16317         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16318
16319         # generate more changelogs to trigger fail_loc
16320         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16321                 error "create $DIR/$tdir/${tfile}bis failed"
16322
16323         # stop MDT to stop GC-thread, should be done in back-ground as it will
16324         # block waiting for the thread to be released and exit
16325         declare -A stop_pids
16326         for i in $(seq $MDSCOUNT); do
16327                 stop mds$i &
16328                 stop_pids[mds$i]=$!
16329         done
16330
16331         for i in $(mdts_nodes); do
16332                 local facet
16333                 local nb=0
16334                 local facets=$(facets_up_on_host $i)
16335
16336                 for facet in ${facets//,/ }; do
16337                         if [[ $facet == mds* ]]; then
16338                                 nb=$((nb + 1))
16339                         fi
16340                 done
16341                 # ensure each MDS's gc threads are still present and all in "R"
16342                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16343                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16344                         error "$i: expected $nb GC-thread"
16345                 wait_update $i \
16346                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16347                         "R" 20 ||
16348                         error "$i: GC-thread not found in R-state"
16349                 # check umounts of each MDT on MDS have reached kthread_stop()
16350                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16351                         error "$i: expected $nb umount"
16352                 wait_update $i \
16353                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16354                         error "$i: umount not found in D-state"
16355         done
16356
16357         # release all GC-threads
16358         do_nodes $mdts $LCTL set_param fail_loc=0
16359
16360         # wait for MDT stop to complete
16361         for i in $(seq $MDSCOUNT); do
16362                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16363         done
16364
16365         # XXX
16366         # may try to check if any orphan changelog records are present
16367         # via ldiskfs/zfs and llog_reader...
16368
16369         # re-start/mount MDTs
16370         for i in $(seq $MDSCOUNT); do
16371                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16372                         error "Fail to start mds$i"
16373         done
16374
16375         local first_rec
16376         for i in $(seq $MDSCOUNT); do
16377                 # check cl_user1 still registered
16378                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16379                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16380                 # check cl_user2 unregistered
16381                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16382                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16383
16384                 # check changelogs are present and starting at $user_rec1 + 1
16385                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16386                 [ -n "$user_rec1" ] ||
16387                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16388                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16389                             awk '{ print $1; exit; }')
16390
16391                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16392                 [ $((user_rec1 + 1)) == $first_rec ] ||
16393                         error "mds$i: first index should be $user_rec1 + 1, " \
16394                               "but is $first_rec"
16395         done
16396 }
16397 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16398               "during mount"
16399
16400 test_160i() {
16401
16402         local mdts=$(comma_list $(mdts_nodes))
16403
16404         changelog_register || error "first changelog_register failed"
16405
16406         # generate some changelog records to accumulate on each MDT
16407         # use all_char because created files should be evenly distributed
16408         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16409                 error "test_mkdir $tdir failed"
16410         for ((i = 0; i < MDSCOUNT; i++)); do
16411                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16412                         error "create $DIR/$tdir/d$i.1 failed"
16413         done
16414
16415         # check changelogs have been generated
16416         local nbcl=$(changelog_dump | wc -l)
16417         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16418
16419         # simulate race between register and unregister
16420         # XXX as fail_loc is set per-MDS, with DNE configs the race
16421         # simulation will only occur for one MDT per MDS and for the
16422         # others the normal race scenario will take place
16423         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16424         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16425         do_nodes $mdts $LCTL set_param fail_val=1
16426
16427         # unregister 1st user
16428         changelog_deregister &
16429         local pid1=$!
16430         # wait some time for deregister work to reach race rdv
16431         sleep 2
16432         # register 2nd user
16433         changelog_register || error "2nd user register failed"
16434
16435         wait $pid1 || error "1st user deregister failed"
16436
16437         local i
16438         local last_rec
16439         declare -A LAST_REC
16440         for i in $(seq $MDSCOUNT); do
16441                 if changelog_users mds$i | grep "^cl"; then
16442                         # make sure new records are added with one user present
16443                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16444                                           awk '/^current.index:/ { print $NF }')
16445                 else
16446                         error "mds$i has no user registered"
16447                 fi
16448         done
16449
16450         # generate more changelog records to accumulate on each MDT
16451         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16452                 error "create $DIR/$tdir/${tfile}bis failed"
16453
16454         for i in $(seq $MDSCOUNT); do
16455                 last_rec=$(changelog_users $SINGLEMDS |
16456                            awk '/^current.index:/ { print $NF }')
16457                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16458                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16459                         error "changelogs are off on mds$i"
16460         done
16461 }
16462 run_test 160i "changelog user register/unregister race"
16463
16464 test_160j() {
16465         remote_mds_nodsh && skip "remote MDS with nodsh"
16466         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16467                 skip "Need MDS version at least 2.12.56"
16468
16469         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16470         stack_trap "umount $MOUNT2" EXIT
16471
16472         changelog_register || error "first changelog_register failed"
16473         stack_trap "changelog_deregister" EXIT
16474
16475         # generate some changelog
16476         # use all_char because created files should be evenly distributed
16477         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16478                 error "mkdir $tdir failed"
16479         for ((i = 0; i < MDSCOUNT; i++)); do
16480                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16481                         error "create $DIR/$tdir/d$i.1 failed"
16482         done
16483
16484         # open the changelog device
16485         exec 3>/dev/changelog-$FSNAME-MDT0000
16486         stack_trap "exec 3>&-" EXIT
16487         exec 4</dev/changelog-$FSNAME-MDT0000
16488         stack_trap "exec 4<&-" EXIT
16489
16490         # umount the first lustre mount
16491         umount $MOUNT
16492         stack_trap "mount_client $MOUNT" EXIT
16493
16494         # read changelog, which may or may not fail, but should not crash
16495         cat <&4 >/dev/null
16496
16497         # clear changelog
16498         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16499         changelog_users $SINGLEMDS | grep -q $cl_user ||
16500                 error "User $cl_user not found in changelog_users"
16501
16502         printf 'clear:'$cl_user':0' >&3
16503 }
16504 run_test 160j "client can be umounted while its chanangelog is being used"
16505
16506 test_160k() {
16507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16508         remote_mds_nodsh && skip "remote MDS with nodsh"
16509
16510         mkdir -p $DIR/$tdir/1/1
16511
16512         changelog_register || error "changelog_register failed"
16513         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16514
16515         changelog_users $SINGLEMDS | grep -q $cl_user ||
16516                 error "User '$cl_user' not found in changelog_users"
16517 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16518         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16519         rmdir $DIR/$tdir/1/1 & sleep 1
16520         mkdir $DIR/$tdir/2
16521         touch $DIR/$tdir/2/2
16522         rm -rf $DIR/$tdir/2
16523
16524         wait
16525         sleep 4
16526
16527         changelog_dump | grep rmdir || error "rmdir not recorded"
16528 }
16529 run_test 160k "Verify that changelog records are not lost"
16530
16531 # Verifies that a file passed as a parameter has recently had an operation
16532 # performed on it that has generated an MTIME changelog which contains the
16533 # correct parent FID. As files might reside on a different MDT from the
16534 # parent directory in DNE configurations, the FIDs are translated to paths
16535 # before being compared, which should be identical
16536 compare_mtime_changelog() {
16537         local file="${1}"
16538         local mdtidx
16539         local mtime
16540         local cl_fid
16541         local pdir
16542         local dir
16543
16544         mdtidx=$($LFS getstripe --mdt-index $file)
16545         mdtidx=$(printf "%04x" $mdtidx)
16546
16547         # Obtain the parent FID from the MTIME changelog
16548         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16549         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16550
16551         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16552         [ -z "$cl_fid" ] && error "parent FID not present"
16553
16554         # Verify that the path for the parent FID is the same as the path for
16555         # the test directory
16556         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16557
16558         dir=$(dirname $1)
16559
16560         [[ "${pdir%/}" == "$dir" ]] ||
16561                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16562 }
16563
16564 test_160l() {
16565         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16566
16567         remote_mds_nodsh && skip "remote MDS with nodsh"
16568         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16569                 skip "Need MDS version at least 2.13.55"
16570
16571         local cl_user
16572
16573         changelog_register || error "changelog_register failed"
16574         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16575
16576         changelog_users $SINGLEMDS | grep -q $cl_user ||
16577                 error "User '$cl_user' not found in changelog_users"
16578
16579         # Clear some types so that MTIME changelogs are generated
16580         changelog_chmask "-CREAT"
16581         changelog_chmask "-CLOSE"
16582
16583         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16584
16585         # Test CL_MTIME during setattr
16586         touch $DIR/$tdir/$tfile
16587         compare_mtime_changelog $DIR/$tdir/$tfile
16588
16589         # Test CL_MTIME during close
16590         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16591         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16592 }
16593 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16594
16595 test_160m() {
16596         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16597         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16598                 skip "Need MDS version at least 2.14.51"
16599         local cl_users
16600         local cl_user1
16601         local cl_user2
16602         local pid1
16603
16604         # Create a user
16605         changelog_register || error "first changelog_register failed"
16606         changelog_register || error "second changelog_register failed"
16607
16608         cl_users=(${CL_USERS[mds1]})
16609         cl_user1="${cl_users[0]}"
16610         cl_user2="${cl_users[1]}"
16611         # generate some changelog records to accumulate on MDT0
16612         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16613         createmany -m $DIR/$tdir/$tfile 50 ||
16614                 error "create $DIR/$tdir/$tfile failed"
16615         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16616         rm -f $DIR/$tdir
16617
16618         # check changelogs have been generated
16619         local nbcl=$(changelog_dump | wc -l)
16620         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16621
16622 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16623         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16624
16625         __changelog_clear mds1 $cl_user1 +10
16626         __changelog_clear mds1 $cl_user2 0 &
16627         pid1=$!
16628         sleep 2
16629         __changelog_clear mds1 $cl_user1 0 ||
16630                 error "fail to cancel record for $cl_user1"
16631         wait $pid1
16632         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16633 }
16634 run_test 160m "Changelog clear race"
16635
16636 test_160n() {
16637         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16638         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16639                 skip "Need MDS version at least 2.14.51"
16640         local cl_users
16641         local cl_user1
16642         local cl_user2
16643         local pid1
16644         local first_rec
16645         local last_rec=0
16646
16647         # Create a user
16648         changelog_register || error "first changelog_register failed"
16649
16650         cl_users=(${CL_USERS[mds1]})
16651         cl_user1="${cl_users[0]}"
16652
16653         # generate some changelog records to accumulate on MDT0
16654         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16655         first_rec=$(changelog_users $SINGLEMDS |
16656                         awk '/^current.index:/ { print $NF }')
16657         while (( last_rec < (( first_rec + 65000)) )); do
16658                 createmany -m $DIR/$tdir/$tfile 10000 ||
16659                         error "create $DIR/$tdir/$tfile failed"
16660
16661                 for i in $(seq 0 10000); do
16662                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16663                                 > /dev/null
16664                 done
16665
16666                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16667                         error "unlinkmany failed unlink"
16668                 last_rec=$(changelog_users $SINGLEMDS |
16669                         awk '/^current.index:/ { print $NF }')
16670                 echo last record $last_rec
16671                 (( last_rec == 0 )) && error "no changelog found"
16672         done
16673
16674 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16675         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16676
16677         __changelog_clear mds1 $cl_user1 0 &
16678         pid1=$!
16679         sleep 2
16680         __changelog_clear mds1 $cl_user1 0 ||
16681                 error "fail to cancel record for $cl_user1"
16682         wait $pid1
16683         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16684 }
16685 run_test 160n "Changelog destroy race"
16686
16687 test_160o() {
16688         local mdt="$(facet_svc $SINGLEMDS)"
16689
16690         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16691         remote_mds_nodsh && skip "remote MDS with nodsh"
16692         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16693                 skip "Need MDS version at least 2.14.52"
16694
16695         changelog_register --user test_160o -m unlnk+close+open ||
16696                 error "changelog_register failed"
16697
16698         do_facet $SINGLEMDS $LCTL --device $mdt \
16699                                 changelog_register -u "Tt3_-#" &&
16700                 error "bad symbols in name should fail"
16701
16702         do_facet $SINGLEMDS $LCTL --device $mdt \
16703                                 changelog_register -u test_160o &&
16704                 error "the same name registration should fail"
16705
16706         do_facet $SINGLEMDS $LCTL --device $mdt \
16707                         changelog_register -u test_160toolongname &&
16708                 error "too long name registration should fail"
16709
16710         changelog_chmask "MARK+HSM"
16711         lctl get_param mdd.*.changelog*mask
16712         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16713         changelog_users $SINGLEMDS | grep -q $cl_user ||
16714                 error "User $cl_user not found in changelog_users"
16715         #verify username
16716         echo $cl_user | grep -q test_160o ||
16717                 error "User $cl_user has no specific name 'test160o'"
16718
16719         # change something
16720         changelog_clear 0 || error "changelog_clear failed"
16721         # generate some changelog records to accumulate on MDT0
16722         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16723         touch $DIR/$tdir/$tfile                 # open 1
16724
16725         OPENS=$(changelog_dump | grep -c "OPEN")
16726         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16727
16728         # must be no MKDIR it wasn't set as user mask
16729         MKDIR=$(changelog_dump | grep -c "MKDIR")
16730         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16731
16732         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16733                                 mdd.$mdt.changelog_current_mask -n)
16734         # register maskless user
16735         changelog_register || error "changelog_register failed"
16736         # effective mask should be not changed because it is not minimal
16737         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16738                                 mdd.$mdt.changelog_current_mask -n)
16739         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16740         # set server mask to minimal value
16741         changelog_chmask "MARK"
16742         # check effective mask again, should be treated as DEFMASK now
16743         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16744                                 mdd.$mdt.changelog_current_mask -n)
16745         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16746
16747         do_facet $SINGLEMDS $LCTL --device $mdt \
16748                                 changelog_deregister -u test_160o ||
16749                 error "cannot deregister by name"
16750 }
16751 run_test 160o "changelog user name and mask"
16752
16753 test_160p() {
16754         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16755         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16756                 skip "Need MDS version at least 2.14.51"
16757         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16758         local cl_users
16759         local cl_user1
16760         local entry_count
16761
16762         # Create a user
16763         changelog_register || error "first changelog_register failed"
16764
16765         cl_users=(${CL_USERS[mds1]})
16766         cl_user1="${cl_users[0]}"
16767
16768         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16769         createmany -m $DIR/$tdir/$tfile 50 ||
16770                 error "create $DIR/$tdir/$tfile failed"
16771         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16772         rm -rf $DIR/$tdir
16773
16774         # check changelogs have been generated
16775         entry_count=$(changelog_dump | wc -l)
16776         ((entry_count != 0)) || error "no changelog entries found"
16777
16778         # remove changelog_users and check that orphan entries are removed
16779         stop mds1
16780         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $(mdsdevname 1)"
16781         start mds1 || error "cannot start mdt"
16782         entry_count=$(changelog_dump | wc -l)
16783         ((entry_count == 0)) ||
16784                 error "found $entry_count changelog entries, expected none"
16785 }
16786 run_test 160p "Changelog orphan cleanup with no users"
16787
16788 test_160q() {
16789         local mdt="$(facet_svc $SINGLEMDS)"
16790         local clu
16791
16792         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16793         remote_mds_nodsh && skip "remote MDS with nodsh"
16794         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16795                 skip "Need MDS version at least 2.14.54"
16796
16797         # set server mask to minimal value like server init does
16798         changelog_chmask "MARK"
16799         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16800                 error "changelog_register failed"
16801         # check effective mask again, should be treated as DEFMASK now
16802         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16803                                 mdd.$mdt.changelog_current_mask -n)
16804         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
16805                 error "changelog_deregister failed"
16806         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16807 }
16808 run_test 160q "changelog effective mask is DEFMASK if not set"
16809
16810 test_160s() {
16811         remote_mds_nodsh && skip "remote MDS with nodsh"
16812         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
16813                 skip "Need MDS version at least 2.14.55"
16814
16815         local mdts=$(comma_list $(mdts_nodes))
16816
16817         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
16818         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
16819                                        fail_val=$((24 * 3600 * 10))
16820
16821         # Create a user which is 10 days old
16822         changelog_register || error "first changelog_register failed"
16823         local cl_users
16824         declare -A cl_user1
16825         local i
16826
16827         # generate some changelog records to accumulate on each MDT
16828         # use all_char because created files should be evenly distributed
16829         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16830                 error "test_mkdir $tdir failed"
16831         for ((i = 0; i < MDSCOUNT; i++)); do
16832                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16833                         error "create $DIR/$tdir/d$i.1 failed"
16834         done
16835
16836         # check changelogs have been generated
16837         local nbcl=$(changelog_dump | wc -l)
16838         (( nbcl > 0 )) || error "no changelogs found"
16839
16840         # reduce the max_idle_indexes value to make sure we exceed it
16841         for param in "changelog_max_idle_indexes=2097446912" \
16842                      "changelog_max_idle_time=2592000" \
16843                      "changelog_gc=1" \
16844                      "changelog_min_gc_interval=2"; do
16845                 local MDT0=$(facet_svc $SINGLEMDS)
16846                 local var="${param%=*}"
16847                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16848
16849                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16850                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16851                         error "unable to set mdd.*.$param"
16852         done
16853
16854         local start=$SECONDS
16855         for i in $(seq $MDSCOUNT); do
16856                 cl_users=(${CL_USERS[mds$i]})
16857                 cl_user1[mds$i]="${cl_users[0]}"
16858
16859                 [[ -n "${cl_user1[mds$i]}" ]] ||
16860                         error "mds$i: no user registered"
16861         done
16862
16863         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
16864         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
16865
16866         # ensure we are past the previous changelog_min_gc_interval set above
16867         local sleep2=$((start + 2 - SECONDS))
16868         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16869
16870         # Generate one more changelog to trigger GC
16871         for ((i = 0; i < MDSCOUNT; i++)); do
16872                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
16873                         error "create $DIR/$tdir/d$i.3 failed"
16874         done
16875
16876         # ensure gc thread is done
16877         for node in $(mdts_nodes); do
16878                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
16879                         error "$node: GC-thread not done"
16880         done
16881
16882         do_nodes $mdts $LCTL set_param fail_loc=0
16883
16884         for (( i = 1; i <= MDSCOUNT; i++ )); do
16885                 # check cl_user1 is purged
16886                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
16887                         error "mds$i: User ${cl_user1[mds$i]} is registered"
16888         done
16889         return 0
16890 }
16891 run_test 160s "changelog garbage collect on idle records * time"
16892
16893 test_161a() {
16894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16895
16896         test_mkdir -c1 $DIR/$tdir
16897         cp /etc/hosts $DIR/$tdir/$tfile
16898         test_mkdir -c1 $DIR/$tdir/foo1
16899         test_mkdir -c1 $DIR/$tdir/foo2
16900         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16901         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16902         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16903         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16904         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16905         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16906                 $LFS fid2path $DIR $FID
16907                 error "bad link ea"
16908         fi
16909         # middle
16910         rm $DIR/$tdir/foo2/zachary
16911         # last
16912         rm $DIR/$tdir/foo2/thor
16913         # first
16914         rm $DIR/$tdir/$tfile
16915         # rename
16916         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16917         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16918                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16919         rm $DIR/$tdir/foo2/maggie
16920
16921         # overflow the EA
16922         local longname=$tfile.avg_len_is_thirty_two_
16923         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16924                 error_noexit 'failed to unlink many hardlinks'" EXIT
16925         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16926                 error "failed to hardlink many files"
16927         links=$($LFS fid2path $DIR $FID | wc -l)
16928         echo -n "${links}/1000 links in link EA"
16929         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16930 }
16931 run_test 161a "link ea sanity"
16932
16933 test_161b() {
16934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16935         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16936
16937         local MDTIDX=1
16938         local remote_dir=$DIR/$tdir/remote_dir
16939
16940         mkdir -p $DIR/$tdir
16941         $LFS mkdir -i $MDTIDX $remote_dir ||
16942                 error "create remote directory failed"
16943
16944         cp /etc/hosts $remote_dir/$tfile
16945         mkdir -p $remote_dir/foo1
16946         mkdir -p $remote_dir/foo2
16947         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16948         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16949         ln $remote_dir/$tfile $remote_dir/foo1/luna
16950         ln $remote_dir/$tfile $remote_dir/foo2/thor
16951
16952         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16953                      tr -d ']')
16954         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16955                 $LFS fid2path $DIR $FID
16956                 error "bad link ea"
16957         fi
16958         # middle
16959         rm $remote_dir/foo2/zachary
16960         # last
16961         rm $remote_dir/foo2/thor
16962         # first
16963         rm $remote_dir/$tfile
16964         # rename
16965         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16966         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16967         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16968                 $LFS fid2path $DIR $FID
16969                 error "bad link rename"
16970         fi
16971         rm $remote_dir/foo2/maggie
16972
16973         # overflow the EA
16974         local longname=filename_avg_len_is_thirty_two_
16975         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
16976                 error "failed to hardlink many files"
16977         links=$($LFS fid2path $DIR $FID | wc -l)
16978         echo -n "${links}/1000 links in link EA"
16979         [[ ${links} -gt 60 ]] ||
16980                 error "expected at least 60 links in link EA"
16981         unlinkmany $remote_dir/foo2/$longname 1000 ||
16982         error "failed to unlink many hardlinks"
16983 }
16984 run_test 161b "link ea sanity under remote directory"
16985
16986 test_161c() {
16987         remote_mds_nodsh && skip "remote MDS with nodsh"
16988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16989         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
16990                 skip "Need MDS version at least 2.1.5"
16991
16992         # define CLF_RENAME_LAST 0x0001
16993         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
16994         changelog_register || error "changelog_register failed"
16995
16996         rm -rf $DIR/$tdir
16997         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
16998         touch $DIR/$tdir/foo_161c
16999         touch $DIR/$tdir/bar_161c
17000         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17001         changelog_dump | grep RENME | tail -n 5
17002         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17003         changelog_clear 0 || error "changelog_clear failed"
17004         if [ x$flags != "x0x1" ]; then
17005                 error "flag $flags is not 0x1"
17006         fi
17007
17008         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17009         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17010         touch $DIR/$tdir/foo_161c
17011         touch $DIR/$tdir/bar_161c
17012         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17013         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17014         changelog_dump | grep RENME | tail -n 5
17015         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17016         changelog_clear 0 || error "changelog_clear failed"
17017         if [ x$flags != "x0x0" ]; then
17018                 error "flag $flags is not 0x0"
17019         fi
17020         echo "rename overwrite a target having nlink > 1," \
17021                 "changelog record has flags of $flags"
17022
17023         # rename doesn't overwrite a target (changelog flag 0x0)
17024         touch $DIR/$tdir/foo_161c
17025         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17026         changelog_dump | grep RENME | tail -n 5
17027         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17028         changelog_clear 0 || error "changelog_clear failed"
17029         if [ x$flags != "x0x0" ]; then
17030                 error "flag $flags is not 0x0"
17031         fi
17032         echo "rename doesn't overwrite a target," \
17033                 "changelog record has flags of $flags"
17034
17035         # define CLF_UNLINK_LAST 0x0001
17036         # unlink a file having nlink = 1 (changelog flag 0x1)
17037         rm -f $DIR/$tdir/foo2_161c
17038         changelog_dump | grep UNLNK | tail -n 5
17039         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17040         changelog_clear 0 || error "changelog_clear failed"
17041         if [ x$flags != "x0x1" ]; then
17042                 error "flag $flags is not 0x1"
17043         fi
17044         echo "unlink a file having nlink = 1," \
17045                 "changelog record has flags of $flags"
17046
17047         # unlink a file having nlink > 1 (changelog flag 0x0)
17048         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17049         rm -f $DIR/$tdir/foobar_161c
17050         changelog_dump | grep UNLNK | tail -n 5
17051         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17052         changelog_clear 0 || error "changelog_clear failed"
17053         if [ x$flags != "x0x0" ]; then
17054                 error "flag $flags is not 0x0"
17055         fi
17056         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17057 }
17058 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17059
17060 test_161d() {
17061         remote_mds_nodsh && skip "remote MDS with nodsh"
17062         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17063
17064         local pid
17065         local fid
17066
17067         changelog_register || error "changelog_register failed"
17068
17069         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17070         # interfer with $MOUNT/.lustre/fid/ access
17071         mkdir $DIR/$tdir
17072         [[ $? -eq 0 ]] || error "mkdir failed"
17073
17074         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17075         $LCTL set_param fail_loc=0x8000140c
17076         # 5s pause
17077         $LCTL set_param fail_val=5
17078
17079         # create file
17080         echo foofoo > $DIR/$tdir/$tfile &
17081         pid=$!
17082
17083         # wait for create to be delayed
17084         sleep 2
17085
17086         ps -p $pid
17087         [[ $? -eq 0 ]] || error "create should be blocked"
17088
17089         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17090         stack_trap "rm -f $tempfile"
17091         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17092         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17093         # some delay may occur during ChangeLog publishing and file read just
17094         # above, that could allow file write to happen finally
17095         [[ -s $tempfile ]] && echo "file should be empty"
17096
17097         $LCTL set_param fail_loc=0
17098
17099         wait $pid
17100         [[ $? -eq 0 ]] || error "create failed"
17101 }
17102 run_test 161d "create with concurrent .lustre/fid access"
17103
17104 check_path() {
17105         local expected="$1"
17106         shift
17107         local fid="$2"
17108
17109         local path
17110         path=$($LFS fid2path "$@")
17111         local rc=$?
17112
17113         if [ $rc -ne 0 ]; then
17114                 error "path looked up of '$expected' failed: rc=$rc"
17115         elif [ "$path" != "$expected" ]; then
17116                 error "path looked up '$path' instead of '$expected'"
17117         else
17118                 echo "FID '$fid' resolves to path '$path' as expected"
17119         fi
17120 }
17121
17122 test_162a() { # was test_162
17123         test_mkdir -p -c1 $DIR/$tdir/d2
17124         touch $DIR/$tdir/d2/$tfile
17125         touch $DIR/$tdir/d2/x1
17126         touch $DIR/$tdir/d2/x2
17127         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17128         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17129         # regular file
17130         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17131         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17132
17133         # softlink
17134         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17135         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17136         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17137
17138         # softlink to wrong file
17139         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17140         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17141         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17142
17143         # hardlink
17144         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17145         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17146         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17147         # fid2path dir/fsname should both work
17148         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17149         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17150
17151         # hardlink count: check that there are 2 links
17152         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17153         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17154
17155         # hardlink indexing: remove the first link
17156         rm $DIR/$tdir/d2/p/q/r/hlink
17157         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17158 }
17159 run_test 162a "path lookup sanity"
17160
17161 test_162b() {
17162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17163         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17164
17165         mkdir $DIR/$tdir
17166         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17167                                 error "create striped dir failed"
17168
17169         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17170                                         tail -n 1 | awk '{print $2}')
17171         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17172
17173         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17174         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17175
17176         # regular file
17177         for ((i=0;i<5;i++)); do
17178                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17179                         error "get fid for f$i failed"
17180                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17181
17182                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17183                         error "get fid for d$i failed"
17184                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17185         done
17186
17187         return 0
17188 }
17189 run_test 162b "striped directory path lookup sanity"
17190
17191 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17192 test_162c() {
17193         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17194                 skip "Need MDS version at least 2.7.51"
17195
17196         local lpath=$tdir.local
17197         local rpath=$tdir.remote
17198
17199         test_mkdir $DIR/$lpath
17200         test_mkdir $DIR/$rpath
17201
17202         for ((i = 0; i <= 101; i++)); do
17203                 lpath="$lpath/$i"
17204                 mkdir $DIR/$lpath
17205                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17206                         error "get fid for local directory $DIR/$lpath failed"
17207                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17208
17209                 rpath="$rpath/$i"
17210                 test_mkdir $DIR/$rpath
17211                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17212                         error "get fid for remote directory $DIR/$rpath failed"
17213                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17214         done
17215
17216         return 0
17217 }
17218 run_test 162c "fid2path works with paths 100 or more directories deep"
17219
17220 oalr_event_count() {
17221         local event="${1}"
17222         local trace="${2}"
17223
17224         awk -v name="${FSNAME}-OST0000" \
17225             -v event="${event}" \
17226             '$1 == "TRACE" && $2 == event && $3 == name' \
17227             "${trace}" |
17228         wc -l
17229 }
17230
17231 oalr_expect_event_count() {
17232         local event="${1}"
17233         local trace="${2}"
17234         local expect="${3}"
17235         local count
17236
17237         count=$(oalr_event_count "${event}" "${trace}")
17238         if ((count == expect)); then
17239                 return 0
17240         fi
17241
17242         error_noexit "${event} event count was '${count}', expected ${expect}"
17243         cat "${trace}" >&2
17244         exit 1
17245 }
17246
17247 cleanup_165() {
17248         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17249         stop ost1
17250         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17251 }
17252
17253 setup_165() {
17254         sync # Flush previous IOs so we can count log entries.
17255         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17256         stack_trap cleanup_165 EXIT
17257 }
17258
17259 test_165a() {
17260         local trace="/tmp/${tfile}.trace"
17261         local rc
17262         local count
17263
17264         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17265                 skip "OFD access log unsupported"
17266
17267         setup_165
17268         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17269         sleep 5
17270
17271         do_facet ost1 ofd_access_log_reader --list
17272         stop ost1
17273
17274         do_facet ost1 killall -TERM ofd_access_log_reader
17275         wait
17276         rc=$?
17277
17278         if ((rc != 0)); then
17279                 error "ofd_access_log_reader exited with rc = '${rc}'"
17280         fi
17281
17282         # Parse trace file for discovery events:
17283         oalr_expect_event_count alr_log_add "${trace}" 1
17284         oalr_expect_event_count alr_log_eof "${trace}" 1
17285         oalr_expect_event_count alr_log_free "${trace}" 1
17286 }
17287 run_test 165a "ofd access log discovery"
17288
17289 test_165b() {
17290         local trace="/tmp/${tfile}.trace"
17291         local file="${DIR}/${tfile}"
17292         local pfid1
17293         local pfid2
17294         local -a entry
17295         local rc
17296         local count
17297         local size
17298         local flags
17299
17300         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17301                 skip "OFD access log unsupported"
17302
17303         setup_165
17304         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17305         sleep 5
17306
17307         do_facet ost1 ofd_access_log_reader --list
17308
17309         lfs setstripe -c 1 -i 0 "${file}"
17310         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17311                 error "cannot create '${file}'"
17312
17313         sleep 5
17314         do_facet ost1 killall -TERM ofd_access_log_reader
17315         wait
17316         rc=$?
17317
17318         if ((rc != 0)); then
17319                 error "ofd_access_log_reader exited with rc = '${rc}'"
17320         fi
17321
17322         oalr_expect_event_count alr_log_entry "${trace}" 1
17323
17324         pfid1=$($LFS path2fid "${file}")
17325
17326         # 1     2             3   4    5     6   7    8    9     10
17327         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17328         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17329
17330         echo "entry = '${entry[*]}'" >&2
17331
17332         pfid2=${entry[4]}
17333         if [[ "${pfid1}" != "${pfid2}" ]]; then
17334                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17335         fi
17336
17337         size=${entry[8]}
17338         if ((size != 1048576)); then
17339                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17340         fi
17341
17342         flags=${entry[10]}
17343         if [[ "${flags}" != "w" ]]; then
17344                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17345         fi
17346
17347         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17348         sleep 5
17349
17350         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17351                 error "cannot read '${file}'"
17352         sleep 5
17353
17354         do_facet ost1 killall -TERM ofd_access_log_reader
17355         wait
17356         rc=$?
17357
17358         if ((rc != 0)); then
17359                 error "ofd_access_log_reader exited with rc = '${rc}'"
17360         fi
17361
17362         oalr_expect_event_count alr_log_entry "${trace}" 1
17363
17364         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17365         echo "entry = '${entry[*]}'" >&2
17366
17367         pfid2=${entry[4]}
17368         if [[ "${pfid1}" != "${pfid2}" ]]; then
17369                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17370         fi
17371
17372         size=${entry[8]}
17373         if ((size != 524288)); then
17374                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17375         fi
17376
17377         flags=${entry[10]}
17378         if [[ "${flags}" != "r" ]]; then
17379                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17380         fi
17381 }
17382 run_test 165b "ofd access log entries are produced and consumed"
17383
17384 test_165c() {
17385         local trace="/tmp/${tfile}.trace"
17386         local file="${DIR}/${tdir}/${tfile}"
17387
17388         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17389                 skip "OFD access log unsupported"
17390
17391         test_mkdir "${DIR}/${tdir}"
17392
17393         setup_165
17394         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17395         sleep 5
17396
17397         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17398
17399         # 4096 / 64 = 64. Create twice as many entries.
17400         for ((i = 0; i < 128; i++)); do
17401                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17402                         error "cannot create file"
17403         done
17404
17405         sync
17406
17407         do_facet ost1 killall -TERM ofd_access_log_reader
17408         wait
17409         rc=$?
17410         if ((rc != 0)); then
17411                 error "ofd_access_log_reader exited with rc = '${rc}'"
17412         fi
17413
17414         unlinkmany  "${file}-%d" 128
17415 }
17416 run_test 165c "full ofd access logs do not block IOs"
17417
17418 oal_get_read_count() {
17419         local stats="$1"
17420
17421         # STATS lustre-OST0001 alr_read_count 1
17422
17423         do_facet ost1 cat "${stats}" |
17424         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17425              END { print count; }'
17426 }
17427
17428 oal_expect_read_count() {
17429         local stats="$1"
17430         local count
17431         local expect="$2"
17432
17433         # Ask ofd_access_log_reader to write stats.
17434         do_facet ost1 killall -USR1 ofd_access_log_reader
17435
17436         # Allow some time for things to happen.
17437         sleep 1
17438
17439         count=$(oal_get_read_count "${stats}")
17440         if ((count == expect)); then
17441                 return 0
17442         fi
17443
17444         error_noexit "bad read count, got ${count}, expected ${expect}"
17445         do_facet ost1 cat "${stats}" >&2
17446         exit 1
17447 }
17448
17449 test_165d() {
17450         local stats="/tmp/${tfile}.stats"
17451         local file="${DIR}/${tdir}/${tfile}"
17452         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17453
17454         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17455                 skip "OFD access log unsupported"
17456
17457         test_mkdir "${DIR}/${tdir}"
17458
17459         setup_165
17460         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17461         sleep 5
17462
17463         lfs setstripe -c 1 -i 0 "${file}"
17464
17465         do_facet ost1 lctl set_param "${param}=rw"
17466         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17467                 error "cannot create '${file}'"
17468         oal_expect_read_count "${stats}" 1
17469
17470         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17471                 error "cannot read '${file}'"
17472         oal_expect_read_count "${stats}" 2
17473
17474         do_facet ost1 lctl set_param "${param}=r"
17475         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17476                 error "cannot create '${file}'"
17477         oal_expect_read_count "${stats}" 2
17478
17479         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17480                 error "cannot read '${file}'"
17481         oal_expect_read_count "${stats}" 3
17482
17483         do_facet ost1 lctl set_param "${param}=w"
17484         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17485                 error "cannot create '${file}'"
17486         oal_expect_read_count "${stats}" 4
17487
17488         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17489                 error "cannot read '${file}'"
17490         oal_expect_read_count "${stats}" 4
17491
17492         do_facet ost1 lctl set_param "${param}=0"
17493         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17494                 error "cannot create '${file}'"
17495         oal_expect_read_count "${stats}" 4
17496
17497         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17498                 error "cannot read '${file}'"
17499         oal_expect_read_count "${stats}" 4
17500
17501         do_facet ost1 killall -TERM ofd_access_log_reader
17502         wait
17503         rc=$?
17504         if ((rc != 0)); then
17505                 error "ofd_access_log_reader exited with rc = '${rc}'"
17506         fi
17507 }
17508 run_test 165d "ofd_access_log mask works"
17509
17510 test_165e() {
17511         local stats="/tmp/${tfile}.stats"
17512         local file0="${DIR}/${tdir}-0/${tfile}"
17513         local file1="${DIR}/${tdir}-1/${tfile}"
17514
17515         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17516                 skip "OFD access log unsupported"
17517
17518         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17519
17520         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17521         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17522
17523         lfs setstripe -c 1 -i 0 "${file0}"
17524         lfs setstripe -c 1 -i 0 "${file1}"
17525
17526         setup_165
17527         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17528         sleep 5
17529
17530         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17531                 error "cannot create '${file0}'"
17532         sync
17533         oal_expect_read_count "${stats}" 0
17534
17535         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17536                 error "cannot create '${file1}'"
17537         sync
17538         oal_expect_read_count "${stats}" 1
17539
17540         do_facet ost1 killall -TERM ofd_access_log_reader
17541         wait
17542         rc=$?
17543         if ((rc != 0)); then
17544                 error "ofd_access_log_reader exited with rc = '${rc}'"
17545         fi
17546 }
17547 run_test 165e "ofd_access_log MDT index filter works"
17548
17549 test_165f() {
17550         local trace="/tmp/${tfile}.trace"
17551         local rc
17552         local count
17553
17554         setup_165
17555         do_facet ost1 timeout 60 ofd_access_log_reader \
17556                 --exit-on-close --debug=- --trace=- > "${trace}" &
17557         sleep 5
17558         stop ost1
17559
17560         wait
17561         rc=$?
17562
17563         if ((rc != 0)); then
17564                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17565                 cat "${trace}"
17566                 exit 1
17567         fi
17568 }
17569 run_test 165f "ofd_access_log_reader --exit-on-close works"
17570
17571 test_169() {
17572         # do directio so as not to populate the page cache
17573         log "creating a 10 Mb file"
17574         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17575                 error "multiop failed while creating a file"
17576         log "starting reads"
17577         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17578         log "truncating the file"
17579         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17580                 error "multiop failed while truncating the file"
17581         log "killing dd"
17582         kill %+ || true # reads might have finished
17583         echo "wait until dd is finished"
17584         wait
17585         log "removing the temporary file"
17586         rm -rf $DIR/$tfile || error "tmp file removal failed"
17587 }
17588 run_test 169 "parallel read and truncate should not deadlock"
17589
17590 test_170() {
17591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17592
17593         $LCTL clear     # bug 18514
17594         $LCTL debug_daemon start $TMP/${tfile}_log_good
17595         touch $DIR/$tfile
17596         $LCTL debug_daemon stop
17597         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17598                 error "sed failed to read log_good"
17599
17600         $LCTL debug_daemon start $TMP/${tfile}_log_good
17601         rm -rf $DIR/$tfile
17602         $LCTL debug_daemon stop
17603
17604         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17605                error "lctl df log_bad failed"
17606
17607         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17608         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17609
17610         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17611         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17612
17613         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17614                 error "bad_line good_line1 good_line2 are empty"
17615
17616         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17617         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17618         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17619
17620         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17621         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17622         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17623
17624         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17625                 error "bad_line_new good_line_new are empty"
17626
17627         local expected_good=$((good_line1 + good_line2*2))
17628
17629         rm -f $TMP/${tfile}*
17630         # LU-231, short malformed line may not be counted into bad lines
17631         if [ $bad_line -ne $bad_line_new ] &&
17632                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17633                 error "expected $bad_line bad lines, but got $bad_line_new"
17634                 return 1
17635         fi
17636
17637         if [ $expected_good -ne $good_line_new ]; then
17638                 error "expected $expected_good good lines, but got $good_line_new"
17639                 return 2
17640         fi
17641         true
17642 }
17643 run_test 170 "test lctl df to handle corrupted log ====================="
17644
17645 test_171() { # bug20592
17646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17647
17648         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17649         $LCTL set_param fail_loc=0x50e
17650         $LCTL set_param fail_val=3000
17651         multiop_bg_pause $DIR/$tfile O_s || true
17652         local MULTIPID=$!
17653         kill -USR1 $MULTIPID
17654         # cause log dump
17655         sleep 3
17656         wait $MULTIPID
17657         if dmesg | grep "recursive fault"; then
17658                 error "caught a recursive fault"
17659         fi
17660         $LCTL set_param fail_loc=0
17661         true
17662 }
17663 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17664
17665 # it would be good to share it with obdfilter-survey/iokit-libecho code
17666 setup_obdecho_osc () {
17667         local rc=0
17668         local ost_nid=$1
17669         local obdfilter_name=$2
17670         echo "Creating new osc for $obdfilter_name on $ost_nid"
17671         # make sure we can find loopback nid
17672         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17673
17674         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17675                            ${obdfilter_name}_osc_UUID || rc=2; }
17676         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17677                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17678         return $rc
17679 }
17680
17681 cleanup_obdecho_osc () {
17682         local obdfilter_name=$1
17683         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17684         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17685         return 0
17686 }
17687
17688 obdecho_test() {
17689         local OBD=$1
17690         local node=$2
17691         local pages=${3:-64}
17692         local rc=0
17693         local id
17694
17695         local count=10
17696         local obd_size=$(get_obd_size $node $OBD)
17697         local page_size=$(get_page_size $node)
17698         if [[ -n "$obd_size" ]]; then
17699                 local new_count=$((obd_size / (pages * page_size / 1024)))
17700                 [[ $new_count -ge $count ]] || count=$new_count
17701         fi
17702
17703         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17704         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17705                            rc=2; }
17706         if [ $rc -eq 0 ]; then
17707             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17708             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17709         fi
17710         echo "New object id is $id"
17711         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17712                            rc=4; }
17713         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17714                            "test_brw $count w v $pages $id" || rc=4; }
17715         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17716                            rc=4; }
17717         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17718                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17719         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17720                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17721         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17722         return $rc
17723 }
17724
17725 test_180a() {
17726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17727
17728         if ! [ -d /sys/fs/lustre/echo_client ] &&
17729            ! module_loaded obdecho; then
17730                 load_module obdecho/obdecho &&
17731                         stack_trap "rmmod obdecho" EXIT ||
17732                         error "unable to load obdecho on client"
17733         fi
17734
17735         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17736         local host=$($LCTL get_param -n osc.$osc.import |
17737                      awk '/current_connection:/ { print $2 }' )
17738         local target=$($LCTL get_param -n osc.$osc.import |
17739                        awk '/target:/ { print $2 }' )
17740         target=${target%_UUID}
17741
17742         if [ -n "$target" ]; then
17743                 setup_obdecho_osc $host $target &&
17744                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17745                         { error "obdecho setup failed with $?"; return; }
17746
17747                 obdecho_test ${target}_osc client ||
17748                         error "obdecho_test failed on ${target}_osc"
17749         else
17750                 $LCTL get_param osc.$osc.import
17751                 error "there is no osc.$osc.import target"
17752         fi
17753 }
17754 run_test 180a "test obdecho on osc"
17755
17756 test_180b() {
17757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17758         remote_ost_nodsh && skip "remote OST with nodsh"
17759
17760         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17761                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17762                 error "failed to load module obdecho"
17763
17764         local target=$(do_facet ost1 $LCTL dl |
17765                        awk '/obdfilter/ { print $4; exit; }')
17766
17767         if [ -n "$target" ]; then
17768                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17769         else
17770                 do_facet ost1 $LCTL dl
17771                 error "there is no obdfilter target on ost1"
17772         fi
17773 }
17774 run_test 180b "test obdecho directly on obdfilter"
17775
17776 test_180c() { # LU-2598
17777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17778         remote_ost_nodsh && skip "remote OST with nodsh"
17779         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17780                 skip "Need MDS version at least 2.4.0"
17781
17782         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17783                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17784                 error "failed to load module obdecho"
17785
17786         local target=$(do_facet ost1 $LCTL dl |
17787                        awk '/obdfilter/ { print $4; exit; }')
17788
17789         if [ -n "$target" ]; then
17790                 local pages=16384 # 64MB bulk I/O RPC size
17791
17792                 obdecho_test "$target" ost1 "$pages" ||
17793                         error "obdecho_test with pages=$pages failed with $?"
17794         else
17795                 do_facet ost1 $LCTL dl
17796                 error "there is no obdfilter target on ost1"
17797         fi
17798 }
17799 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17800
17801 test_181() { # bug 22177
17802         test_mkdir $DIR/$tdir
17803         # create enough files to index the directory
17804         createmany -o $DIR/$tdir/foobar 4000
17805         # print attributes for debug purpose
17806         lsattr -d .
17807         # open dir
17808         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17809         MULTIPID=$!
17810         # remove the files & current working dir
17811         unlinkmany $DIR/$tdir/foobar 4000
17812         rmdir $DIR/$tdir
17813         kill -USR1 $MULTIPID
17814         wait $MULTIPID
17815         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17816         return 0
17817 }
17818 run_test 181 "Test open-unlinked dir ========================"
17819
17820 test_182() {
17821         local fcount=1000
17822         local tcount=10
17823
17824         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17825
17826         $LCTL set_param mdc.*.rpc_stats=clear
17827
17828         for (( i = 0; i < $tcount; i++ )) ; do
17829                 mkdir $DIR/$tdir/$i
17830         done
17831
17832         for (( i = 0; i < $tcount; i++ )) ; do
17833                 createmany -o $DIR/$tdir/$i/f- $fcount &
17834         done
17835         wait
17836
17837         for (( i = 0; i < $tcount; i++ )) ; do
17838                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17839         done
17840         wait
17841
17842         $LCTL get_param mdc.*.rpc_stats
17843
17844         rm -rf $DIR/$tdir
17845 }
17846 run_test 182 "Test parallel modify metadata operations ================"
17847
17848 test_183() { # LU-2275
17849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17850         remote_mds_nodsh && skip "remote MDS with nodsh"
17851         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17852                 skip "Need MDS version at least 2.3.56"
17853
17854         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17855         echo aaa > $DIR/$tdir/$tfile
17856
17857 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17858         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17859
17860         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17861         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17862
17863         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17864
17865         # Flush negative dentry cache
17866         touch $DIR/$tdir/$tfile
17867
17868         # We are not checking for any leaked references here, they'll
17869         # become evident next time we do cleanup with module unload.
17870         rm -rf $DIR/$tdir
17871 }
17872 run_test 183 "No crash or request leak in case of strange dispositions ========"
17873
17874 # test suite 184 is for LU-2016, LU-2017
17875 test_184a() {
17876         check_swap_layouts_support
17877
17878         dir0=$DIR/$tdir/$testnum
17879         test_mkdir -p -c1 $dir0
17880         ref1=/etc/passwd
17881         ref2=/etc/group
17882         file1=$dir0/f1
17883         file2=$dir0/f2
17884         $LFS setstripe -c1 $file1
17885         cp $ref1 $file1
17886         $LFS setstripe -c2 $file2
17887         cp $ref2 $file2
17888         gen1=$($LFS getstripe -g $file1)
17889         gen2=$($LFS getstripe -g $file2)
17890
17891         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17892         gen=$($LFS getstripe -g $file1)
17893         [[ $gen1 != $gen ]] ||
17894                 error "Layout generation on $file1 does not change"
17895         gen=$($LFS getstripe -g $file2)
17896         [[ $gen2 != $gen ]] ||
17897                 error "Layout generation on $file2 does not change"
17898
17899         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17900         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17901
17902         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17903 }
17904 run_test 184a "Basic layout swap"
17905
17906 test_184b() {
17907         check_swap_layouts_support
17908
17909         dir0=$DIR/$tdir/$testnum
17910         mkdir -p $dir0 || error "creating dir $dir0"
17911         file1=$dir0/f1
17912         file2=$dir0/f2
17913         file3=$dir0/f3
17914         dir1=$dir0/d1
17915         dir2=$dir0/d2
17916         mkdir $dir1 $dir2
17917         $LFS setstripe -c1 $file1
17918         $LFS setstripe -c2 $file2
17919         $LFS setstripe -c1 $file3
17920         chown $RUNAS_ID $file3
17921         gen1=$($LFS getstripe -g $file1)
17922         gen2=$($LFS getstripe -g $file2)
17923
17924         $LFS swap_layouts $dir1 $dir2 &&
17925                 error "swap of directories layouts should fail"
17926         $LFS swap_layouts $dir1 $file1 &&
17927                 error "swap of directory and file layouts should fail"
17928         $RUNAS $LFS swap_layouts $file1 $file2 &&
17929                 error "swap of file we cannot write should fail"
17930         $LFS swap_layouts $file1 $file3 &&
17931                 error "swap of file with different owner should fail"
17932         /bin/true # to clear error code
17933 }
17934 run_test 184b "Forbidden layout swap (will generate errors)"
17935
17936 test_184c() {
17937         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
17938         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
17939         check_swap_layouts_support
17940         check_swap_layout_no_dom $DIR
17941
17942         local dir0=$DIR/$tdir/$testnum
17943         mkdir -p $dir0 || error "creating dir $dir0"
17944
17945         local ref1=$dir0/ref1
17946         local ref2=$dir0/ref2
17947         local file1=$dir0/file1
17948         local file2=$dir0/file2
17949         # create a file large enough for the concurrent test
17950         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
17951         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
17952         echo "ref file size: ref1($(stat -c %s $ref1))," \
17953              "ref2($(stat -c %s $ref2))"
17954
17955         cp $ref2 $file2
17956         dd if=$ref1 of=$file1 bs=16k &
17957         local DD_PID=$!
17958
17959         # Make sure dd starts to copy file, but wait at most 5 seconds
17960         local loops=0
17961         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
17962
17963         $LFS swap_layouts $file1 $file2
17964         local rc=$?
17965         wait $DD_PID
17966         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
17967         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
17968
17969         # how many bytes copied before swapping layout
17970         local copied=$(stat -c %s $file2)
17971         local remaining=$(stat -c %s $ref1)
17972         remaining=$((remaining - copied))
17973         echo "Copied $copied bytes before swapping layout..."
17974
17975         cmp -n $copied $file1 $ref2 | grep differ &&
17976                 error "Content mismatch [0, $copied) of ref2 and file1"
17977         cmp -n $copied $file2 $ref1 ||
17978                 error "Content mismatch [0, $copied) of ref1 and file2"
17979         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
17980                 error "Content mismatch [$copied, EOF) of ref1 and file1"
17981
17982         # clean up
17983         rm -f $ref1 $ref2 $file1 $file2
17984 }
17985 run_test 184c "Concurrent write and layout swap"
17986
17987 test_184d() {
17988         check_swap_layouts_support
17989         check_swap_layout_no_dom $DIR
17990         [ -z "$(which getfattr 2>/dev/null)" ] &&
17991                 skip_env "no getfattr command"
17992
17993         local file1=$DIR/$tdir/$tfile-1
17994         local file2=$DIR/$tdir/$tfile-2
17995         local file3=$DIR/$tdir/$tfile-3
17996         local lovea1
17997         local lovea2
17998
17999         mkdir -p $DIR/$tdir
18000         touch $file1 || error "create $file1 failed"
18001         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18002                 error "create $file2 failed"
18003         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18004                 error "create $file3 failed"
18005         lovea1=$(get_layout_param $file1)
18006
18007         $LFS swap_layouts $file2 $file3 ||
18008                 error "swap $file2 $file3 layouts failed"
18009         $LFS swap_layouts $file1 $file2 ||
18010                 error "swap $file1 $file2 layouts failed"
18011
18012         lovea2=$(get_layout_param $file2)
18013         echo "$lovea1"
18014         echo "$lovea2"
18015         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18016
18017         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18018         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18019 }
18020 run_test 184d "allow stripeless layouts swap"
18021
18022 test_184e() {
18023         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18024                 skip "Need MDS version at least 2.6.94"
18025         check_swap_layouts_support
18026         check_swap_layout_no_dom $DIR
18027         [ -z "$(which getfattr 2>/dev/null)" ] &&
18028                 skip_env "no getfattr command"
18029
18030         local file1=$DIR/$tdir/$tfile-1
18031         local file2=$DIR/$tdir/$tfile-2
18032         local file3=$DIR/$tdir/$tfile-3
18033         local lovea
18034
18035         mkdir -p $DIR/$tdir
18036         touch $file1 || error "create $file1 failed"
18037         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18038                 error "create $file2 failed"
18039         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18040                 error "create $file3 failed"
18041
18042         $LFS swap_layouts $file1 $file2 ||
18043                 error "swap $file1 $file2 layouts failed"
18044
18045         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18046         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18047
18048         echo 123 > $file1 || error "Should be able to write into $file1"
18049
18050         $LFS swap_layouts $file1 $file3 ||
18051                 error "swap $file1 $file3 layouts failed"
18052
18053         echo 123 > $file1 || error "Should be able to write into $file1"
18054
18055         rm -rf $file1 $file2 $file3
18056 }
18057 run_test 184e "Recreate layout after stripeless layout swaps"
18058
18059 test_184f() {
18060         # Create a file with name longer than sizeof(struct stat) ==
18061         # 144 to see if we can get chars from the file name to appear
18062         # in the returned striping. Note that 'f' == 0x66.
18063         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18064
18065         mkdir -p $DIR/$tdir
18066         mcreate $DIR/$tdir/$file
18067         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18068                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18069         fi
18070 }
18071 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18072
18073 test_185() { # LU-2441
18074         # LU-3553 - no volatile file support in old servers
18075         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18076                 skip "Need MDS version at least 2.3.60"
18077
18078         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18079         touch $DIR/$tdir/spoo
18080         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18081         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18082                 error "cannot create/write a volatile file"
18083         [ "$FILESET" == "" ] &&
18084         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18085                 error "FID is still valid after close"
18086
18087         multiop_bg_pause $DIR/$tdir vVw4096_c
18088         local multi_pid=$!
18089
18090         local OLD_IFS=$IFS
18091         IFS=":"
18092         local fidv=($fid)
18093         IFS=$OLD_IFS
18094         # assume that the next FID for this client is sequential, since stdout
18095         # is unfortunately eaten by multiop_bg_pause
18096         local n=$((${fidv[1]} + 1))
18097         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18098         if [ "$FILESET" == "" ]; then
18099                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18100                         error "FID is missing before close"
18101         fi
18102         kill -USR1 $multi_pid
18103         # 1 second delay, so if mtime change we will see it
18104         sleep 1
18105         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18106         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18107 }
18108 run_test 185 "Volatile file support"
18109
18110 function create_check_volatile() {
18111         local idx=$1
18112         local tgt
18113
18114         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18115         local PID=$!
18116         sleep 1
18117         local FID=$(cat /tmp/${tfile}.fid)
18118         [ "$FID" == "" ] && error "can't get FID for volatile"
18119         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18120         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18121         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18122         kill -USR1 $PID
18123         wait
18124         sleep 1
18125         cancel_lru_locks mdc # flush opencache
18126         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18127         return 0
18128 }
18129
18130 test_185a(){
18131         # LU-12516 - volatile creation via .lustre
18132         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18133                 skip "Need MDS version at least 2.3.55"
18134
18135         create_check_volatile 0
18136         [ $MDSCOUNT -lt 2 ] && return 0
18137
18138         # DNE case
18139         create_check_volatile 1
18140
18141         return 0
18142 }
18143 run_test 185a "Volatile file creation in .lustre/fid/"
18144
18145 test_187a() {
18146         remote_mds_nodsh && skip "remote MDS with nodsh"
18147         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18148                 skip "Need MDS version at least 2.3.0"
18149
18150         local dir0=$DIR/$tdir/$testnum
18151         mkdir -p $dir0 || error "creating dir $dir0"
18152
18153         local file=$dir0/file1
18154         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18155         local dv1=$($LFS data_version $file)
18156         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18157         local dv2=$($LFS data_version $file)
18158         [[ $dv1 != $dv2 ]] ||
18159                 error "data version did not change on write $dv1 == $dv2"
18160
18161         # clean up
18162         rm -f $file1
18163 }
18164 run_test 187a "Test data version change"
18165
18166 test_187b() {
18167         remote_mds_nodsh && skip "remote MDS with nodsh"
18168         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18169                 skip "Need MDS version at least 2.3.0"
18170
18171         local dir0=$DIR/$tdir/$testnum
18172         mkdir -p $dir0 || error "creating dir $dir0"
18173
18174         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18175         [[ ${DV[0]} != ${DV[1]} ]] ||
18176                 error "data version did not change on write"\
18177                       " ${DV[0]} == ${DV[1]}"
18178
18179         # clean up
18180         rm -f $file1
18181 }
18182 run_test 187b "Test data version change on volatile file"
18183
18184 test_200() {
18185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18186         remote_mgs_nodsh && skip "remote MGS with nodsh"
18187         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18188
18189         local POOL=${POOL:-cea1}
18190         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18191         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18192         # Pool OST targets
18193         local first_ost=0
18194         local last_ost=$(($OSTCOUNT - 1))
18195         local ost_step=2
18196         local ost_list=$(seq $first_ost $ost_step $last_ost)
18197         local ost_range="$first_ost $last_ost $ost_step"
18198         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18199         local file_dir=$POOL_ROOT/file_tst
18200         local subdir=$test_path/subdir
18201         local rc=0
18202
18203         while : ; do
18204                 # former test_200a test_200b
18205                 pool_add $POOL                          || { rc=$? ; break; }
18206                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18207                 # former test_200c test_200d
18208                 mkdir -p $test_path
18209                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18210                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18211                 mkdir -p $subdir
18212                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18213                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18214                                                         || { rc=$? ; break; }
18215                 # former test_200e test_200f
18216                 local files=$((OSTCOUNT*3))
18217                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18218                                                         || { rc=$? ; break; }
18219                 pool_create_files $POOL $file_dir $files "$ost_list" \
18220                                                         || { rc=$? ; break; }
18221                 # former test_200g test_200h
18222                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18223                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18224
18225                 # former test_201a test_201b test_201c
18226                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18227
18228                 local f=$test_path/$tfile
18229                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18230                 pool_remove $POOL $f                    || { rc=$? ; break; }
18231                 break
18232         done
18233
18234         destroy_test_pools
18235
18236         return $rc
18237 }
18238 run_test 200 "OST pools"
18239
18240 # usage: default_attr <count | size | offset>
18241 default_attr() {
18242         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18243 }
18244
18245 # usage: check_default_stripe_attr
18246 check_default_stripe_attr() {
18247         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18248         case $1 in
18249         --stripe-count|-c)
18250                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18251         --stripe-size|-S)
18252                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18253         --stripe-index|-i)
18254                 EXPECTED=-1;;
18255         *)
18256                 error "unknown getstripe attr '$1'"
18257         esac
18258
18259         [ $ACTUAL == $EXPECTED ] ||
18260                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18261 }
18262
18263 test_204a() {
18264         test_mkdir $DIR/$tdir
18265         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18266
18267         check_default_stripe_attr --stripe-count
18268         check_default_stripe_attr --stripe-size
18269         check_default_stripe_attr --stripe-index
18270 }
18271 run_test 204a "Print default stripe attributes"
18272
18273 test_204b() {
18274         test_mkdir $DIR/$tdir
18275         $LFS setstripe --stripe-count 1 $DIR/$tdir
18276
18277         check_default_stripe_attr --stripe-size
18278         check_default_stripe_attr --stripe-index
18279 }
18280 run_test 204b "Print default stripe size and offset"
18281
18282 test_204c() {
18283         test_mkdir $DIR/$tdir
18284         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18285
18286         check_default_stripe_attr --stripe-count
18287         check_default_stripe_attr --stripe-index
18288 }
18289 run_test 204c "Print default stripe count and offset"
18290
18291 test_204d() {
18292         test_mkdir $DIR/$tdir
18293         $LFS setstripe --stripe-index 0 $DIR/$tdir
18294
18295         check_default_stripe_attr --stripe-count
18296         check_default_stripe_attr --stripe-size
18297 }
18298 run_test 204d "Print default stripe count and size"
18299
18300 test_204e() {
18301         test_mkdir $DIR/$tdir
18302         $LFS setstripe -d $DIR/$tdir
18303
18304         check_default_stripe_attr --stripe-count --raw
18305         check_default_stripe_attr --stripe-size --raw
18306         check_default_stripe_attr --stripe-index --raw
18307 }
18308 run_test 204e "Print raw stripe attributes"
18309
18310 test_204f() {
18311         test_mkdir $DIR/$tdir
18312         $LFS setstripe --stripe-count 1 $DIR/$tdir
18313
18314         check_default_stripe_attr --stripe-size --raw
18315         check_default_stripe_attr --stripe-index --raw
18316 }
18317 run_test 204f "Print raw stripe size and offset"
18318
18319 test_204g() {
18320         test_mkdir $DIR/$tdir
18321         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18322
18323         check_default_stripe_attr --stripe-count --raw
18324         check_default_stripe_attr --stripe-index --raw
18325 }
18326 run_test 204g "Print raw stripe count and offset"
18327
18328 test_204h() {
18329         test_mkdir $DIR/$tdir
18330         $LFS setstripe --stripe-index 0 $DIR/$tdir
18331
18332         check_default_stripe_attr --stripe-count --raw
18333         check_default_stripe_attr --stripe-size --raw
18334 }
18335 run_test 204h "Print raw stripe count and size"
18336
18337 # Figure out which job scheduler is being used, if any,
18338 # or use a fake one
18339 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18340         JOBENV=SLURM_JOB_ID
18341 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18342         JOBENV=LSB_JOBID
18343 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18344         JOBENV=PBS_JOBID
18345 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18346         JOBENV=LOADL_STEP_ID
18347 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18348         JOBENV=JOB_ID
18349 else
18350         $LCTL list_param jobid_name > /dev/null 2>&1
18351         if [ $? -eq 0 ]; then
18352                 JOBENV=nodelocal
18353         else
18354                 JOBENV=FAKE_JOBID
18355         fi
18356 fi
18357 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18358
18359 verify_jobstats() {
18360         local cmd=($1)
18361         shift
18362         local facets="$@"
18363
18364 # we don't really need to clear the stats for this test to work, since each
18365 # command has a unique jobid, but it makes debugging easier if needed.
18366 #       for facet in $facets; do
18367 #               local dev=$(convert_facet2label $facet)
18368 #               # clear old jobstats
18369 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18370 #       done
18371
18372         # use a new JobID for each test, or we might see an old one
18373         [ "$JOBENV" = "FAKE_JOBID" ] &&
18374                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18375
18376         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18377
18378         [ "$JOBENV" = "nodelocal" ] && {
18379                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18380                 $LCTL set_param jobid_name=$FAKE_JOBID
18381                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18382         }
18383
18384         log "Test: ${cmd[*]}"
18385         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18386
18387         if [ $JOBENV = "FAKE_JOBID" ]; then
18388                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18389         else
18390                 ${cmd[*]}
18391         fi
18392
18393         # all files are created on OST0000
18394         for facet in $facets; do
18395                 local stats="*.$(convert_facet2label $facet).job_stats"
18396
18397                 # strip out libtool wrappers for in-tree executables
18398                 if (( $(do_facet $facet lctl get_param $stats |
18399                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18400                         do_facet $facet lctl get_param $stats
18401                         error "No jobstats for $JOBVAL found on $facet::$stats"
18402                 fi
18403         done
18404 }
18405
18406 jobstats_set() {
18407         local new_jobenv=$1
18408
18409         set_persistent_param_and_check client "jobid_var" \
18410                 "$FSNAME.sys.jobid_var" $new_jobenv
18411 }
18412
18413 test_205a() { # Job stats
18414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18415         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18416                 skip "Need MDS version with at least 2.7.1"
18417         remote_mgs_nodsh && skip "remote MGS with nodsh"
18418         remote_mds_nodsh && skip "remote MDS with nodsh"
18419         remote_ost_nodsh && skip "remote OST with nodsh"
18420         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18421                 skip "Server doesn't support jobstats"
18422         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18423
18424         local old_jobenv=$($LCTL get_param -n jobid_var)
18425         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18426
18427         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18428                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18429         else
18430                 stack_trap "do_facet mgs $PERM_CMD \
18431                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18432         fi
18433         changelog_register
18434
18435         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18436                                 mdt.*.job_cleanup_interval | head -n 1)
18437         local new_interval=5
18438         do_facet $SINGLEMDS \
18439                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18440         stack_trap "do_facet $SINGLEMDS \
18441                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18442         local start=$SECONDS
18443
18444         local cmd
18445         # mkdir
18446         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18447         verify_jobstats "$cmd" "$SINGLEMDS"
18448         # rmdir
18449         cmd="rmdir $DIR/$tdir"
18450         verify_jobstats "$cmd" "$SINGLEMDS"
18451         # mkdir on secondary MDT
18452         if [ $MDSCOUNT -gt 1 ]; then
18453                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18454                 verify_jobstats "$cmd" "mds2"
18455         fi
18456         # mknod
18457         cmd="mknod $DIR/$tfile c 1 3"
18458         verify_jobstats "$cmd" "$SINGLEMDS"
18459         # unlink
18460         cmd="rm -f $DIR/$tfile"
18461         verify_jobstats "$cmd" "$SINGLEMDS"
18462         # create all files on OST0000 so verify_jobstats can find OST stats
18463         # open & close
18464         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18465         verify_jobstats "$cmd" "$SINGLEMDS"
18466         # setattr
18467         cmd="touch $DIR/$tfile"
18468         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18469         # write
18470         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18471         verify_jobstats "$cmd" "ost1"
18472         # read
18473         cancel_lru_locks osc
18474         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18475         verify_jobstats "$cmd" "ost1"
18476         # truncate
18477         cmd="$TRUNCATE $DIR/$tfile 0"
18478         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18479         # rename
18480         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18481         verify_jobstats "$cmd" "$SINGLEMDS"
18482         # jobstats expiry - sleep until old stats should be expired
18483         local left=$((new_interval + 5 - (SECONDS - start)))
18484         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18485                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18486                         "0" $left
18487         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18488         verify_jobstats "$cmd" "$SINGLEMDS"
18489         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18490             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18491
18492         # Ensure that jobid are present in changelog (if supported by MDS)
18493         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18494                 changelog_dump | tail -10
18495                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18496                 [ $jobids -eq 9 ] ||
18497                         error "Wrong changelog jobid count $jobids != 9"
18498
18499                 # LU-5862
18500                 JOBENV="disable"
18501                 jobstats_set $JOBENV
18502                 touch $DIR/$tfile
18503                 changelog_dump | grep $tfile
18504                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18505                 [ $jobids -eq 0 ] ||
18506                         error "Unexpected jobids when jobid_var=$JOBENV"
18507         fi
18508
18509         # test '%j' access to environment variable - if supported
18510         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18511                 JOBENV="JOBCOMPLEX"
18512                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18513
18514                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18515         fi
18516
18517         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18518                 JOBENV="JOBCOMPLEX"
18519                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18520
18521                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18522         fi
18523
18524         # test '%j' access to per-session jobid - if supported
18525         if lctl list_param jobid_this_session > /dev/null 2>&1
18526         then
18527                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18528                 lctl set_param jobid_this_session=$USER
18529
18530                 JOBENV="JOBCOMPLEX"
18531                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18532
18533                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18534         fi
18535 }
18536 run_test 205a "Verify job stats"
18537
18538 # LU-13117, LU-13597
18539 test_205b() {
18540         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18541                 skip "Need MDS version at least 2.13.54.91"
18542
18543         job_stats="mdt.*.job_stats"
18544         $LCTL set_param $job_stats=clear
18545         # Setting jobid_var to USER might not be supported
18546         $LCTL set_param jobid_var=USER || true
18547         $LCTL set_param jobid_name="%e.%u"
18548         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18549         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18550                 grep "job_id:.*foolish" &&
18551                         error "Unexpected jobid found"
18552         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18553                 grep "open:.*min.*max.*sum" ||
18554                         error "wrong job_stats format found"
18555 }
18556 run_test 205b "Verify job stats jobid and output format"
18557
18558 # LU-13733
18559 test_205c() {
18560         $LCTL set_param llite.*.stats=0
18561         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18562         $LCTL get_param llite.*.stats
18563         $LCTL get_param llite.*.stats | grep \
18564                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18565                         error "wrong client stats format found"
18566 }
18567 run_test 205c "Verify client stats format"
18568
18569 # LU-1480, LU-1773 and LU-1657
18570 test_206() {
18571         mkdir -p $DIR/$tdir
18572         $LFS setstripe -c -1 $DIR/$tdir
18573 #define OBD_FAIL_LOV_INIT 0x1403
18574         $LCTL set_param fail_loc=0xa0001403
18575         $LCTL set_param fail_val=1
18576         touch $DIR/$tdir/$tfile || true
18577 }
18578 run_test 206 "fail lov_init_raid0() doesn't lbug"
18579
18580 test_207a() {
18581         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18582         local fsz=`stat -c %s $DIR/$tfile`
18583         cancel_lru_locks mdc
18584
18585         # do not return layout in getattr intent
18586 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18587         $LCTL set_param fail_loc=0x170
18588         local sz=`stat -c %s $DIR/$tfile`
18589
18590         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18591
18592         rm -rf $DIR/$tfile
18593 }
18594 run_test 207a "can refresh layout at glimpse"
18595
18596 test_207b() {
18597         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18598         local cksum=`md5sum $DIR/$tfile`
18599         local fsz=`stat -c %s $DIR/$tfile`
18600         cancel_lru_locks mdc
18601         cancel_lru_locks osc
18602
18603         # do not return layout in getattr intent
18604 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18605         $LCTL set_param fail_loc=0x171
18606
18607         # it will refresh layout after the file is opened but before read issues
18608         echo checksum is "$cksum"
18609         echo "$cksum" |md5sum -c --quiet || error "file differs"
18610
18611         rm -rf $DIR/$tfile
18612 }
18613 run_test 207b "can refresh layout at open"
18614
18615 test_208() {
18616         # FIXME: in this test suite, only RD lease is used. This is okay
18617         # for now as only exclusive open is supported. After generic lease
18618         # is done, this test suite should be revised. - Jinshan
18619
18620         remote_mds_nodsh && skip "remote MDS with nodsh"
18621         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18622                 skip "Need MDS version at least 2.4.52"
18623
18624         echo "==== test 1: verify get lease work"
18625         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18626
18627         echo "==== test 2: verify lease can be broken by upcoming open"
18628         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18629         local PID=$!
18630         sleep 2
18631
18632         $MULTIOP $DIR/$tfile oO_RDWR:c
18633         kill -USR1 $PID && wait $PID || error "break lease error"
18634
18635         echo "==== test 3: verify lease can't be granted if an open already exists"
18636         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18637         local PID=$!
18638         sleep 2
18639
18640         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18641         kill -USR1 $PID && wait $PID || error "open file error"
18642
18643         echo "==== test 4: lease can sustain over recovery"
18644         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18645         PID=$!
18646         sleep 2
18647
18648         fail mds1
18649
18650         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18651
18652         echo "==== test 5: lease broken can't be regained by replay"
18653         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18654         PID=$!
18655         sleep 2
18656
18657         # open file to break lease and then recovery
18658         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18659         fail mds1
18660
18661         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18662
18663         rm -f $DIR/$tfile
18664 }
18665 run_test 208 "Exclusive open"
18666
18667 test_209() {
18668         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18669                 skip_env "must have disp_stripe"
18670
18671         touch $DIR/$tfile
18672         sync; sleep 5; sync;
18673
18674         echo 3 > /proc/sys/vm/drop_caches
18675         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18676                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18677         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18678
18679         # open/close 500 times
18680         for i in $(seq 500); do
18681                 cat $DIR/$tfile
18682         done
18683
18684         echo 3 > /proc/sys/vm/drop_caches
18685         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18686                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18687         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18688
18689         echo "before: $req_before, after: $req_after"
18690         [ $((req_after - req_before)) -ge 300 ] &&
18691                 error "open/close requests are not freed"
18692         return 0
18693 }
18694 run_test 209 "read-only open/close requests should be freed promptly"
18695
18696 test_210() {
18697         local pid
18698
18699         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18700         pid=$!
18701         sleep 1
18702
18703         $LFS getstripe $DIR/$tfile
18704         kill -USR1 $pid
18705         wait $pid || error "multiop failed"
18706
18707         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18708         pid=$!
18709         sleep 1
18710
18711         $LFS getstripe $DIR/$tfile
18712         kill -USR1 $pid
18713         wait $pid || error "multiop failed"
18714 }
18715 run_test 210 "lfs getstripe does not break leases"
18716
18717 test_212() {
18718         size=`date +%s`
18719         size=$((size % 8192 + 1))
18720         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18721         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18722         rm -f $DIR/f212 $DIR/f212.xyz
18723 }
18724 run_test 212 "Sendfile test ============================================"
18725
18726 test_213() {
18727         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18728         cancel_lru_locks osc
18729         lctl set_param fail_loc=0x8000040f
18730         # generate a read lock
18731         cat $DIR/$tfile > /dev/null
18732         # write to the file, it will try to cancel the above read lock.
18733         cat /etc/hosts >> $DIR/$tfile
18734 }
18735 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18736
18737 test_214() { # for bug 20133
18738         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18739         for (( i=0; i < 340; i++ )) ; do
18740                 touch $DIR/$tdir/d214c/a$i
18741         done
18742
18743         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18744         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18745         ls $DIR/d214c || error "ls $DIR/d214c failed"
18746         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18747         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18748 }
18749 run_test 214 "hash-indexed directory test - bug 20133"
18750
18751 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18752 create_lnet_proc_files() {
18753         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18754 }
18755
18756 # counterpart of create_lnet_proc_files
18757 remove_lnet_proc_files() {
18758         rm -f $TMP/lnet_$1.sys
18759 }
18760
18761 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18762 # 3rd arg as regexp for body
18763 check_lnet_proc_stats() {
18764         local l=$(cat "$TMP/lnet_$1" |wc -l)
18765         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18766
18767         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18768 }
18769
18770 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18771 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18772 # optional and can be regexp for 2nd line (lnet.routes case)
18773 check_lnet_proc_entry() {
18774         local blp=2          # blp stands for 'position of 1st line of body'
18775         [ -z "$5" ] || blp=3 # lnet.routes case
18776
18777         local l=$(cat "$TMP/lnet_$1" |wc -l)
18778         # subtracting one from $blp because the body can be empty
18779         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18780
18781         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18782                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18783
18784         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18785                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18786
18787         # bail out if any unexpected line happened
18788         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18789         [ "$?" != 0 ] || error "$2 misformatted"
18790 }
18791
18792 test_215() { # for bugs 18102, 21079, 21517
18793         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18794
18795         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18796         local P='[1-9][0-9]*'           # positive numeric
18797         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18798         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18799         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18800         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18801
18802         local L1 # regexp for 1st line
18803         local L2 # regexp for 2nd line (optional)
18804         local BR # regexp for the rest (body)
18805
18806         # lnet.stats should look as 11 space-separated non-negative numerics
18807         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18808         create_lnet_proc_files "stats"
18809         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18810         remove_lnet_proc_files "stats"
18811
18812         # lnet.routes should look like this:
18813         # Routing disabled/enabled
18814         # net hops priority state router
18815         # where net is a string like tcp0, hops > 0, priority >= 0,
18816         # state is up/down,
18817         # router is a string like 192.168.1.1@tcp2
18818         L1="^Routing (disabled|enabled)$"
18819         L2="^net +hops +priority +state +router$"
18820         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18821         create_lnet_proc_files "routes"
18822         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18823         remove_lnet_proc_files "routes"
18824
18825         # lnet.routers should look like this:
18826         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18827         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18828         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18829         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18830         L1="^ref +rtr_ref +alive +router$"
18831         BR="^$P +$P +(up|down) +$NID$"
18832         create_lnet_proc_files "routers"
18833         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18834         remove_lnet_proc_files "routers"
18835
18836         # lnet.peers should look like this:
18837         # nid refs state last max rtr min tx min queue
18838         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18839         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18840         # numeric (0 or >0 or <0), queue >= 0.
18841         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18842         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18843         create_lnet_proc_files "peers"
18844         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18845         remove_lnet_proc_files "peers"
18846
18847         # lnet.buffers  should look like this:
18848         # pages count credits min
18849         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18850         L1="^pages +count +credits +min$"
18851         BR="^ +$N +$N +$I +$I$"
18852         create_lnet_proc_files "buffers"
18853         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18854         remove_lnet_proc_files "buffers"
18855
18856         # lnet.nis should look like this:
18857         # nid status alive refs peer rtr max tx min
18858         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18859         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18860         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18861         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18862         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18863         create_lnet_proc_files "nis"
18864         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18865         remove_lnet_proc_files "nis"
18866
18867         # can we successfully write to lnet.stats?
18868         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18869 }
18870 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18871
18872 test_216() { # bug 20317
18873         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18874         remote_ost_nodsh && skip "remote OST with nodsh"
18875
18876         local node
18877         local facets=$(get_facets OST)
18878         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18879
18880         save_lustre_params client "osc.*.contention_seconds" > $p
18881         save_lustre_params $facets \
18882                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18883         save_lustre_params $facets \
18884                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18885         save_lustre_params $facets \
18886                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18887         clear_stats osc.*.osc_stats
18888
18889         # agressive lockless i/o settings
18890         do_nodes $(comma_list $(osts_nodes)) \
18891                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18892                         ldlm.namespaces.filter-*.contended_locks=0 \
18893                         ldlm.namespaces.filter-*.contention_seconds=60"
18894         lctl set_param -n osc.*.contention_seconds=60
18895
18896         $DIRECTIO write $DIR/$tfile 0 10 4096
18897         $CHECKSTAT -s 40960 $DIR/$tfile
18898
18899         # disable lockless i/o
18900         do_nodes $(comma_list $(osts_nodes)) \
18901                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18902                         ldlm.namespaces.filter-*.contended_locks=32 \
18903                         ldlm.namespaces.filter-*.contention_seconds=0"
18904         lctl set_param -n osc.*.contention_seconds=0
18905         clear_stats osc.*.osc_stats
18906
18907         dd if=/dev/zero of=$DIR/$tfile count=0
18908         $CHECKSTAT -s 0 $DIR/$tfile
18909
18910         restore_lustre_params <$p
18911         rm -f $p
18912         rm $DIR/$tfile
18913 }
18914 run_test 216 "check lockless direct write updates file size and kms correctly"
18915
18916 test_217() { # bug 22430
18917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18918
18919         local node
18920         local nid
18921
18922         for node in $(nodes_list); do
18923                 nid=$(host_nids_address $node $NETTYPE)
18924                 if [[ $nid = *-* ]] ; then
18925                         echo "lctl ping $(h2nettype $nid)"
18926                         lctl ping $(h2nettype $nid)
18927                 else
18928                         echo "skipping $node (no hyphen detected)"
18929                 fi
18930         done
18931 }
18932 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18933
18934 test_218() {
18935        # do directio so as not to populate the page cache
18936        log "creating a 10 Mb file"
18937        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
18938        log "starting reads"
18939        dd if=$DIR/$tfile of=/dev/null bs=4096 &
18940        log "truncating the file"
18941        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
18942        log "killing dd"
18943        kill %+ || true # reads might have finished
18944        echo "wait until dd is finished"
18945        wait
18946        log "removing the temporary file"
18947        rm -rf $DIR/$tfile || error "tmp file removal failed"
18948 }
18949 run_test 218 "parallel read and truncate should not deadlock"
18950
18951 test_219() {
18952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18953
18954         # write one partial page
18955         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
18956         # set no grant so vvp_io_commit_write will do sync write
18957         $LCTL set_param fail_loc=0x411
18958         # write a full page at the end of file
18959         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
18960
18961         $LCTL set_param fail_loc=0
18962         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
18963         $LCTL set_param fail_loc=0x411
18964         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
18965
18966         # LU-4201
18967         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
18968         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
18969 }
18970 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
18971
18972 test_220() { #LU-325
18973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18974         remote_ost_nodsh && skip "remote OST with nodsh"
18975         remote_mds_nodsh && skip "remote MDS with nodsh"
18976         remote_mgs_nodsh && skip "remote MGS with nodsh"
18977
18978         local OSTIDX=0
18979
18980         # create on MDT0000 so the last_id and next_id are correct
18981         mkdir_on_mdt0 $DIR/$tdir
18982         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
18983         OST=${OST%_UUID}
18984
18985         # on the mdt's osc
18986         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
18987         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
18988                         osp.$mdtosc_proc1.prealloc_last_id)
18989         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
18990                         osp.$mdtosc_proc1.prealloc_next_id)
18991
18992         $LFS df -i
18993
18994         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
18995         #define OBD_FAIL_OST_ENOINO              0x229
18996         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
18997         create_pool $FSNAME.$TESTNAME || return 1
18998         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
18999
19000         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19001
19002         MDSOBJS=$((last_id - next_id))
19003         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19004
19005         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19006         echo "OST still has $count kbytes free"
19007
19008         echo "create $MDSOBJS files @next_id..."
19009         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19010
19011         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19012                         osp.$mdtosc_proc1.prealloc_last_id)
19013         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19014                         osp.$mdtosc_proc1.prealloc_next_id)
19015
19016         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19017         $LFS df -i
19018
19019         echo "cleanup..."
19020
19021         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19022         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19023
19024         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19025                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19026         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19027                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19028         echo "unlink $MDSOBJS files @$next_id..."
19029         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19030 }
19031 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19032
19033 test_221() {
19034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19035
19036         dd if=`which date` of=$MOUNT/date oflag=sync
19037         chmod +x $MOUNT/date
19038
19039         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19040         $LCTL set_param fail_loc=0x80001401
19041
19042         $MOUNT/date > /dev/null
19043         rm -f $MOUNT/date
19044 }
19045 run_test 221 "make sure fault and truncate race to not cause OOM"
19046
19047 test_222a () {
19048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19049
19050         rm -rf $DIR/$tdir
19051         test_mkdir $DIR/$tdir
19052         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19053         createmany -o $DIR/$tdir/$tfile 10
19054         cancel_lru_locks mdc
19055         cancel_lru_locks osc
19056         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19057         $LCTL set_param fail_loc=0x31a
19058         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19059         $LCTL set_param fail_loc=0
19060         rm -r $DIR/$tdir
19061 }
19062 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19063
19064 test_222b () {
19065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19066
19067         rm -rf $DIR/$tdir
19068         test_mkdir $DIR/$tdir
19069         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19070         createmany -o $DIR/$tdir/$tfile 10
19071         cancel_lru_locks mdc
19072         cancel_lru_locks osc
19073         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19074         $LCTL set_param fail_loc=0x31a
19075         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19076         $LCTL set_param fail_loc=0
19077 }
19078 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19079
19080 test_223 () {
19081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19082
19083         rm -rf $DIR/$tdir
19084         test_mkdir $DIR/$tdir
19085         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19086         createmany -o $DIR/$tdir/$tfile 10
19087         cancel_lru_locks mdc
19088         cancel_lru_locks osc
19089         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19090         $LCTL set_param fail_loc=0x31b
19091         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19092         $LCTL set_param fail_loc=0
19093         rm -r $DIR/$tdir
19094 }
19095 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19096
19097 test_224a() { # LU-1039, MRP-303
19098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19099         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19100         $LCTL set_param fail_loc=0x508
19101         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19102         $LCTL set_param fail_loc=0
19103         df $DIR
19104 }
19105 run_test 224a "Don't panic on bulk IO failure"
19106
19107 test_224bd_sub() { # LU-1039, MRP-303
19108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19109         local timeout=$1
19110
19111         shift
19112         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19113
19114         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19115
19116         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19117         cancel_lru_locks osc
19118         set_checksums 0
19119         stack_trap "set_checksums $ORIG_CSUM" EXIT
19120         local at_max_saved=0
19121
19122         # adaptive timeouts may prevent seeing the issue
19123         if at_is_enabled; then
19124                 at_max_saved=$(at_max_get mds)
19125                 at_max_set 0 mds client
19126                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19127         fi
19128
19129         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19130         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19131         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19132
19133         do_facet ost1 $LCTL set_param fail_loc=0
19134         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19135         df $DIR
19136 }
19137
19138 test_224b() {
19139         test_224bd_sub 3 error "dd failed"
19140 }
19141 run_test 224b "Don't panic on bulk IO failure"
19142
19143 test_224c() { # LU-6441
19144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19145         remote_mds_nodsh && skip "remote MDS with nodsh"
19146
19147         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19148         save_writethrough $p
19149         set_cache writethrough on
19150
19151         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19152         local at_max=$($LCTL get_param -n at_max)
19153         local timeout=$($LCTL get_param -n timeout)
19154         local test_at="at_max"
19155         local param_at="$FSNAME.sys.at_max"
19156         local test_timeout="timeout"
19157         local param_timeout="$FSNAME.sys.timeout"
19158
19159         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19160
19161         set_persistent_param_and_check client "$test_at" "$param_at" 0
19162         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19163
19164         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19165         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19166         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19167         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19168         sync
19169         do_facet ost1 "$LCTL set_param fail_loc=0"
19170
19171         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19172         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19173                 $timeout
19174
19175         $LCTL set_param -n $pages_per_rpc
19176         restore_lustre_params < $p
19177         rm -f $p
19178 }
19179 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19180
19181 test_224d() { # LU-11169
19182         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19183 }
19184 run_test 224d "Don't corrupt data on bulk IO timeout"
19185
19186 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19187 test_225a () {
19188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19189         if [ -z ${MDSSURVEY} ]; then
19190                 skip_env "mds-survey not found"
19191         fi
19192         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19193                 skip "Need MDS version at least 2.2.51"
19194
19195         local mds=$(facet_host $SINGLEMDS)
19196         local target=$(do_nodes $mds 'lctl dl' |
19197                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19198
19199         local cmd1="file_count=1000 thrhi=4"
19200         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19201         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19202         local cmd="$cmd1 $cmd2 $cmd3"
19203
19204         rm -f ${TMP}/mds_survey*
19205         echo + $cmd
19206         eval $cmd || error "mds-survey with zero-stripe failed"
19207         cat ${TMP}/mds_survey*
19208         rm -f ${TMP}/mds_survey*
19209 }
19210 run_test 225a "Metadata survey sanity with zero-stripe"
19211
19212 test_225b () {
19213         if [ -z ${MDSSURVEY} ]; then
19214                 skip_env "mds-survey not found"
19215         fi
19216         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19217                 skip "Need MDS version at least 2.2.51"
19218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19219         remote_mds_nodsh && skip "remote MDS with nodsh"
19220         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19221                 skip_env "Need to mount OST to test"
19222         fi
19223
19224         local mds=$(facet_host $SINGLEMDS)
19225         local target=$(do_nodes $mds 'lctl dl' |
19226                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19227
19228         local cmd1="file_count=1000 thrhi=4"
19229         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19230         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19231         local cmd="$cmd1 $cmd2 $cmd3"
19232
19233         rm -f ${TMP}/mds_survey*
19234         echo + $cmd
19235         eval $cmd || error "mds-survey with stripe_count failed"
19236         cat ${TMP}/mds_survey*
19237         rm -f ${TMP}/mds_survey*
19238 }
19239 run_test 225b "Metadata survey sanity with stripe_count = 1"
19240
19241 mcreate_path2fid () {
19242         local mode=$1
19243         local major=$2
19244         local minor=$3
19245         local name=$4
19246         local desc=$5
19247         local path=$DIR/$tdir/$name
19248         local fid
19249         local rc
19250         local fid_path
19251
19252         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19253                 error "cannot create $desc"
19254
19255         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19256         rc=$?
19257         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19258
19259         fid_path=$($LFS fid2path $MOUNT $fid)
19260         rc=$?
19261         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19262
19263         [ "$path" == "$fid_path" ] ||
19264                 error "fid2path returned $fid_path, expected $path"
19265
19266         echo "pass with $path and $fid"
19267 }
19268
19269 test_226a () {
19270         rm -rf $DIR/$tdir
19271         mkdir -p $DIR/$tdir
19272
19273         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19274         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19275         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19276         mcreate_path2fid 0040666 0 0 dir "directory"
19277         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19278         mcreate_path2fid 0100666 0 0 file "regular file"
19279         mcreate_path2fid 0120666 0 0 link "symbolic link"
19280         mcreate_path2fid 0140666 0 0 sock "socket"
19281 }
19282 run_test 226a "call path2fid and fid2path on files of all type"
19283
19284 test_226b () {
19285         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19286
19287         local MDTIDX=1
19288
19289         rm -rf $DIR/$tdir
19290         mkdir -p $DIR/$tdir
19291         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19292                 error "create remote directory failed"
19293         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19294         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19295                                 "character special file (null)"
19296         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19297                                 "character special file (no device)"
19298         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19299         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19300                                 "block special file (loop)"
19301         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19302         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19303         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19304 }
19305 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19306
19307 test_226c () {
19308         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19309         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19310                 skip "Need MDS version at least 2.13.55"
19311
19312         local submnt=/mnt/submnt
19313         local srcfile=/etc/passwd
19314         local dstfile=$submnt/passwd
19315         local path
19316         local fid
19317
19318         rm -rf $DIR/$tdir
19319         rm -rf $submnt
19320         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19321                 error "create remote directory failed"
19322         mkdir -p $submnt || error "create $submnt failed"
19323         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19324                 error "mount $submnt failed"
19325         stack_trap "umount $submnt" EXIT
19326
19327         cp $srcfile $dstfile
19328         fid=$($LFS path2fid $dstfile)
19329         path=$($LFS fid2path $submnt "$fid")
19330         [ "$path" = "$dstfile" ] ||
19331                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19332 }
19333 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19334
19335 # LU-1299 Executing or running ldd on a truncated executable does not
19336 # cause an out-of-memory condition.
19337 test_227() {
19338         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19339         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19340
19341         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19342         chmod +x $MOUNT/date
19343
19344         $MOUNT/date > /dev/null
19345         ldd $MOUNT/date > /dev/null
19346         rm -f $MOUNT/date
19347 }
19348 run_test 227 "running truncated executable does not cause OOM"
19349
19350 # LU-1512 try to reuse idle OI blocks
19351 test_228a() {
19352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19353         remote_mds_nodsh && skip "remote MDS with nodsh"
19354         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19355
19356         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19357         local myDIR=$DIR/$tdir
19358
19359         mkdir -p $myDIR
19360         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19361         $LCTL set_param fail_loc=0x80001002
19362         createmany -o $myDIR/t- 10000
19363         $LCTL set_param fail_loc=0
19364         # The guard is current the largest FID holder
19365         touch $myDIR/guard
19366         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19367                     tr -d '[')
19368         local IDX=$(($SEQ % 64))
19369
19370         do_facet $SINGLEMDS sync
19371         # Make sure journal flushed.
19372         sleep 6
19373         local blk1=$(do_facet $SINGLEMDS \
19374                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19375                      grep Blockcount | awk '{print $4}')
19376
19377         # Remove old files, some OI blocks will become idle.
19378         unlinkmany $myDIR/t- 10000
19379         # Create new files, idle OI blocks should be reused.
19380         createmany -o $myDIR/t- 2000
19381         do_facet $SINGLEMDS sync
19382         # Make sure journal flushed.
19383         sleep 6
19384         local blk2=$(do_facet $SINGLEMDS \
19385                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19386                      grep Blockcount | awk '{print $4}')
19387
19388         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19389 }
19390 run_test 228a "try to reuse idle OI blocks"
19391
19392 test_228b() {
19393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19394         remote_mds_nodsh && skip "remote MDS with nodsh"
19395         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19396
19397         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19398         local myDIR=$DIR/$tdir
19399
19400         mkdir -p $myDIR
19401         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19402         $LCTL set_param fail_loc=0x80001002
19403         createmany -o $myDIR/t- 10000
19404         $LCTL set_param fail_loc=0
19405         # The guard is current the largest FID holder
19406         touch $myDIR/guard
19407         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19408                     tr -d '[')
19409         local IDX=$(($SEQ % 64))
19410
19411         do_facet $SINGLEMDS sync
19412         # Make sure journal flushed.
19413         sleep 6
19414         local blk1=$(do_facet $SINGLEMDS \
19415                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19416                      grep Blockcount | awk '{print $4}')
19417
19418         # Remove old files, some OI blocks will become idle.
19419         unlinkmany $myDIR/t- 10000
19420
19421         # stop the MDT
19422         stop $SINGLEMDS || error "Fail to stop MDT."
19423         # remount the MDT
19424         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
19425
19426         df $MOUNT || error "Fail to df."
19427         # Create new files, idle OI blocks should be reused.
19428         createmany -o $myDIR/t- 2000
19429         do_facet $SINGLEMDS sync
19430         # Make sure journal flushed.
19431         sleep 6
19432         local blk2=$(do_facet $SINGLEMDS \
19433                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19434                      grep Blockcount | awk '{print $4}')
19435
19436         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19437 }
19438 run_test 228b "idle OI blocks can be reused after MDT restart"
19439
19440 #LU-1881
19441 test_228c() {
19442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19443         remote_mds_nodsh && skip "remote MDS with nodsh"
19444         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19445
19446         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19447         local myDIR=$DIR/$tdir
19448
19449         mkdir -p $myDIR
19450         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19451         $LCTL set_param fail_loc=0x80001002
19452         # 20000 files can guarantee there are index nodes in the OI file
19453         createmany -o $myDIR/t- 20000
19454         $LCTL set_param fail_loc=0
19455         # The guard is current the largest FID holder
19456         touch $myDIR/guard
19457         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19458                     tr -d '[')
19459         local IDX=$(($SEQ % 64))
19460
19461         do_facet $SINGLEMDS sync
19462         # Make sure journal flushed.
19463         sleep 6
19464         local blk1=$(do_facet $SINGLEMDS \
19465                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19466                      grep Blockcount | awk '{print $4}')
19467
19468         # Remove old files, some OI blocks will become idle.
19469         unlinkmany $myDIR/t- 20000
19470         rm -f $myDIR/guard
19471         # The OI file should become empty now
19472
19473         # Create new files, idle OI blocks should be reused.
19474         createmany -o $myDIR/t- 2000
19475         do_facet $SINGLEMDS sync
19476         # Make sure journal flushed.
19477         sleep 6
19478         local blk2=$(do_facet $SINGLEMDS \
19479                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19480                      grep Blockcount | awk '{print $4}')
19481
19482         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19483 }
19484 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19485
19486 test_229() { # LU-2482, LU-3448
19487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19488         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19489         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19490                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19491
19492         rm -f $DIR/$tfile
19493
19494         # Create a file with a released layout and stripe count 2.
19495         $MULTIOP $DIR/$tfile H2c ||
19496                 error "failed to create file with released layout"
19497
19498         $LFS getstripe -v $DIR/$tfile
19499
19500         local pattern=$($LFS getstripe -L $DIR/$tfile)
19501         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19502
19503         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19504                 error "getstripe"
19505         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19506         stat $DIR/$tfile || error "failed to stat released file"
19507
19508         chown $RUNAS_ID $DIR/$tfile ||
19509                 error "chown $RUNAS_ID $DIR/$tfile failed"
19510
19511         chgrp $RUNAS_ID $DIR/$tfile ||
19512                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19513
19514         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19515         rm $DIR/$tfile || error "failed to remove released file"
19516 }
19517 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19518
19519 test_230a() {
19520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19521         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19522         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19523                 skip "Need MDS version at least 2.11.52"
19524
19525         local MDTIDX=1
19526
19527         test_mkdir $DIR/$tdir
19528         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19529         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19530         [ $mdt_idx -ne 0 ] &&
19531                 error "create local directory on wrong MDT $mdt_idx"
19532
19533         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19534                         error "create remote directory failed"
19535         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19536         [ $mdt_idx -ne $MDTIDX ] &&
19537                 error "create remote directory on wrong MDT $mdt_idx"
19538
19539         createmany -o $DIR/$tdir/test_230/t- 10 ||
19540                 error "create files on remote directory failed"
19541         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19542         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19543         rm -r $DIR/$tdir || error "unlink remote directory failed"
19544 }
19545 run_test 230a "Create remote directory and files under the remote directory"
19546
19547 test_230b() {
19548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19549         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19550         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19551                 skip "Need MDS version at least 2.11.52"
19552
19553         local MDTIDX=1
19554         local mdt_index
19555         local i
19556         local file
19557         local pid
19558         local stripe_count
19559         local migrate_dir=$DIR/$tdir/migrate_dir
19560         local other_dir=$DIR/$tdir/other_dir
19561
19562         test_mkdir $DIR/$tdir
19563         test_mkdir -i0 -c1 $migrate_dir
19564         test_mkdir -i0 -c1 $other_dir
19565         for ((i=0; i<10; i++)); do
19566                 mkdir -p $migrate_dir/dir_${i}
19567                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19568                         error "create files under remote dir failed $i"
19569         done
19570
19571         cp /etc/passwd $migrate_dir/$tfile
19572         cp /etc/passwd $other_dir/$tfile
19573         chattr +SAD $migrate_dir
19574         chattr +SAD $migrate_dir/$tfile
19575
19576         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19577         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19578         local old_dir_mode=$(stat -c%f $migrate_dir)
19579         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19580
19581         mkdir -p $migrate_dir/dir_default_stripe2
19582         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19583         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19584
19585         mkdir -p $other_dir
19586         ln $migrate_dir/$tfile $other_dir/luna
19587         ln $migrate_dir/$tfile $migrate_dir/sofia
19588         ln $other_dir/$tfile $migrate_dir/david
19589         ln -s $migrate_dir/$tfile $other_dir/zachary
19590         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19591         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19592
19593         local len
19594         local lnktgt
19595
19596         # inline symlink
19597         for len in 58 59 60; do
19598                 lnktgt=$(str_repeat 'l' $len)
19599                 touch $migrate_dir/$lnktgt
19600                 ln -s $lnktgt $migrate_dir/${len}char_ln
19601         done
19602
19603         # PATH_MAX
19604         for len in 4094 4095; do
19605                 lnktgt=$(str_repeat 'l' $len)
19606                 ln -s $lnktgt $migrate_dir/${len}char_ln
19607         done
19608
19609         # NAME_MAX
19610         for len in 254 255; do
19611                 touch $migrate_dir/$(str_repeat 'l' $len)
19612         done
19613
19614         $LFS migrate -m $MDTIDX $migrate_dir ||
19615                 error "fails on migrating remote dir to MDT1"
19616
19617         echo "migratate to MDT1, then checking.."
19618         for ((i = 0; i < 10; i++)); do
19619                 for file in $(find $migrate_dir/dir_${i}); do
19620                         mdt_index=$($LFS getstripe -m $file)
19621                         # broken symlink getstripe will fail
19622                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19623                                 error "$file is not on MDT${MDTIDX}"
19624                 done
19625         done
19626
19627         # the multiple link file should still in MDT0
19628         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19629         [ $mdt_index == 0 ] ||
19630                 error "$file is not on MDT${MDTIDX}"
19631
19632         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19633         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19634                 error " expect $old_dir_flag get $new_dir_flag"
19635
19636         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19637         [ "$old_file_flag" = "$new_file_flag" ] ||
19638                 error " expect $old_file_flag get $new_file_flag"
19639
19640         local new_dir_mode=$(stat -c%f $migrate_dir)
19641         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19642                 error "expect mode $old_dir_mode get $new_dir_mode"
19643
19644         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19645         [ "$old_file_mode" = "$new_file_mode" ] ||
19646                 error "expect mode $old_file_mode get $new_file_mode"
19647
19648         diff /etc/passwd $migrate_dir/$tfile ||
19649                 error "$tfile different after migration"
19650
19651         diff /etc/passwd $other_dir/luna ||
19652                 error "luna different after migration"
19653
19654         diff /etc/passwd $migrate_dir/sofia ||
19655                 error "sofia different after migration"
19656
19657         diff /etc/passwd $migrate_dir/david ||
19658                 error "david different after migration"
19659
19660         diff /etc/passwd $other_dir/zachary ||
19661                 error "zachary different after migration"
19662
19663         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19664                 error "${tfile}_ln different after migration"
19665
19666         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19667                 error "${tfile}_ln_other different after migration"
19668
19669         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19670         [ $stripe_count = 2 ] ||
19671                 error "dir strpe_count $d != 2 after migration."
19672
19673         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19674         [ $stripe_count = 2 ] ||
19675                 error "file strpe_count $d != 2 after migration."
19676
19677         #migrate back to MDT0
19678         MDTIDX=0
19679
19680         $LFS migrate -m $MDTIDX $migrate_dir ||
19681                 error "fails on migrating remote dir to MDT0"
19682
19683         echo "migrate back to MDT0, checking.."
19684         for file in $(find $migrate_dir); do
19685                 mdt_index=$($LFS getstripe -m $file)
19686                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19687                         error "$file is not on MDT${MDTIDX}"
19688         done
19689
19690         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19691         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19692                 error " expect $old_dir_flag get $new_dir_flag"
19693
19694         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19695         [ "$old_file_flag" = "$new_file_flag" ] ||
19696                 error " expect $old_file_flag get $new_file_flag"
19697
19698         local new_dir_mode=$(stat -c%f $migrate_dir)
19699         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19700                 error "expect mode $old_dir_mode get $new_dir_mode"
19701
19702         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19703         [ "$old_file_mode" = "$new_file_mode" ] ||
19704                 error "expect mode $old_file_mode get $new_file_mode"
19705
19706         diff /etc/passwd ${migrate_dir}/$tfile ||
19707                 error "$tfile different after migration"
19708
19709         diff /etc/passwd ${other_dir}/luna ||
19710                 error "luna different after migration"
19711
19712         diff /etc/passwd ${migrate_dir}/sofia ||
19713                 error "sofia different after migration"
19714
19715         diff /etc/passwd ${other_dir}/zachary ||
19716                 error "zachary different after migration"
19717
19718         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19719                 error "${tfile}_ln different after migration"
19720
19721         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19722                 error "${tfile}_ln_other different after migration"
19723
19724         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19725         [ $stripe_count = 2 ] ||
19726                 error "dir strpe_count $d != 2 after migration."
19727
19728         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19729         [ $stripe_count = 2 ] ||
19730                 error "file strpe_count $d != 2 after migration."
19731
19732         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19733 }
19734 run_test 230b "migrate directory"
19735
19736 test_230c() {
19737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19738         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19739         remote_mds_nodsh && skip "remote MDS with nodsh"
19740         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19741                 skip "Need MDS version at least 2.11.52"
19742
19743         local MDTIDX=1
19744         local total=3
19745         local mdt_index
19746         local file
19747         local migrate_dir=$DIR/$tdir/migrate_dir
19748
19749         #If migrating directory fails in the middle, all entries of
19750         #the directory is still accessiable.
19751         test_mkdir $DIR/$tdir
19752         test_mkdir -i0 -c1 $migrate_dir
19753         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19754         stat $migrate_dir
19755         createmany -o $migrate_dir/f $total ||
19756                 error "create files under ${migrate_dir} failed"
19757
19758         # fail after migrating top dir, and this will fail only once, so the
19759         # first sub file migration will fail (currently f3), others succeed.
19760         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19761         do_facet mds1 lctl set_param fail_loc=0x1801
19762         local t=$(ls $migrate_dir | wc -l)
19763         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19764                 error "migrate should fail"
19765         local u=$(ls $migrate_dir | wc -l)
19766         [ "$u" == "$t" ] || error "$u != $t during migration"
19767
19768         # add new dir/file should succeed
19769         mkdir $migrate_dir/dir ||
19770                 error "mkdir failed under migrating directory"
19771         touch $migrate_dir/file ||
19772                 error "create file failed under migrating directory"
19773
19774         # add file with existing name should fail
19775         for file in $migrate_dir/f*; do
19776                 stat $file > /dev/null || error "stat $file failed"
19777                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19778                         error "open(O_CREAT|O_EXCL) $file should fail"
19779                 $MULTIOP $file m && error "create $file should fail"
19780                 touch $DIR/$tdir/remote_dir/$tfile ||
19781                         error "touch $tfile failed"
19782                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19783                         error "link $file should fail"
19784                 mdt_index=$($LFS getstripe -m $file)
19785                 if [ $mdt_index == 0 ]; then
19786                         # file failed to migrate is not allowed to rename to
19787                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19788                                 error "rename to $file should fail"
19789                 else
19790                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19791                                 error "rename to $file failed"
19792                 fi
19793                 echo hello >> $file || error "write $file failed"
19794         done
19795
19796         # resume migration with different options should fail
19797         $LFS migrate -m 0 $migrate_dir &&
19798                 error "migrate -m 0 $migrate_dir should fail"
19799
19800         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19801                 error "migrate -c 2 $migrate_dir should fail"
19802
19803         # resume migration should succeed
19804         $LFS migrate -m $MDTIDX $migrate_dir ||
19805                 error "migrate $migrate_dir failed"
19806
19807         echo "Finish migration, then checking.."
19808         for file in $(find $migrate_dir); do
19809                 mdt_index=$($LFS getstripe -m $file)
19810                 [ $mdt_index == $MDTIDX ] ||
19811                         error "$file is not on MDT${MDTIDX}"
19812         done
19813
19814         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19815 }
19816 run_test 230c "check directory accessiblity if migration failed"
19817
19818 test_230d() {
19819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19820         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19821         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19822                 skip "Need MDS version at least 2.11.52"
19823         # LU-11235
19824         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19825
19826         local migrate_dir=$DIR/$tdir/migrate_dir
19827         local old_index
19828         local new_index
19829         local old_count
19830         local new_count
19831         local new_hash
19832         local mdt_index
19833         local i
19834         local j
19835
19836         old_index=$((RANDOM % MDSCOUNT))
19837         old_count=$((MDSCOUNT - old_index))
19838         new_index=$((RANDOM % MDSCOUNT))
19839         new_count=$((MDSCOUNT - new_index))
19840         new_hash=1 # for all_char
19841
19842         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19843         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19844
19845         test_mkdir $DIR/$tdir
19846         test_mkdir -i $old_index -c $old_count $migrate_dir
19847
19848         for ((i=0; i<100; i++)); do
19849                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19850                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19851                         error "create files under remote dir failed $i"
19852         done
19853
19854         echo -n "Migrate from MDT$old_index "
19855         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19856         echo -n "to MDT$new_index"
19857         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19858         echo
19859
19860         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19861         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19862                 error "migrate remote dir error"
19863
19864         echo "Finish migration, then checking.."
19865         for file in $(find $migrate_dir -maxdepth 1); do
19866                 mdt_index=$($LFS getstripe -m $file)
19867                 if [ $mdt_index -lt $new_index ] ||
19868                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19869                         error "$file is on MDT$mdt_index"
19870                 fi
19871         done
19872
19873         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19874 }
19875 run_test 230d "check migrate big directory"
19876
19877 test_230e() {
19878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19879         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19880         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19881                 skip "Need MDS version at least 2.11.52"
19882
19883         local i
19884         local j
19885         local a_fid
19886         local b_fid
19887
19888         mkdir_on_mdt0 $DIR/$tdir
19889         mkdir $DIR/$tdir/migrate_dir
19890         mkdir $DIR/$tdir/other_dir
19891         touch $DIR/$tdir/migrate_dir/a
19892         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19893         ls $DIR/$tdir/other_dir
19894
19895         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19896                 error "migrate dir fails"
19897
19898         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19899         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19900
19901         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19902         [ $mdt_index == 0 ] || error "a is not on MDT0"
19903
19904         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19905                 error "migrate dir fails"
19906
19907         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19908         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19909
19910         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19911         [ $mdt_index == 1 ] || error "a is not on MDT1"
19912
19913         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19914         [ $mdt_index == 1 ] || error "b is not on MDT1"
19915
19916         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19917         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19918
19919         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19920
19921         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19922 }
19923 run_test 230e "migrate mulitple local link files"
19924
19925 test_230f() {
19926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19927         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19928         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19929                 skip "Need MDS version at least 2.11.52"
19930
19931         local a_fid
19932         local ln_fid
19933
19934         mkdir -p $DIR/$tdir
19935         mkdir $DIR/$tdir/migrate_dir
19936         $LFS mkdir -i1 $DIR/$tdir/other_dir
19937         touch $DIR/$tdir/migrate_dir/a
19938         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
19939         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
19940         ls $DIR/$tdir/other_dir
19941
19942         # a should be migrated to MDT1, since no other links on MDT0
19943         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19944                 error "#1 migrate dir fails"
19945         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19946         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19947         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19948         [ $mdt_index == 1 ] || error "a is not on MDT1"
19949
19950         # a should stay on MDT1, because it is a mulitple link file
19951         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19952                 error "#2 migrate dir fails"
19953         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19954         [ $mdt_index == 1 ] || error "a is not on MDT1"
19955
19956         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19957                 error "#3 migrate dir fails"
19958
19959         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19960         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
19961         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
19962
19963         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
19964         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
19965
19966         # a should be migrated to MDT0, since no other links on MDT1
19967         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19968                 error "#4 migrate dir fails"
19969         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19970         [ $mdt_index == 0 ] || error "a is not on MDT0"
19971
19972         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19973 }
19974 run_test 230f "migrate mulitple remote link files"
19975
19976 test_230g() {
19977         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19978         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19979         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19980                 skip "Need MDS version at least 2.11.52"
19981
19982         mkdir -p $DIR/$tdir/migrate_dir
19983
19984         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
19985                 error "migrating dir to non-exist MDT succeeds"
19986         true
19987 }
19988 run_test 230g "migrate dir to non-exist MDT"
19989
19990 test_230h() {
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 mdt_index
19997
19998         mkdir -p $DIR/$tdir/migrate_dir
19999
20000         $LFS migrate -m1 $DIR &&
20001                 error "migrating mountpoint1 should fail"
20002
20003         $LFS migrate -m1 $DIR/$tdir/.. &&
20004                 error "migrating mountpoint2 should fail"
20005
20006         # same as mv
20007         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20008                 error "migrating $tdir/migrate_dir/.. should fail"
20009
20010         true
20011 }
20012 run_test 230h "migrate .. and root"
20013
20014 test_230i() {
20015         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20016         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20017         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20018                 skip "Need MDS version at least 2.11.52"
20019
20020         mkdir -p $DIR/$tdir/migrate_dir
20021
20022         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20023                 error "migration fails with a tailing slash"
20024
20025         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20026                 error "migration fails with two tailing slashes"
20027 }
20028 run_test 230i "lfs migrate -m tolerates trailing slashes"
20029
20030 test_230j() {
20031         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20032         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20033                 skip "Need MDS version at least 2.11.52"
20034
20035         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20036         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20037                 error "create $tfile failed"
20038         cat /etc/passwd > $DIR/$tdir/$tfile
20039
20040         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20041
20042         cmp /etc/passwd $DIR/$tdir/$tfile ||
20043                 error "DoM file mismatch after migration"
20044 }
20045 run_test 230j "DoM file data not changed after dir migration"
20046
20047 test_230k() {
20048         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20049         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20050                 skip "Need MDS version at least 2.11.56"
20051
20052         local total=20
20053         local files_on_starting_mdt=0
20054
20055         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20056         $LFS getdirstripe $DIR/$tdir
20057         for i in $(seq $total); do
20058                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20059                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20060                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20061         done
20062
20063         echo "$files_on_starting_mdt files on MDT0"
20064
20065         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20066         $LFS getdirstripe $DIR/$tdir
20067
20068         files_on_starting_mdt=0
20069         for i in $(seq $total); do
20070                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20071                         error "file $tfile.$i mismatch after migration"
20072                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20073                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20074         done
20075
20076         echo "$files_on_starting_mdt files on MDT1 after migration"
20077         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20078
20079         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20080         $LFS getdirstripe $DIR/$tdir
20081
20082         files_on_starting_mdt=0
20083         for i in $(seq $total); do
20084                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20085                         error "file $tfile.$i mismatch after 2nd migration"
20086                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20087                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20088         done
20089
20090         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20091         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20092
20093         true
20094 }
20095 run_test 230k "file data not changed after dir migration"
20096
20097 test_230l() {
20098         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20099         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20100                 skip "Need MDS version at least 2.11.56"
20101
20102         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20103         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20104                 error "create files under remote dir failed $i"
20105         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20106 }
20107 run_test 230l "readdir between MDTs won't crash"
20108
20109 test_230m() {
20110         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20111         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20112                 skip "Need MDS version at least 2.11.56"
20113
20114         local MDTIDX=1
20115         local mig_dir=$DIR/$tdir/migrate_dir
20116         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20117         local shortstr="b"
20118         local val
20119
20120         echo "Creating files and dirs with xattrs"
20121         test_mkdir $DIR/$tdir
20122         test_mkdir -i0 -c1 $mig_dir
20123         mkdir $mig_dir/dir
20124         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20125                 error "cannot set xattr attr1 on dir"
20126         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20127                 error "cannot set xattr attr2 on dir"
20128         touch $mig_dir/dir/f0
20129         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20130                 error "cannot set xattr attr1 on file"
20131         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20132                 error "cannot set xattr attr2 on file"
20133         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20134         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20135         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20136         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20137         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20138         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20139         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20140         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20141         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20142
20143         echo "Migrating to MDT1"
20144         $LFS migrate -m $MDTIDX $mig_dir ||
20145                 error "fails on migrating dir to MDT1"
20146
20147         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20148         echo "Checking xattrs"
20149         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20150         [ "$val" = $longstr ] ||
20151                 error "expecting xattr1 $longstr on dir, found $val"
20152         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20153         [ "$val" = $shortstr ] ||
20154                 error "expecting xattr2 $shortstr on dir, found $val"
20155         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20156         [ "$val" = $longstr ] ||
20157                 error "expecting xattr1 $longstr on file, found $val"
20158         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20159         [ "$val" = $shortstr ] ||
20160                 error "expecting xattr2 $shortstr on file, found $val"
20161 }
20162 run_test 230m "xattrs not changed after dir migration"
20163
20164 test_230n() {
20165         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20166         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20167                 skip "Need MDS version at least 2.13.53"
20168
20169         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20170         cat /etc/hosts > $DIR/$tdir/$tfile
20171         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20172         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20173
20174         cmp /etc/hosts $DIR/$tdir/$tfile ||
20175                 error "File data mismatch after migration"
20176 }
20177 run_test 230n "Dir migration with mirrored file"
20178
20179 test_230o() {
20180         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20181         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20182                 skip "Need MDS version at least 2.13.52"
20183
20184         local mdts=$(comma_list $(mdts_nodes))
20185         local timeout=100
20186         local restripe_status
20187         local delta
20188         local i
20189
20190         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20191
20192         # in case "crush" hash type is not set
20193         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20194
20195         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20196                            mdt.*MDT0000.enable_dir_restripe)
20197         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20198         stack_trap "do_nodes $mdts $LCTL set_param \
20199                     mdt.*.enable_dir_restripe=$restripe_status"
20200
20201         mkdir $DIR/$tdir
20202         createmany -m $DIR/$tdir/f 100 ||
20203                 error "create files under remote dir failed $i"
20204         createmany -d $DIR/$tdir/d 100 ||
20205                 error "create dirs under remote dir failed $i"
20206
20207         for i in $(seq 2 $MDSCOUNT); do
20208                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20209                 $LFS setdirstripe -c $i $DIR/$tdir ||
20210                         error "split -c $i $tdir failed"
20211                 wait_update $HOSTNAME \
20212                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20213                         error "dir split not finished"
20214                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20215                         awk '/migrate/ {sum += $2} END { print sum }')
20216                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20217                 # delta is around total_files/stripe_count
20218                 (( $delta < 200 / (i - 1) + 4 )) ||
20219                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20220         done
20221 }
20222 run_test 230o "dir split"
20223
20224 test_230p() {
20225         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20226         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20227                 skip "Need MDS version at least 2.13.52"
20228
20229         local mdts=$(comma_list $(mdts_nodes))
20230         local timeout=100
20231         local restripe_status
20232         local delta
20233         local c
20234
20235         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20236
20237         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20238
20239         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20240                            mdt.*MDT0000.enable_dir_restripe)
20241         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20242         stack_trap "do_nodes $mdts $LCTL set_param \
20243                     mdt.*.enable_dir_restripe=$restripe_status"
20244
20245         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20246         createmany -m $DIR/$tdir/f 100 ||
20247                 error "create files under remote dir failed"
20248         createmany -d $DIR/$tdir/d 100 ||
20249                 error "create dirs under remote dir failed"
20250
20251         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20252                 local mdt_hash="crush"
20253
20254                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20255                 $LFS setdirstripe -c $c $DIR/$tdir ||
20256                         error "split -c $c $tdir failed"
20257                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20258                         mdt_hash="$mdt_hash,fixed"
20259                 elif [ $c -eq 1 ]; then
20260                         mdt_hash="none"
20261                 fi
20262                 wait_update $HOSTNAME \
20263                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20264                         error "dir merge not finished"
20265                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20266                         awk '/migrate/ {sum += $2} END { print sum }')
20267                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20268                 # delta is around total_files/stripe_count
20269                 (( delta < 200 / c + 4 )) ||
20270                         error "$delta files migrated >= $((200 / c + 4))"
20271         done
20272 }
20273 run_test 230p "dir merge"
20274
20275 test_230q() {
20276         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20277         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20278                 skip "Need MDS version at least 2.13.52"
20279
20280         local mdts=$(comma_list $(mdts_nodes))
20281         local saved_threshold=$(do_facet mds1 \
20282                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20283         local saved_delta=$(do_facet mds1 \
20284                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20285         local threshold=100
20286         local delta=2
20287         local total=0
20288         local stripe_count=0
20289         local stripe_index
20290         local nr_files
20291         local create
20292
20293         # test with fewer files on ZFS
20294         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20295
20296         stack_trap "do_nodes $mdts $LCTL set_param \
20297                     mdt.*.dir_split_count=$saved_threshold"
20298         stack_trap "do_nodes $mdts $LCTL set_param \
20299                     mdt.*.dir_split_delta=$saved_delta"
20300         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20301         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20302         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20303         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20304         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20305         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20306
20307         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20308         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20309
20310         create=$((threshold * 3 / 2))
20311         while [ $stripe_count -lt $MDSCOUNT ]; do
20312                 createmany -m $DIR/$tdir/f $total $create ||
20313                         error "create sub files failed"
20314                 stat $DIR/$tdir > /dev/null
20315                 total=$((total + create))
20316                 stripe_count=$((stripe_count + delta))
20317                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20318
20319                 wait_update $HOSTNAME \
20320                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20321                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20322
20323                 wait_update $HOSTNAME \
20324                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20325                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20326
20327                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20328                 echo "$nr_files/$total files on MDT$stripe_index after split"
20329                 # allow 10% margin of imbalance with crush hash
20330                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20331                         error "$nr_files files on MDT$stripe_index after split"
20332
20333                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20334                 [ $nr_files -eq $total ] ||
20335                         error "total sub files $nr_files != $total"
20336         done
20337
20338         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20339
20340         echo "fixed layout directory won't auto split"
20341         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20342         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20343                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20344         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20345                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20346 }
20347 run_test 230q "dir auto split"
20348
20349 test_230r() {
20350         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20351         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20352         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20353                 skip "Need MDS version at least 2.13.54"
20354
20355         # maximum amount of local locks:
20356         # parent striped dir - 2 locks
20357         # new stripe in parent to migrate to - 1 lock
20358         # source and target - 2 locks
20359         # Total 5 locks for regular file
20360         mkdir -p $DIR/$tdir
20361         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20362         touch $DIR/$tdir/dir1/eee
20363
20364         # create 4 hardlink for 4 more locks
20365         # Total: 9 locks > RS_MAX_LOCKS (8)
20366         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20367         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20368         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20369         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20370         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20371         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20372         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20373         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20374
20375         cancel_lru_locks mdc
20376
20377         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20378                 error "migrate dir fails"
20379
20380         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20381 }
20382 run_test 230r "migrate with too many local locks"
20383
20384 test_230s() {
20385         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
20386                 skip "Need MDS version at least 2.13.57"
20387
20388         local mdts=$(comma_list $(mdts_nodes))
20389         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20390                                 mdt.*MDT0000.enable_dir_restripe)
20391
20392         stack_trap "do_nodes $mdts $LCTL set_param \
20393                     mdt.*.enable_dir_restripe=$restripe_status"
20394
20395         local st
20396         for st in 0 1; do
20397                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20398                 test_mkdir $DIR/$tdir
20399                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20400                         error "$LFS mkdir doesn't return -EEXIST if target exists"
20401                 rmdir $DIR/$tdir
20402         done
20403 }
20404 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20405
20406 test_230t()
20407 {
20408         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20409         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20410                 skip "Need MDS version at least 2.14.50"
20411
20412         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20413         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20414         $LFS project -p 1 -s $DIR/$tdir ||
20415                 error "set $tdir project id failed"
20416         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20417                 error "set subdir project id failed"
20418         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20419 }
20420 run_test 230t "migrate directory with project ID set"
20421
20422 test_230u()
20423 {
20424         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20425         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20426                 skip "Need MDS version at least 2.14.53"
20427
20428         local count
20429
20430         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20431         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20432         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20433         for i in $(seq 0 $((MDSCOUNT - 1))); do
20434                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20435                 echo "$count dirs migrated to MDT$i"
20436         done
20437         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20438         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20439 }
20440 run_test 230u "migrate directory by QOS"
20441
20442 test_230v()
20443 {
20444         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20445         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20446                 skip "Need MDS version at least 2.14.53"
20447
20448         local count
20449
20450         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20451         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20452         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20453         for i in $(seq 0 $((MDSCOUNT - 1))); do
20454                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20455                 echo "$count subdirs migrated to MDT$i"
20456                 (( i == 3 )) && (( count > 0 )) &&
20457                         error "subdir shouldn't be migrated to MDT3"
20458         done
20459         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20460         (( count == 3 )) || error "dirs migrated to $count MDTs"
20461 }
20462 run_test 230v "subdir migrated to the MDT where its parent is located"
20463
20464 test_230w() {
20465         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20466         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20467                 skip "Need MDS version at least 2.14.53"
20468
20469         mkdir -p $DIR/$tdir/sub || error "mkdir failed"
20470
20471         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
20472                 error "migrate failed"
20473
20474         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
20475                 error "$tdir stripe count mismatch"
20476
20477         (( $($LFS getdirstripe -c $DIR/$tdir/sub) == 0 )) ||
20478                 error "$tdir/sub is striped"
20479 }
20480 run_test 230w "non-recursive mode dir migration"
20481
20482 test_231a()
20483 {
20484         # For simplicity this test assumes that max_pages_per_rpc
20485         # is the same across all OSCs
20486         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20487         local bulk_size=$((max_pages * PAGE_SIZE))
20488         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20489                                        head -n 1)
20490
20491         mkdir -p $DIR/$tdir
20492         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20493                 error "failed to set stripe with -S ${brw_size}M option"
20494
20495         # clear the OSC stats
20496         $LCTL set_param osc.*.stats=0 &>/dev/null
20497         stop_writeback
20498
20499         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20500         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20501                 oflag=direct &>/dev/null || error "dd failed"
20502
20503         sync; sleep 1; sync # just to be safe
20504         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20505         if [ x$nrpcs != "x1" ]; then
20506                 $LCTL get_param osc.*.stats
20507                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20508         fi
20509
20510         start_writeback
20511         # Drop the OSC cache, otherwise we will read from it
20512         cancel_lru_locks osc
20513
20514         # clear the OSC stats
20515         $LCTL set_param osc.*.stats=0 &>/dev/null
20516
20517         # Client reads $bulk_size.
20518         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20519                 iflag=direct &>/dev/null || error "dd failed"
20520
20521         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20522         if [ x$nrpcs != "x1" ]; then
20523                 $LCTL get_param osc.*.stats
20524                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20525         fi
20526 }
20527 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20528
20529 test_231b() {
20530         mkdir -p $DIR/$tdir
20531         local i
20532         for i in {0..1023}; do
20533                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20534                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20535                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20536         done
20537         sync
20538 }
20539 run_test 231b "must not assert on fully utilized OST request buffer"
20540
20541 test_232a() {
20542         mkdir -p $DIR/$tdir
20543         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20544
20545         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20546         do_facet ost1 $LCTL set_param fail_loc=0x31c
20547
20548         # ignore dd failure
20549         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20550
20551         do_facet ost1 $LCTL set_param fail_loc=0
20552         umount_client $MOUNT || error "umount failed"
20553         mount_client $MOUNT || error "mount failed"
20554         stop ost1 || error "cannot stop ost1"
20555         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20556 }
20557 run_test 232a "failed lock should not block umount"
20558
20559 test_232b() {
20560         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20561                 skip "Need MDS version at least 2.10.58"
20562
20563         mkdir -p $DIR/$tdir
20564         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20565         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20566         sync
20567         cancel_lru_locks osc
20568
20569         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20570         do_facet ost1 $LCTL set_param fail_loc=0x31c
20571
20572         # ignore failure
20573         $LFS data_version $DIR/$tdir/$tfile || true
20574
20575         do_facet ost1 $LCTL set_param fail_loc=0
20576         umount_client $MOUNT || error "umount failed"
20577         mount_client $MOUNT || error "mount failed"
20578         stop ost1 || error "cannot stop ost1"
20579         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20580 }
20581 run_test 232b "failed data version lock should not block umount"
20582
20583 test_233a() {
20584         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20585                 skip "Need MDS version at least 2.3.64"
20586         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20587
20588         local fid=$($LFS path2fid $MOUNT)
20589
20590         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20591                 error "cannot access $MOUNT using its FID '$fid'"
20592 }
20593 run_test 233a "checking that OBF of the FS root succeeds"
20594
20595 test_233b() {
20596         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20597                 skip "Need MDS version at least 2.5.90"
20598         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20599
20600         local fid=$($LFS path2fid $MOUNT/.lustre)
20601
20602         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20603                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20604
20605         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20606         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20607                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20608 }
20609 run_test 233b "checking that OBF of the FS .lustre succeeds"
20610
20611 test_234() {
20612         local p="$TMP/sanityN-$TESTNAME.parameters"
20613         save_lustre_params client "llite.*.xattr_cache" > $p
20614         lctl set_param llite.*.xattr_cache 1 ||
20615                 skip_env "xattr cache is not supported"
20616
20617         mkdir -p $DIR/$tdir || error "mkdir failed"
20618         touch $DIR/$tdir/$tfile || error "touch failed"
20619         # OBD_FAIL_LLITE_XATTR_ENOMEM
20620         $LCTL set_param fail_loc=0x1405
20621         getfattr -n user.attr $DIR/$tdir/$tfile &&
20622                 error "getfattr should have failed with ENOMEM"
20623         $LCTL set_param fail_loc=0x0
20624         rm -rf $DIR/$tdir
20625
20626         restore_lustre_params < $p
20627         rm -f $p
20628 }
20629 run_test 234 "xattr cache should not crash on ENOMEM"
20630
20631 test_235() {
20632         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20633                 skip "Need MDS version at least 2.4.52"
20634
20635         flock_deadlock $DIR/$tfile
20636         local RC=$?
20637         case $RC in
20638                 0)
20639                 ;;
20640                 124) error "process hangs on a deadlock"
20641                 ;;
20642                 *) error "error executing flock_deadlock $DIR/$tfile"
20643                 ;;
20644         esac
20645 }
20646 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20647
20648 #LU-2935
20649 test_236() {
20650         check_swap_layouts_support
20651
20652         local ref1=/etc/passwd
20653         local ref2=/etc/group
20654         local file1=$DIR/$tdir/f1
20655         local file2=$DIR/$tdir/f2
20656
20657         test_mkdir -c1 $DIR/$tdir
20658         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20659         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20660         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20661         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20662         local fd=$(free_fd)
20663         local cmd="exec $fd<>$file2"
20664         eval $cmd
20665         rm $file2
20666         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20667                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20668         cmd="exec $fd>&-"
20669         eval $cmd
20670         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20671
20672         #cleanup
20673         rm -rf $DIR/$tdir
20674 }
20675 run_test 236 "Layout swap on open unlinked file"
20676
20677 # LU-4659 linkea consistency
20678 test_238() {
20679         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20680                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20681                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20682                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20683
20684         touch $DIR/$tfile
20685         ln $DIR/$tfile $DIR/$tfile.lnk
20686         touch $DIR/$tfile.new
20687         mv $DIR/$tfile.new $DIR/$tfile
20688         local fid1=$($LFS path2fid $DIR/$tfile)
20689         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20690         local path1=$($LFS fid2path $FSNAME "$fid1")
20691         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20692         local path2=$($LFS fid2path $FSNAME "$fid2")
20693         [ $tfile.lnk == $path2 ] ||
20694                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20695         rm -f $DIR/$tfile*
20696 }
20697 run_test 238 "Verify linkea consistency"
20698
20699 test_239A() { # was test_239
20700         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20701                 skip "Need MDS version at least 2.5.60"
20702
20703         local list=$(comma_list $(mdts_nodes))
20704
20705         mkdir -p $DIR/$tdir
20706         createmany -o $DIR/$tdir/f- 5000
20707         unlinkmany $DIR/$tdir/f- 5000
20708         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20709                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20710         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20711                         osp.*MDT*.sync_in_flight" | calc_sum)
20712         [ "$changes" -eq 0 ] || error "$changes not synced"
20713 }
20714 run_test 239A "osp_sync test"
20715
20716 test_239a() { #LU-5297
20717         remote_mds_nodsh && skip "remote MDS with nodsh"
20718
20719         touch $DIR/$tfile
20720         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20721         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20722         chgrp $RUNAS_GID $DIR/$tfile
20723         wait_delete_completed
20724 }
20725 run_test 239a "process invalid osp sync record correctly"
20726
20727 test_239b() { #LU-5297
20728         remote_mds_nodsh && skip "remote MDS with nodsh"
20729
20730         touch $DIR/$tfile1
20731         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20732         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20733         chgrp $RUNAS_GID $DIR/$tfile1
20734         wait_delete_completed
20735         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20736         touch $DIR/$tfile2
20737         chgrp $RUNAS_GID $DIR/$tfile2
20738         wait_delete_completed
20739 }
20740 run_test 239b "process osp sync record with ENOMEM error correctly"
20741
20742 test_240() {
20743         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20744         remote_mds_nodsh && skip "remote MDS with nodsh"
20745
20746         mkdir -p $DIR/$tdir
20747
20748         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20749                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20750         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20751                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20752
20753         umount_client $MOUNT || error "umount failed"
20754         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20755         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20756         mount_client $MOUNT || error "failed to mount client"
20757
20758         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20759         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20760 }
20761 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20762
20763 test_241_bio() {
20764         local count=$1
20765         local bsize=$2
20766
20767         for LOOP in $(seq $count); do
20768                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20769                 cancel_lru_locks $OSC || true
20770         done
20771 }
20772
20773 test_241_dio() {
20774         local count=$1
20775         local bsize=$2
20776
20777         for LOOP in $(seq $1); do
20778                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20779                         2>/dev/null
20780         done
20781 }
20782
20783 test_241a() { # was test_241
20784         local bsize=$PAGE_SIZE
20785
20786         (( bsize < 40960 )) && bsize=40960
20787         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20788         ls -la $DIR/$tfile
20789         cancel_lru_locks $OSC
20790         test_241_bio 1000 $bsize &
20791         PID=$!
20792         test_241_dio 1000 $bsize
20793         wait $PID
20794 }
20795 run_test 241a "bio vs dio"
20796
20797 test_241b() {
20798         local bsize=$PAGE_SIZE
20799
20800         (( bsize < 40960 )) && bsize=40960
20801         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20802         ls -la $DIR/$tfile
20803         test_241_dio 1000 $bsize &
20804         PID=$!
20805         test_241_dio 1000 $bsize
20806         wait $PID
20807 }
20808 run_test 241b "dio vs dio"
20809
20810 test_242() {
20811         remote_mds_nodsh && skip "remote MDS with nodsh"
20812
20813         mkdir_on_mdt0 $DIR/$tdir
20814         touch $DIR/$tdir/$tfile
20815
20816         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20817         do_facet mds1 lctl set_param fail_loc=0x105
20818         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20819
20820         do_facet mds1 lctl set_param fail_loc=0
20821         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20822 }
20823 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20824
20825 test_243()
20826 {
20827         test_mkdir $DIR/$tdir
20828         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20829 }
20830 run_test 243 "various group lock tests"
20831
20832 test_244a()
20833 {
20834         test_mkdir $DIR/$tdir
20835         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20836         sendfile_grouplock $DIR/$tdir/$tfile || \
20837                 error "sendfile+grouplock failed"
20838         rm -rf $DIR/$tdir
20839 }
20840 run_test 244a "sendfile with group lock tests"
20841
20842 test_244b()
20843 {
20844         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20845
20846         local threads=50
20847         local size=$((1024*1024))
20848
20849         test_mkdir $DIR/$tdir
20850         for i in $(seq 1 $threads); do
20851                 local file=$DIR/$tdir/file_$((i / 10))
20852                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20853                 local pids[$i]=$!
20854         done
20855         for i in $(seq 1 $threads); do
20856                 wait ${pids[$i]}
20857         done
20858 }
20859 run_test 244b "multi-threaded write with group lock"
20860
20861 test_245() {
20862         local flagname="multi_mod_rpcs"
20863         local connect_data_name="max_mod_rpcs"
20864         local out
20865
20866         # check if multiple modify RPCs flag is set
20867         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20868                 grep "connect_flags:")
20869         echo "$out"
20870
20871         echo "$out" | grep -qw $flagname
20872         if [ $? -ne 0 ]; then
20873                 echo "connect flag $flagname is not set"
20874                 return
20875         fi
20876
20877         # check if multiple modify RPCs data is set
20878         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20879         echo "$out"
20880
20881         echo "$out" | grep -qw $connect_data_name ||
20882                 error "import should have connect data $connect_data_name"
20883 }
20884 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
20885
20886 cleanup_247() {
20887         local submount=$1
20888
20889         trap 0
20890         umount_client $submount
20891         rmdir $submount
20892 }
20893
20894 test_247a() {
20895         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20896                 grep -q subtree ||
20897                 skip_env "Fileset feature is not supported"
20898
20899         local submount=${MOUNT}_$tdir
20900
20901         mkdir $MOUNT/$tdir
20902         mkdir -p $submount || error "mkdir $submount failed"
20903         FILESET="$FILESET/$tdir" mount_client $submount ||
20904                 error "mount $submount failed"
20905         trap "cleanup_247 $submount" EXIT
20906         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
20907         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
20908                 error "read $MOUNT/$tdir/$tfile failed"
20909         cleanup_247 $submount
20910 }
20911 run_test 247a "mount subdir as fileset"
20912
20913 test_247b() {
20914         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20915                 skip_env "Fileset feature is not supported"
20916
20917         local submount=${MOUNT}_$tdir
20918
20919         rm -rf $MOUNT/$tdir
20920         mkdir -p $submount || error "mkdir $submount failed"
20921         SKIP_FILESET=1
20922         FILESET="$FILESET/$tdir" mount_client $submount &&
20923                 error "mount $submount should fail"
20924         rmdir $submount
20925 }
20926 run_test 247b "mount subdir that dose not exist"
20927
20928 test_247c() {
20929         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20930                 skip_env "Fileset feature is not supported"
20931
20932         local submount=${MOUNT}_$tdir
20933
20934         mkdir -p $MOUNT/$tdir/dir1
20935         mkdir -p $submount || error "mkdir $submount failed"
20936         trap "cleanup_247 $submount" EXIT
20937         FILESET="$FILESET/$tdir" mount_client $submount ||
20938                 error "mount $submount failed"
20939         local fid=$($LFS path2fid $MOUNT/)
20940         $LFS fid2path $submount $fid && error "fid2path should fail"
20941         cleanup_247 $submount
20942 }
20943 run_test 247c "running fid2path outside subdirectory root"
20944
20945 test_247d() {
20946         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20947                 skip "Fileset feature is not supported"
20948
20949         local submount=${MOUNT}_$tdir
20950
20951         mkdir -p $MOUNT/$tdir/dir1
20952         mkdir -p $submount || error "mkdir $submount failed"
20953         FILESET="$FILESET/$tdir" mount_client $submount ||
20954                 error "mount $submount failed"
20955         trap "cleanup_247 $submount" EXIT
20956
20957         local td=$submount/dir1
20958         local fid=$($LFS path2fid $td)
20959         [ -z "$fid" ] && error "path2fid unable to get $td FID"
20960
20961         # check that we get the same pathname back
20962         local rootpath
20963         local found
20964         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
20965                 echo "$rootpath $fid"
20966                 found=$($LFS fid2path $rootpath "$fid")
20967                 [ -n "found" ] || error "fid2path should succeed"
20968                 [ "$found" == "$td" ] || error "fid2path $found != $td"
20969         done
20970         # check wrong root path format
20971         rootpath=$submount"_wrong"
20972         found=$($LFS fid2path $rootpath "$fid")
20973         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
20974
20975         cleanup_247 $submount
20976 }
20977 run_test 247d "running fid2path inside subdirectory root"
20978
20979 # LU-8037
20980 test_247e() {
20981         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20982                 grep -q subtree ||
20983                 skip "Fileset feature is not supported"
20984
20985         local submount=${MOUNT}_$tdir
20986
20987         mkdir $MOUNT/$tdir
20988         mkdir -p $submount || error "mkdir $submount failed"
20989         FILESET="$FILESET/.." mount_client $submount &&
20990                 error "mount $submount should fail"
20991         rmdir $submount
20992 }
20993 run_test 247e "mount .. as fileset"
20994
20995 test_247f() {
20996         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20997         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20998                 skip "Need at least version 2.13.52"
20999         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21000                 skip "Need at least version 2.14.50"
21001         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21002                 grep -q subtree ||
21003                 skip "Fileset feature is not supported"
21004
21005         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21006         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21007                 error "mkdir remote failed"
21008         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21009                 error "mkdir remote/subdir failed"
21010         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21011                 error "mkdir striped failed"
21012         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21013
21014         local submount=${MOUNT}_$tdir
21015
21016         mkdir -p $submount || error "mkdir $submount failed"
21017         stack_trap "rmdir $submount"
21018
21019         local dir
21020         local stat
21021         local fileset=$FILESET
21022         local mdts=$(comma_list $(mdts_nodes))
21023
21024         stat=$(do_facet mds1 $LCTL get_param -n \
21025                 mdt.*MDT0000.enable_remote_subdir_mount)
21026         stack_trap "do_nodes $mdts $LCTL set_param \
21027                 mdt.*.enable_remote_subdir_mount=$stat"
21028
21029         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21030         stack_trap "umount_client $submount"
21031         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21032                 error "mount remote dir $dir should fail"
21033
21034         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21035                 $tdir/striped/. ; do
21036                 FILESET="$fileset/$dir" mount_client $submount ||
21037                         error "mount $dir failed"
21038                 umount_client $submount
21039         done
21040
21041         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21042         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21043                 error "mount $tdir/remote failed"
21044 }
21045 run_test 247f "mount striped or remote directory as fileset"
21046
21047 test_247g() {
21048         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21049         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21050                 skip "Need at least version 2.14.50"
21051
21052         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21053                 error "mkdir $tdir failed"
21054         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21055
21056         local submount=${MOUNT}_$tdir
21057
21058         mkdir -p $submount || error "mkdir $submount failed"
21059         stack_trap "rmdir $submount"
21060
21061         FILESET="$fileset/$tdir" mount_client $submount ||
21062                 error "mount $dir failed"
21063         stack_trap "umount $submount"
21064
21065         local mdts=$(comma_list $(mdts_nodes))
21066
21067         local nrpcs
21068
21069         stat $submount > /dev/null
21070         cancel_lru_locks $MDC
21071         stat $submount > /dev/null
21072         stat $submount/$tfile > /dev/null
21073         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21074         stat $submount/$tfile > /dev/null
21075         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21076                 awk '/getattr/ {sum += $2} END {print sum}')
21077
21078         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21079 }
21080 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21081
21082 test_248a() {
21083         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21084         [ -z "$fast_read_sav" ] && skip "no fast read support"
21085
21086         # create a large file for fast read verification
21087         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21088
21089         # make sure the file is created correctly
21090         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21091                 { rm -f $DIR/$tfile; skip "file creation error"; }
21092
21093         echo "Test 1: verify that fast read is 4 times faster on cache read"
21094
21095         # small read with fast read enabled
21096         $LCTL set_param -n llite.*.fast_read=1
21097         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21098                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21099                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21100         # small read with fast read disabled
21101         $LCTL set_param -n llite.*.fast_read=0
21102         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21103                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21104                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21105
21106         # verify that fast read is 4 times faster for cache read
21107         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21108                 error_not_in_vm "fast read was not 4 times faster: " \
21109                            "$t_fast vs $t_slow"
21110
21111         echo "Test 2: verify the performance between big and small read"
21112         $LCTL set_param -n llite.*.fast_read=1
21113
21114         # 1k non-cache read
21115         cancel_lru_locks osc
21116         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21117                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21118                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21119
21120         # 1M non-cache read
21121         cancel_lru_locks osc
21122         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21123                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21124                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21125
21126         # verify that big IO is not 4 times faster than small IO
21127         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21128                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21129
21130         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21131         rm -f $DIR/$tfile
21132 }
21133 run_test 248a "fast read verification"
21134
21135 test_248b() {
21136         # Default short_io_bytes=16384, try both smaller and larger sizes.
21137         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21138         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21139         echo "bs=53248 count=113 normal buffered write"
21140         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21141                 error "dd of initial data file failed"
21142         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21143
21144         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21145         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21146                 error "dd with sync normal writes failed"
21147         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21148
21149         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21150         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21151                 error "dd with sync small writes failed"
21152         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21153
21154         cancel_lru_locks osc
21155
21156         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21157         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21158         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21159         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21160                 iflag=direct || error "dd with O_DIRECT small read failed"
21161         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21162         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21163                 error "compare $TMP/$tfile.1 failed"
21164
21165         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21166         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21167
21168         # just to see what the maximum tunable value is, and test parsing
21169         echo "test invalid parameter 2MB"
21170         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21171                 error "too-large short_io_bytes allowed"
21172         echo "test maximum parameter 512KB"
21173         # if we can set a larger short_io_bytes, run test regardless of version
21174         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21175                 # older clients may not allow setting it this large, that's OK
21176                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21177                         skip "Need at least client version 2.13.50"
21178                 error "medium short_io_bytes failed"
21179         fi
21180         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21181         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21182
21183         echo "test large parameter 64KB"
21184         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21185         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21186
21187         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21188         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21189                 error "dd with sync large writes failed"
21190         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21191
21192         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21193         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21194         num=$((113 * 4096 / PAGE_SIZE))
21195         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21196         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21197                 error "dd with O_DIRECT large writes failed"
21198         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21199                 error "compare $DIR/$tfile.3 failed"
21200
21201         cancel_lru_locks osc
21202
21203         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21204         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21205                 error "dd with O_DIRECT large read failed"
21206         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21207                 error "compare $TMP/$tfile.2 failed"
21208
21209         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21210         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21211                 error "dd with O_DIRECT large read failed"
21212         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21213                 error "compare $TMP/$tfile.3 failed"
21214 }
21215 run_test 248b "test short_io read and write for both small and large sizes"
21216
21217 test_249() { # LU-7890
21218         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21219                 skip "Need at least version 2.8.54"
21220
21221         rm -f $DIR/$tfile
21222         $LFS setstripe -c 1 $DIR/$tfile
21223         # Offset 2T == 4k * 512M
21224         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21225                 error "dd to 2T offset failed"
21226 }
21227 run_test 249 "Write above 2T file size"
21228
21229 test_250() {
21230         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21231          && skip "no 16TB file size limit on ZFS"
21232
21233         $LFS setstripe -c 1 $DIR/$tfile
21234         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21235         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21236         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21237         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21238                 conv=notrunc,fsync && error "append succeeded"
21239         return 0
21240 }
21241 run_test 250 "Write above 16T limit"
21242
21243 test_251() {
21244         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21245
21246         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21247         #Skip once - writing the first stripe will succeed
21248         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21249         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21250                 error "short write happened"
21251
21252         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21253         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21254                 error "short read happened"
21255
21256         rm -f $DIR/$tfile
21257 }
21258 run_test 251 "Handling short read and write correctly"
21259
21260 test_252() {
21261         remote_mds_nodsh && skip "remote MDS with nodsh"
21262         remote_ost_nodsh && skip "remote OST with nodsh"
21263         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21264                 skip_env "ldiskfs only test"
21265         fi
21266
21267         local tgt
21268         local dev
21269         local out
21270         local uuid
21271         local num
21272         local gen
21273
21274         # check lr_reader on OST0000
21275         tgt=ost1
21276         dev=$(facet_device $tgt)
21277         out=$(do_facet $tgt $LR_READER $dev)
21278         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21279         echo "$out"
21280         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21281         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21282                 error "Invalid uuid returned by $LR_READER on target $tgt"
21283         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21284
21285         # check lr_reader -c on MDT0000
21286         tgt=mds1
21287         dev=$(facet_device $tgt)
21288         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21289                 skip "$LR_READER does not support additional options"
21290         fi
21291         out=$(do_facet $tgt $LR_READER -c $dev)
21292         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21293         echo "$out"
21294         num=$(echo "$out" | grep -c "mdtlov")
21295         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21296                 error "Invalid number of mdtlov clients returned by $LR_READER"
21297         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21298
21299         # check lr_reader -cr on MDT0000
21300         out=$(do_facet $tgt $LR_READER -cr $dev)
21301         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21302         echo "$out"
21303         echo "$out" | grep -q "^reply_data:$" ||
21304                 error "$LR_READER should have returned 'reply_data' section"
21305         num=$(echo "$out" | grep -c "client_generation")
21306         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21307 }
21308 run_test 252 "check lr_reader tool"
21309
21310 test_253() {
21311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21312         remote_mds_nodsh && skip "remote MDS with nodsh"
21313         remote_mgs_nodsh && skip "remote MGS with nodsh"
21314
21315         local ostidx=0
21316         local rc=0
21317         local ost_name=$(ostname_from_index $ostidx)
21318
21319         # on the mdt's osc
21320         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21321         do_facet $SINGLEMDS $LCTL get_param -n \
21322                 osp.$mdtosc_proc1.reserved_mb_high ||
21323                 skip  "remote MDS does not support reserved_mb_high"
21324
21325         rm -rf $DIR/$tdir
21326         wait_mds_ost_sync
21327         wait_delete_completed
21328         mkdir $DIR/$tdir
21329
21330         pool_add $TESTNAME || error "Pool creation failed"
21331         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21332
21333         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21334                 error "Setstripe failed"
21335
21336         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21337
21338         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21339                     grep "watermarks")
21340         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21341
21342         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21343                         osp.$mdtosc_proc1.prealloc_status)
21344         echo "prealloc_status $oa_status"
21345
21346         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21347                 error "File creation should fail"
21348
21349         #object allocation was stopped, but we still able to append files
21350         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21351                 oflag=append || error "Append failed"
21352
21353         rm -f $DIR/$tdir/$tfile.0
21354
21355         # For this test, we want to delete the files we created to go out of
21356         # space but leave the watermark, so we remain nearly out of space
21357         ost_watermarks_enospc_delete_files $tfile $ostidx
21358
21359         wait_delete_completed
21360
21361         sleep_maxage
21362
21363         for i in $(seq 10 12); do
21364                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21365                         2>/dev/null || error "File creation failed after rm"
21366         done
21367
21368         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21369                         osp.$mdtosc_proc1.prealloc_status)
21370         echo "prealloc_status $oa_status"
21371
21372         if (( oa_status != 0 )); then
21373                 error "Object allocation still disable after rm"
21374         fi
21375 }
21376 run_test 253 "Check object allocation limit"
21377
21378 test_254() {
21379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21380         remote_mds_nodsh && skip "remote MDS with nodsh"
21381
21382         local mdt=$(facet_svc $SINGLEMDS)
21383
21384         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21385                 skip "MDS does not support changelog_size"
21386
21387         local cl_user
21388
21389         changelog_register || error "changelog_register failed"
21390
21391         changelog_clear 0 || error "changelog_clear failed"
21392
21393         local size1=$(do_facet $SINGLEMDS \
21394                       $LCTL get_param -n mdd.$mdt.changelog_size)
21395         echo "Changelog size $size1"
21396
21397         rm -rf $DIR/$tdir
21398         $LFS mkdir -i 0 $DIR/$tdir
21399         # change something
21400         mkdir -p $DIR/$tdir/pics/2008/zachy
21401         touch $DIR/$tdir/pics/2008/zachy/timestamp
21402         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21403         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21404         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21405         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21406         rm $DIR/$tdir/pics/desktop.jpg
21407
21408         local size2=$(do_facet $SINGLEMDS \
21409                       $LCTL get_param -n mdd.$mdt.changelog_size)
21410         echo "Changelog size after work $size2"
21411
21412         (( $size2 > $size1 )) ||
21413                 error "new Changelog size=$size2 less than old size=$size1"
21414 }
21415 run_test 254 "Check changelog size"
21416
21417 ladvise_no_type()
21418 {
21419         local type=$1
21420         local file=$2
21421
21422         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21423                 awk -F: '{print $2}' | grep $type > /dev/null
21424         if [ $? -ne 0 ]; then
21425                 return 0
21426         fi
21427         return 1
21428 }
21429
21430 ladvise_no_ioctl()
21431 {
21432         local file=$1
21433
21434         lfs ladvise -a willread $file > /dev/null 2>&1
21435         if [ $? -eq 0 ]; then
21436                 return 1
21437         fi
21438
21439         lfs ladvise -a willread $file 2>&1 |
21440                 grep "Inappropriate ioctl for device" > /dev/null
21441         if [ $? -eq 0 ]; then
21442                 return 0
21443         fi
21444         return 1
21445 }
21446
21447 percent() {
21448         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21449 }
21450
21451 # run a random read IO workload
21452 # usage: random_read_iops <filename> <filesize> <iosize>
21453 random_read_iops() {
21454         local file=$1
21455         local fsize=$2
21456         local iosize=${3:-4096}
21457
21458         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21459                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21460 }
21461
21462 drop_file_oss_cache() {
21463         local file="$1"
21464         local nodes="$2"
21465
21466         $LFS ladvise -a dontneed $file 2>/dev/null ||
21467                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21468 }
21469
21470 ladvise_willread_performance()
21471 {
21472         local repeat=10
21473         local average_origin=0
21474         local average_cache=0
21475         local average_ladvise=0
21476
21477         for ((i = 1; i <= $repeat; i++)); do
21478                 echo "Iter $i/$repeat: reading without willread hint"
21479                 cancel_lru_locks osc
21480                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21481                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21482                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21483                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21484
21485                 cancel_lru_locks osc
21486                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21487                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21488                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21489
21490                 cancel_lru_locks osc
21491                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21492                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21493                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21494                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21495                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21496         done
21497         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21498         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21499         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21500
21501         speedup_cache=$(percent $average_cache $average_origin)
21502         speedup_ladvise=$(percent $average_ladvise $average_origin)
21503
21504         echo "Average uncached read: $average_origin"
21505         echo "Average speedup with OSS cached read: " \
21506                 "$average_cache = +$speedup_cache%"
21507         echo "Average speedup with ladvise willread: " \
21508                 "$average_ladvise = +$speedup_ladvise%"
21509
21510         local lowest_speedup=20
21511         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
21512                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
21513                         "got $average_cache%. Skipping ladvise willread check."
21514                 return 0
21515         fi
21516
21517         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21518         # it is still good to run until then to exercise 'ladvise willread'
21519         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21520                 [ "$ost1_FSTYPE" = "zfs" ] &&
21521                 echo "osd-zfs does not support dontneed or drop_caches" &&
21522                 return 0
21523
21524         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21525         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
21526                 error_not_in_vm "Speedup with willread is less than " \
21527                         "$lowest_speedup%, got $average_ladvise%"
21528 }
21529
21530 test_255a() {
21531         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21532                 skip "lustre < 2.8.54 does not support ladvise "
21533         remote_ost_nodsh && skip "remote OST with nodsh"
21534
21535         stack_trap "rm -f $DIR/$tfile"
21536         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21537
21538         ladvise_no_type willread $DIR/$tfile &&
21539                 skip "willread ladvise is not supported"
21540
21541         ladvise_no_ioctl $DIR/$tfile &&
21542                 skip "ladvise ioctl is not supported"
21543
21544         local size_mb=100
21545         local size=$((size_mb * 1048576))
21546         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21547                 error "dd to $DIR/$tfile failed"
21548
21549         lfs ladvise -a willread $DIR/$tfile ||
21550                 error "Ladvise failed with no range argument"
21551
21552         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21553                 error "Ladvise failed with no -l or -e argument"
21554
21555         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21556                 error "Ladvise failed with only -e argument"
21557
21558         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21559                 error "Ladvise failed with only -l argument"
21560
21561         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21562                 error "End offset should not be smaller than start offset"
21563
21564         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21565                 error "End offset should not be equal to start offset"
21566
21567         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21568                 error "Ladvise failed with overflowing -s argument"
21569
21570         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21571                 error "Ladvise failed with overflowing -e argument"
21572
21573         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21574                 error "Ladvise failed with overflowing -l argument"
21575
21576         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21577                 error "Ladvise succeeded with conflicting -l and -e arguments"
21578
21579         echo "Synchronous ladvise should wait"
21580         local delay=4
21581 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21582         do_nodes $(comma_list $(osts_nodes)) \
21583                 $LCTL set_param fail_val=$delay fail_loc=0x237
21584
21585         local start_ts=$SECONDS
21586         lfs ladvise -a willread $DIR/$tfile ||
21587                 error "Ladvise failed with no range argument"
21588         local end_ts=$SECONDS
21589         local inteval_ts=$((end_ts - start_ts))
21590
21591         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21592                 error "Synchronous advice didn't wait reply"
21593         fi
21594
21595         echo "Asynchronous ladvise shouldn't wait"
21596         local start_ts=$SECONDS
21597         lfs ladvise -a willread -b $DIR/$tfile ||
21598                 error "Ladvise failed with no range argument"
21599         local end_ts=$SECONDS
21600         local inteval_ts=$((end_ts - start_ts))
21601
21602         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21603                 error "Asynchronous advice blocked"
21604         fi
21605
21606         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21607         ladvise_willread_performance
21608 }
21609 run_test 255a "check 'lfs ladvise -a willread'"
21610
21611 facet_meminfo() {
21612         local facet=$1
21613         local info=$2
21614
21615         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21616 }
21617
21618 test_255b() {
21619         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21620                 skip "lustre < 2.8.54 does not support ladvise "
21621         remote_ost_nodsh && skip "remote OST with nodsh"
21622
21623         stack_trap "rm -f $DIR/$tfile"
21624         lfs setstripe -c 1 -i 0 $DIR/$tfile
21625
21626         ladvise_no_type dontneed $DIR/$tfile &&
21627                 skip "dontneed ladvise is not supported"
21628
21629         ladvise_no_ioctl $DIR/$tfile &&
21630                 skip "ladvise ioctl is not supported"
21631
21632         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21633                 [ "$ost1_FSTYPE" = "zfs" ] &&
21634                 skip "zfs-osd does not support 'ladvise dontneed'"
21635
21636         local size_mb=100
21637         local size=$((size_mb * 1048576))
21638         # In order to prevent disturbance of other processes, only check 3/4
21639         # of the memory usage
21640         local kibibytes=$((size_mb * 1024 * 3 / 4))
21641
21642         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21643                 error "dd to $DIR/$tfile failed"
21644
21645         #force write to complete before dropping OST cache & checking memory
21646         sync
21647
21648         local total=$(facet_meminfo ost1 MemTotal)
21649         echo "Total memory: $total KiB"
21650
21651         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21652         local before_read=$(facet_meminfo ost1 Cached)
21653         echo "Cache used before read: $before_read KiB"
21654
21655         lfs ladvise -a willread $DIR/$tfile ||
21656                 error "Ladvise willread failed"
21657         local after_read=$(facet_meminfo ost1 Cached)
21658         echo "Cache used after read: $after_read KiB"
21659
21660         lfs ladvise -a dontneed $DIR/$tfile ||
21661                 error "Ladvise dontneed again failed"
21662         local no_read=$(facet_meminfo ost1 Cached)
21663         echo "Cache used after dontneed ladvise: $no_read KiB"
21664
21665         if [ $total -lt $((before_read + kibibytes)) ]; then
21666                 echo "Memory is too small, abort checking"
21667                 return 0
21668         fi
21669
21670         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21671                 error "Ladvise willread should use more memory" \
21672                         "than $kibibytes KiB"
21673         fi
21674
21675         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21676                 error "Ladvise dontneed should release more memory" \
21677                         "than $kibibytes KiB"
21678         fi
21679 }
21680 run_test 255b "check 'lfs ladvise -a dontneed'"
21681
21682 test_255c() {
21683         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21684                 skip "lustre < 2.10.50 does not support lockahead"
21685
21686         local ost1_imp=$(get_osc_import_name client ost1)
21687         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21688                          cut -d'.' -f2)
21689         local count
21690         local new_count
21691         local difference
21692         local i
21693         local rc
21694
21695         test_mkdir -p $DIR/$tdir
21696         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21697
21698         #test 10 returns only success/failure
21699         i=10
21700         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21701         rc=$?
21702         if [ $rc -eq 255 ]; then
21703                 error "Ladvise test${i} failed, ${rc}"
21704         fi
21705
21706         #test 11 counts lock enqueue requests, all others count new locks
21707         i=11
21708         count=$(do_facet ost1 \
21709                 $LCTL get_param -n ost.OSS.ost.stats)
21710         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21711
21712         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21713         rc=$?
21714         if [ $rc -eq 255 ]; then
21715                 error "Ladvise test${i} failed, ${rc}"
21716         fi
21717
21718         new_count=$(do_facet ost1 \
21719                 $LCTL get_param -n ost.OSS.ost.stats)
21720         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21721                    awk '{ print $2 }')
21722
21723         difference="$((new_count - count))"
21724         if [ $difference -ne $rc ]; then
21725                 error "Ladvise test${i}, bad enqueue count, returned " \
21726                       "${rc}, actual ${difference}"
21727         fi
21728
21729         for i in $(seq 12 21); do
21730                 # If we do not do this, we run the risk of having too many
21731                 # locks and starting lock cancellation while we are checking
21732                 # lock counts.
21733                 cancel_lru_locks osc
21734
21735                 count=$($LCTL get_param -n \
21736                        ldlm.namespaces.$imp_name.lock_unused_count)
21737
21738                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21739                 rc=$?
21740                 if [ $rc -eq 255 ]; then
21741                         error "Ladvise test ${i} failed, ${rc}"
21742                 fi
21743
21744                 new_count=$($LCTL get_param -n \
21745                        ldlm.namespaces.$imp_name.lock_unused_count)
21746                 difference="$((new_count - count))"
21747
21748                 # Test 15 output is divided by 100 to map down to valid return
21749                 if [ $i -eq 15 ]; then
21750                         rc="$((rc * 100))"
21751                 fi
21752
21753                 if [ $difference -ne $rc ]; then
21754                         error "Ladvise test ${i}, bad lock count, returned " \
21755                               "${rc}, actual ${difference}"
21756                 fi
21757         done
21758
21759         #test 22 returns only success/failure
21760         i=22
21761         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21762         rc=$?
21763         if [ $rc -eq 255 ]; then
21764                 error "Ladvise test${i} failed, ${rc}"
21765         fi
21766 }
21767 run_test 255c "suite of ladvise lockahead tests"
21768
21769 test_256() {
21770         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21771         remote_mds_nodsh && skip "remote MDS with nodsh"
21772         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21773         changelog_users $SINGLEMDS | grep "^cl" &&
21774                 skip "active changelog user"
21775
21776         local cl_user
21777         local cat_sl
21778         local mdt_dev
21779
21780         mdt_dev=$(mdsdevname 1)
21781         echo $mdt_dev
21782
21783         changelog_register || error "changelog_register failed"
21784
21785         rm -rf $DIR/$tdir
21786         mkdir_on_mdt0 $DIR/$tdir
21787
21788         changelog_clear 0 || error "changelog_clear failed"
21789
21790         # change something
21791         touch $DIR/$tdir/{1..10}
21792
21793         # stop the MDT
21794         stop $SINGLEMDS || error "Fail to stop MDT"
21795
21796         # remount the MDT
21797
21798         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
21799
21800         #after mount new plainllog is used
21801         touch $DIR/$tdir/{11..19}
21802         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21803         stack_trap "rm -f $tmpfile"
21804         cat_sl=$(do_facet $SINGLEMDS "sync; \
21805                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21806                  llog_reader $tmpfile | grep -c type=1064553b")
21807         do_facet $SINGLEMDS llog_reader $tmpfile
21808
21809         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21810
21811         changelog_clear 0 || error "changelog_clear failed"
21812
21813         cat_sl=$(do_facet $SINGLEMDS "sync; \
21814                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21815                  llog_reader $tmpfile | grep -c type=1064553b")
21816
21817         if (( cat_sl == 2 )); then
21818                 error "Empty plain llog was not deleted from changelog catalog"
21819         elif (( cat_sl != 1 )); then
21820                 error "Active plain llog shouldn't be deleted from catalog"
21821         fi
21822 }
21823 run_test 256 "Check llog delete for empty and not full state"
21824
21825 test_257() {
21826         remote_mds_nodsh && skip "remote MDS with nodsh"
21827         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21828                 skip "Need MDS version at least 2.8.55"
21829
21830         test_mkdir $DIR/$tdir
21831
21832         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21833                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21834         stat $DIR/$tdir
21835
21836 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21837         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21838         local facet=mds$((mdtidx + 1))
21839         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21840         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21841
21842         stop $facet || error "stop MDS failed"
21843         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21844                 error "start MDS fail"
21845         wait_recovery_complete $facet
21846 }
21847 run_test 257 "xattr locks are not lost"
21848
21849 # Verify we take the i_mutex when security requires it
21850 test_258a() {
21851 #define OBD_FAIL_IMUTEX_SEC 0x141c
21852         $LCTL set_param fail_loc=0x141c
21853         touch $DIR/$tfile
21854         chmod u+s $DIR/$tfile
21855         chmod a+rwx $DIR/$tfile
21856         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21857         RC=$?
21858         if [ $RC -ne 0 ]; then
21859                 error "error, failed to take i_mutex, rc=$?"
21860         fi
21861         rm -f $DIR/$tfile
21862 }
21863 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21864
21865 # Verify we do NOT take the i_mutex in the normal case
21866 test_258b() {
21867 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21868         $LCTL set_param fail_loc=0x141d
21869         touch $DIR/$tfile
21870         chmod a+rwx $DIR
21871         chmod a+rw $DIR/$tfile
21872         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21873         RC=$?
21874         if [ $RC -ne 0 ]; then
21875                 error "error, took i_mutex unnecessarily, rc=$?"
21876         fi
21877         rm -f $DIR/$tfile
21878
21879 }
21880 run_test 258b "verify i_mutex security behavior"
21881
21882 test_259() {
21883         local file=$DIR/$tfile
21884         local before
21885         local after
21886
21887         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21888
21889         stack_trap "rm -f $file" EXIT
21890
21891         wait_delete_completed
21892         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21893         echo "before: $before"
21894
21895         $LFS setstripe -i 0 -c 1 $file
21896         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21897         sync_all_data
21898         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21899         echo "after write: $after"
21900
21901 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
21902         do_facet ost1 $LCTL set_param fail_loc=0x2301
21903         $TRUNCATE $file 0
21904         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21905         echo "after truncate: $after"
21906
21907         stop ost1
21908         do_facet ost1 $LCTL set_param fail_loc=0
21909         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21910         sleep 2
21911         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21912         echo "after restart: $after"
21913         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
21914                 error "missing truncate?"
21915
21916         return 0
21917 }
21918 run_test 259 "crash at delayed truncate"
21919
21920 test_260() {
21921 #define OBD_FAIL_MDC_CLOSE               0x806
21922         $LCTL set_param fail_loc=0x80000806
21923         touch $DIR/$tfile
21924
21925 }
21926 run_test 260 "Check mdc_close fail"
21927
21928 ### Data-on-MDT sanity tests ###
21929 test_270a() {
21930         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21931                 skip "Need MDS version at least 2.10.55 for DoM"
21932
21933         # create DoM file
21934         local dom=$DIR/$tdir/dom_file
21935         local tmp=$DIR/$tdir/tmp_file
21936
21937         mkdir_on_mdt0 $DIR/$tdir
21938
21939         # basic checks for DoM component creation
21940         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
21941                 error "Can set MDT layout to non-first entry"
21942
21943         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
21944                 error "Can define multiple entries as MDT layout"
21945
21946         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
21947
21948         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
21949         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
21950         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
21951
21952         local mdtidx=$($LFS getstripe -m $dom)
21953         local mdtname=MDT$(printf %04x $mdtidx)
21954         local facet=mds$((mdtidx + 1))
21955         local space_check=1
21956
21957         # Skip free space checks with ZFS
21958         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
21959
21960         # write
21961         sync
21962         local size_tmp=$((65536 * 3))
21963         local mdtfree1=$(do_facet $facet \
21964                          lctl get_param -n osd*.*$mdtname.kbytesfree)
21965
21966         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21967         # check also direct IO along write
21968         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
21969         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21970         sync
21971         cmp $tmp $dom || error "file data is different"
21972         [ $(stat -c%s $dom) == $size_tmp ] ||
21973                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21974         if [ $space_check == 1 ]; then
21975                 local mdtfree2=$(do_facet $facet \
21976                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
21977
21978                 # increase in usage from by $size_tmp
21979                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21980                         error "MDT free space wrong after write: " \
21981                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21982         fi
21983
21984         # truncate
21985         local size_dom=10000
21986
21987         $TRUNCATE $dom $size_dom
21988         [ $(stat -c%s $dom) == $size_dom ] ||
21989                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
21990         if [ $space_check == 1 ]; then
21991                 mdtfree1=$(do_facet $facet \
21992                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21993                 # decrease in usage from $size_tmp to new $size_dom
21994                 [ $(($mdtfree1 - $mdtfree2)) -ge \
21995                   $(((size_tmp - size_dom) / 1024)) ] ||
21996                         error "MDT free space is wrong after truncate: " \
21997                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
21998         fi
21999
22000         # append
22001         cat $tmp >> $dom
22002         sync
22003         size_dom=$((size_dom + size_tmp))
22004         [ $(stat -c%s $dom) == $size_dom ] ||
22005                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22006         if [ $space_check == 1 ]; then
22007                 mdtfree2=$(do_facet $facet \
22008                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22009                 # increase in usage by $size_tmp from previous
22010                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22011                         error "MDT free space is wrong after append: " \
22012                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22013         fi
22014
22015         # delete
22016         rm $dom
22017         if [ $space_check == 1 ]; then
22018                 mdtfree1=$(do_facet $facet \
22019                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22020                 # decrease in usage by $size_dom from previous
22021                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22022                         error "MDT free space is wrong after removal: " \
22023                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22024         fi
22025
22026         # combined striping
22027         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22028                 error "Can't create DoM + OST striping"
22029
22030         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22031         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22032         # check also direct IO along write
22033         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22034         sync
22035         cmp $tmp $dom || error "file data is different"
22036         [ $(stat -c%s $dom) == $size_tmp ] ||
22037                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22038         rm $dom $tmp
22039
22040         return 0
22041 }
22042 run_test 270a "DoM: basic functionality tests"
22043
22044 test_270b() {
22045         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22046                 skip "Need MDS version at least 2.10.55"
22047
22048         local dom=$DIR/$tdir/dom_file
22049         local max_size=1048576
22050
22051         mkdir -p $DIR/$tdir
22052         $LFS setstripe -E $max_size -L mdt $dom
22053
22054         # truncate over the limit
22055         $TRUNCATE $dom $(($max_size + 1)) &&
22056                 error "successful truncate over the maximum size"
22057         # write over the limit
22058         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22059                 error "successful write over the maximum size"
22060         # append over the limit
22061         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22062         echo "12345" >> $dom && error "successful append over the maximum size"
22063         rm $dom
22064
22065         return 0
22066 }
22067 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22068
22069 test_270c() {
22070         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22071                 skip "Need MDS version at least 2.10.55"
22072
22073         mkdir -p $DIR/$tdir
22074         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22075
22076         # check files inherit DoM EA
22077         touch $DIR/$tdir/first
22078         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22079                 error "bad pattern"
22080         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22081                 error "bad stripe count"
22082         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22083                 error "bad stripe size"
22084
22085         # check directory inherits DoM EA and uses it as default
22086         mkdir $DIR/$tdir/subdir
22087         touch $DIR/$tdir/subdir/second
22088         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22089                 error "bad pattern in sub-directory"
22090         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22091                 error "bad stripe count in sub-directory"
22092         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22093                 error "bad stripe size in sub-directory"
22094         return 0
22095 }
22096 run_test 270c "DoM: DoM EA inheritance tests"
22097
22098 test_270d() {
22099         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22100                 skip "Need MDS version at least 2.10.55"
22101
22102         mkdir -p $DIR/$tdir
22103         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22104
22105         # inherit default DoM striping
22106         mkdir $DIR/$tdir/subdir
22107         touch $DIR/$tdir/subdir/f1
22108
22109         # change default directory striping
22110         $LFS setstripe -c 1 $DIR/$tdir/subdir
22111         touch $DIR/$tdir/subdir/f2
22112         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22113                 error "wrong default striping in file 2"
22114         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22115                 error "bad pattern in file 2"
22116         return 0
22117 }
22118 run_test 270d "DoM: change striping from DoM to RAID0"
22119
22120 test_270e() {
22121         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22122                 skip "Need MDS version at least 2.10.55"
22123
22124         mkdir -p $DIR/$tdir/dom
22125         mkdir -p $DIR/$tdir/norm
22126         DOMFILES=20
22127         NORMFILES=10
22128         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22129         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22130
22131         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22132         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22133
22134         # find DoM files by layout
22135         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22136         [ $NUM -eq  $DOMFILES ] ||
22137                 error "lfs find -L: found $NUM, expected $DOMFILES"
22138         echo "Test 1: lfs find 20 DOM files by layout: OK"
22139
22140         # there should be 1 dir with default DOM striping
22141         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22142         [ $NUM -eq  1 ] ||
22143                 error "lfs find -L: found $NUM, expected 1 dir"
22144         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22145
22146         # find DoM files by stripe size
22147         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22148         [ $NUM -eq  $DOMFILES ] ||
22149                 error "lfs find -S: found $NUM, expected $DOMFILES"
22150         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22151
22152         # find files by stripe offset except DoM files
22153         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22154         [ $NUM -eq  $NORMFILES ] ||
22155                 error "lfs find -i: found $NUM, expected $NORMFILES"
22156         echo "Test 5: lfs find no DOM files by stripe index: OK"
22157         return 0
22158 }
22159 run_test 270e "DoM: lfs find with DoM files test"
22160
22161 test_270f() {
22162         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22163                 skip "Need MDS version at least 2.10.55"
22164
22165         local mdtname=${FSNAME}-MDT0000-mdtlov
22166         local dom=$DIR/$tdir/dom_file
22167         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22168                                                 lod.$mdtname.dom_stripesize)
22169         local dom_limit=131072
22170
22171         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22172         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22173                                                 lod.$mdtname.dom_stripesize)
22174         [ ${dom_limit} -eq ${dom_current} ] ||
22175                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22176
22177         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22178         $LFS setstripe -d $DIR/$tdir
22179         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22180                 error "Can't set directory default striping"
22181
22182         # exceed maximum stripe size
22183         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22184                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22185         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22186                 error "Able to create DoM component size more than LOD limit"
22187
22188         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22189         dom_current=$(do_facet mds1 $LCTL get_param -n \
22190                                                 lod.$mdtname.dom_stripesize)
22191         [ 0 -eq ${dom_current} ] ||
22192                 error "Can't set zero DoM stripe limit"
22193         rm $dom
22194
22195         # attempt to create DoM file on server with disabled DoM should
22196         # remove DoM entry from layout and be succeed
22197         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22198                 error "Can't create DoM file (DoM is disabled)"
22199         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22200                 error "File has DoM component while DoM is disabled"
22201         rm $dom
22202
22203         # attempt to create DoM file with only DoM stripe should return error
22204         $LFS setstripe -E $dom_limit -L mdt $dom &&
22205                 error "Able to create DoM-only file while DoM is disabled"
22206
22207         # too low values to be aligned with smallest stripe size 64K
22208         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22209         dom_current=$(do_facet mds1 $LCTL get_param -n \
22210                                                 lod.$mdtname.dom_stripesize)
22211         [ 30000 -eq ${dom_current} ] &&
22212                 error "Can set too small DoM stripe limit"
22213
22214         # 64K is a minimal stripe size in Lustre, expect limit of that size
22215         [ 65536 -eq ${dom_current} ] ||
22216                 error "Limit is not set to 64K but ${dom_current}"
22217
22218         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22219         dom_current=$(do_facet mds1 $LCTL get_param -n \
22220                                                 lod.$mdtname.dom_stripesize)
22221         echo $dom_current
22222         [ 2147483648 -eq ${dom_current} ] &&
22223                 error "Can set too large DoM stripe limit"
22224
22225         do_facet mds1 $LCTL set_param -n \
22226                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22227         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22228                 error "Can't create DoM component size after limit change"
22229         do_facet mds1 $LCTL set_param -n \
22230                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22231         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22232                 error "Can't create DoM file after limit decrease"
22233         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22234                 error "Can create big DoM component after limit decrease"
22235         touch ${dom}_def ||
22236                 error "Can't create file with old default layout"
22237
22238         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22239         return 0
22240 }
22241 run_test 270f "DoM: maximum DoM stripe size checks"
22242
22243 test_270g() {
22244         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22245                 skip "Need MDS version at least 2.13.52"
22246         local dom=$DIR/$tdir/$tfile
22247
22248         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22249         local lodname=${FSNAME}-MDT0000-mdtlov
22250
22251         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22252         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22253         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22254         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22255
22256         local dom_limit=1024
22257         local dom_threshold="50%"
22258
22259         $LFS setstripe -d $DIR/$tdir
22260         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22261                 error "Can't set directory default striping"
22262
22263         do_facet mds1 $LCTL set_param -n \
22264                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22265         # set 0 threshold and create DOM file to change tunable stripesize
22266         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22267         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22268                 error "Failed to create $dom file"
22269         # now tunable dom_cur_stripesize should reach maximum
22270         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22271                                         lod.${lodname}.dom_stripesize_cur_kb)
22272         [[ $dom_current == $dom_limit ]] ||
22273                 error "Current DOM stripesize is not maximum"
22274         rm $dom
22275
22276         # set threshold for further tests
22277         do_facet mds1 $LCTL set_param -n \
22278                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22279         echo "DOM threshold is $dom_threshold free space"
22280         local dom_def
22281         local dom_set
22282         # Spoof bfree to exceed threshold
22283         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22284         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22285         for spfree in 40 20 0 15 30 55; do
22286                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22287                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22288                         error "Failed to create $dom file"
22289                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22290                                         lod.${lodname}.dom_stripesize_cur_kb)
22291                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22292                 [[ $dom_def != $dom_current ]] ||
22293                         error "Default stripe size was not changed"
22294                 if [[ $spfree > 0 ]] ; then
22295                         dom_set=$($LFS getstripe -S $dom)
22296                         [[ $dom_set == $((dom_def * 1024)) ]] ||
22297                                 error "DOM component size is still old"
22298                 else
22299                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22300                                 error "DoM component is set with no free space"
22301                 fi
22302                 rm $dom
22303                 dom_current=$dom_def
22304         done
22305 }
22306 run_test 270g "DoM: default DoM stripe size depends on free space"
22307
22308 test_270h() {
22309         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22310                 skip "Need MDS version at least 2.13.53"
22311
22312         local mdtname=${FSNAME}-MDT0000-mdtlov
22313         local dom=$DIR/$tdir/$tfile
22314         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22315
22316         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22317         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22318
22319         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22320         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22321                 error "can't create OST file"
22322         # mirrored file with DOM entry in the second mirror
22323         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22324                 error "can't create mirror with DoM component"
22325
22326         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22327
22328         # DOM component in the middle and has other enries in the same mirror,
22329         # should succeed but lost DoM component
22330         $LFS setstripe --copy=${dom}_1 $dom ||
22331                 error "Can't create file from OST|DOM mirror layout"
22332         # check new file has no DoM layout after all
22333         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22334                 error "File has DoM component while DoM is disabled"
22335 }
22336 run_test 270h "DoM: DoM stripe removal when disabled on server"
22337
22338 test_270i() {
22339         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22340                 skip "Need MDS version at least 2.14.54"
22341
22342         mkdir $DIR/$tdir
22343         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22344                 error "setstripe should fail" || true
22345 }
22346 run_test 270i "DoM: setting invalid DoM striping should fail"
22347
22348 test_271a() {
22349         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22350                 skip "Need MDS version at least 2.10.55"
22351
22352         local dom=$DIR/$tdir/dom
22353
22354         mkdir -p $DIR/$tdir
22355
22356         $LFS setstripe -E 1024K -L mdt $dom
22357
22358         lctl set_param -n mdc.*.stats=clear
22359         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22360         cat $dom > /dev/null
22361         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22362         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22363         ls $dom
22364         rm -f $dom
22365 }
22366 run_test 271a "DoM: data is cached for read after write"
22367
22368 test_271b() {
22369         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22370                 skip "Need MDS version at least 2.10.55"
22371
22372         local dom=$DIR/$tdir/dom
22373
22374         mkdir -p $DIR/$tdir
22375
22376         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22377
22378         lctl set_param -n mdc.*.stats=clear
22379         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22380         cancel_lru_locks mdc
22381         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22382         # second stat to check size is cached on client
22383         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22384         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22385         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22386         rm -f $dom
22387 }
22388 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22389
22390 test_271ba() {
22391         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22392                 skip "Need MDS version at least 2.10.55"
22393
22394         local dom=$DIR/$tdir/dom
22395
22396         mkdir -p $DIR/$tdir
22397
22398         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22399
22400         lctl set_param -n mdc.*.stats=clear
22401         lctl set_param -n osc.*.stats=clear
22402         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22403         cancel_lru_locks mdc
22404         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22405         # second stat to check size is cached on client
22406         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22407         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22408         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22409         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22410         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22411         rm -f $dom
22412 }
22413 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22414
22415
22416 get_mdc_stats() {
22417         local mdtidx=$1
22418         local param=$2
22419         local mdt=MDT$(printf %04x $mdtidx)
22420
22421         if [ -z $param ]; then
22422                 lctl get_param -n mdc.*$mdt*.stats
22423         else
22424                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22425         fi
22426 }
22427
22428 test_271c() {
22429         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22430                 skip "Need MDS version at least 2.10.55"
22431
22432         local dom=$DIR/$tdir/dom
22433
22434         mkdir -p $DIR/$tdir
22435
22436         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22437
22438         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22439         local facet=mds$((mdtidx + 1))
22440
22441         cancel_lru_locks mdc
22442         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22443         createmany -o $dom 1000
22444         lctl set_param -n mdc.*.stats=clear
22445         smalliomany -w $dom 1000 200
22446         get_mdc_stats $mdtidx
22447         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22448         # Each file has 1 open, 1 IO enqueues, total 2000
22449         # but now we have also +1 getxattr for security.capability, total 3000
22450         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22451         unlinkmany $dom 1000
22452
22453         cancel_lru_locks mdc
22454         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22455         createmany -o $dom 1000
22456         lctl set_param -n mdc.*.stats=clear
22457         smalliomany -w $dom 1000 200
22458         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22459         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22460         # for OPEN and IO lock.
22461         [ $((enq - enq_2)) -ge 1000 ] ||
22462                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22463         unlinkmany $dom 1000
22464         return 0
22465 }
22466 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22467
22468 cleanup_271def_tests() {
22469         trap 0
22470         rm -f $1
22471 }
22472
22473 test_271d() {
22474         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22475                 skip "Need MDS version at least 2.10.57"
22476
22477         local dom=$DIR/$tdir/dom
22478         local tmp=$TMP/$tfile
22479         trap "cleanup_271def_tests $tmp" EXIT
22480
22481         mkdir -p $DIR/$tdir
22482
22483         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22484
22485         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22486
22487         cancel_lru_locks mdc
22488         dd if=/dev/urandom of=$tmp bs=1000 count=1
22489         dd if=$tmp of=$dom bs=1000 count=1
22490         cancel_lru_locks mdc
22491
22492         cat /etc/hosts >> $tmp
22493         lctl set_param -n mdc.*.stats=clear
22494
22495         # append data to the same file it should update local page
22496         echo "Append to the same page"
22497         cat /etc/hosts >> $dom
22498         local num=$(get_mdc_stats $mdtidx ost_read)
22499         local ra=$(get_mdc_stats $mdtidx req_active)
22500         local rw=$(get_mdc_stats $mdtidx req_waittime)
22501
22502         [ -z $num ] || error "$num READ RPC occured"
22503         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22504         echo "... DONE"
22505
22506         # compare content
22507         cmp $tmp $dom || error "file miscompare"
22508
22509         cancel_lru_locks mdc
22510         lctl set_param -n mdc.*.stats=clear
22511
22512         echo "Open and read file"
22513         cat $dom > /dev/null
22514         local num=$(get_mdc_stats $mdtidx ost_read)
22515         local ra=$(get_mdc_stats $mdtidx req_active)
22516         local rw=$(get_mdc_stats $mdtidx req_waittime)
22517
22518         [ -z $num ] || error "$num READ RPC occured"
22519         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22520         echo "... DONE"
22521
22522         # compare content
22523         cmp $tmp $dom || error "file miscompare"
22524
22525         return 0
22526 }
22527 run_test 271d "DoM: read on open (1K file in reply buffer)"
22528
22529 test_271f() {
22530         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22531                 skip "Need MDS version at least 2.10.57"
22532
22533         local dom=$DIR/$tdir/dom
22534         local tmp=$TMP/$tfile
22535         trap "cleanup_271def_tests $tmp" EXIT
22536
22537         mkdir -p $DIR/$tdir
22538
22539         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22540
22541         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22542
22543         cancel_lru_locks mdc
22544         dd if=/dev/urandom of=$tmp bs=265000 count=1
22545         dd if=$tmp of=$dom bs=265000 count=1
22546         cancel_lru_locks mdc
22547         cat /etc/hosts >> $tmp
22548         lctl set_param -n mdc.*.stats=clear
22549
22550         echo "Append to the same page"
22551         cat /etc/hosts >> $dom
22552         local num=$(get_mdc_stats $mdtidx ost_read)
22553         local ra=$(get_mdc_stats $mdtidx req_active)
22554         local rw=$(get_mdc_stats $mdtidx req_waittime)
22555
22556         [ -z $num ] || error "$num READ RPC occured"
22557         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22558         echo "... DONE"
22559
22560         # compare content
22561         cmp $tmp $dom || error "file miscompare"
22562
22563         cancel_lru_locks mdc
22564         lctl set_param -n mdc.*.stats=clear
22565
22566         echo "Open and read file"
22567         cat $dom > /dev/null
22568         local num=$(get_mdc_stats $mdtidx ost_read)
22569         local ra=$(get_mdc_stats $mdtidx req_active)
22570         local rw=$(get_mdc_stats $mdtidx req_waittime)
22571
22572         [ -z $num ] && num=0
22573         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22574         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22575         echo "... DONE"
22576
22577         # compare content
22578         cmp $tmp $dom || error "file miscompare"
22579
22580         return 0
22581 }
22582 run_test 271f "DoM: read on open (200K file and read tail)"
22583
22584 test_271g() {
22585         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22586                 skip "Skipping due to old client or server version"
22587
22588         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22589         # to get layout
22590         $CHECKSTAT -t file $DIR1/$tfile
22591
22592         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22593         MULTIOP_PID=$!
22594         sleep 1
22595         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22596         $LCTL set_param fail_loc=0x80000314
22597         rm $DIR1/$tfile || error "Unlink fails"
22598         RC=$?
22599         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22600         [ $RC -eq 0 ] || error "Failed write to stale object"
22601 }
22602 run_test 271g "Discard DoM data vs client flush race"
22603
22604 test_272a() {
22605         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22606                 skip "Need MDS version at least 2.11.50"
22607
22608         local dom=$DIR/$tdir/dom
22609         mkdir -p $DIR/$tdir
22610
22611         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22612         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22613                 error "failed to write data into $dom"
22614         local old_md5=$(md5sum $dom)
22615
22616         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22617                 error "failed to migrate to the same DoM component"
22618
22619         local new_md5=$(md5sum $dom)
22620
22621         [ "$old_md5" == "$new_md5" ] ||
22622                 error "md5sum differ: $old_md5, $new_md5"
22623
22624         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22625                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22626 }
22627 run_test 272a "DoM migration: new layout with the same DOM component"
22628
22629 test_272b() {
22630         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22631                 skip "Need MDS version at least 2.11.50"
22632
22633         local dom=$DIR/$tdir/dom
22634         mkdir -p $DIR/$tdir
22635         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22636
22637         local mdtidx=$($LFS getstripe -m $dom)
22638         local mdtname=MDT$(printf %04x $mdtidx)
22639         local facet=mds$((mdtidx + 1))
22640
22641         local mdtfree1=$(do_facet $facet \
22642                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22643         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22644                 error "failed to write data into $dom"
22645         local old_md5=$(md5sum $dom)
22646         cancel_lru_locks mdc
22647         local mdtfree1=$(do_facet $facet \
22648                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22649
22650         $LFS migrate -c2 $dom ||
22651                 error "failed to migrate to the new composite layout"
22652         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22653                 error "MDT stripe was not removed"
22654
22655         cancel_lru_locks mdc
22656         local new_md5=$(md5sum $dom)
22657         [ "$old_md5" == "$new_md5" ] ||
22658                 error "$old_md5 != $new_md5"
22659
22660         # Skip free space checks with ZFS
22661         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22662                 local mdtfree2=$(do_facet $facet \
22663                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22664                 [ $mdtfree2 -gt $mdtfree1 ] ||
22665                         error "MDT space is not freed after migration"
22666         fi
22667         return 0
22668 }
22669 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22670
22671 test_272c() {
22672         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22673                 skip "Need MDS version at least 2.11.50"
22674
22675         local dom=$DIR/$tdir/$tfile
22676         mkdir -p $DIR/$tdir
22677         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22678
22679         local mdtidx=$($LFS getstripe -m $dom)
22680         local mdtname=MDT$(printf %04x $mdtidx)
22681         local facet=mds$((mdtidx + 1))
22682
22683         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22684                 error "failed to write data into $dom"
22685         local old_md5=$(md5sum $dom)
22686         cancel_lru_locks mdc
22687         local mdtfree1=$(do_facet $facet \
22688                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22689
22690         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22691                 error "failed to migrate to the new composite layout"
22692         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22693                 error "MDT stripe was not removed"
22694
22695         cancel_lru_locks mdc
22696         local new_md5=$(md5sum $dom)
22697         [ "$old_md5" == "$new_md5" ] ||
22698                 error "$old_md5 != $new_md5"
22699
22700         # Skip free space checks with ZFS
22701         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22702                 local mdtfree2=$(do_facet $facet \
22703                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22704                 [ $mdtfree2 -gt $mdtfree1 ] ||
22705                         error "MDS space is not freed after migration"
22706         fi
22707         return 0
22708 }
22709 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22710
22711 test_272d() {
22712         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22713                 skip "Need MDS version at least 2.12.55"
22714
22715         local dom=$DIR/$tdir/$tfile
22716         mkdir -p $DIR/$tdir
22717         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22718
22719         local mdtidx=$($LFS getstripe -m $dom)
22720         local mdtname=MDT$(printf %04x $mdtidx)
22721         local facet=mds$((mdtidx + 1))
22722
22723         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22724                 error "failed to write data into $dom"
22725         local old_md5=$(md5sum $dom)
22726         cancel_lru_locks mdc
22727         local mdtfree1=$(do_facet $facet \
22728                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22729
22730         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22731                 error "failed mirroring to the new composite layout"
22732         $LFS mirror resync $dom ||
22733                 error "failed mirror resync"
22734         $LFS mirror split --mirror-id 1 -d $dom ||
22735                 error "failed mirror split"
22736
22737         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22738                 error "MDT stripe was not removed"
22739
22740         cancel_lru_locks mdc
22741         local new_md5=$(md5sum $dom)
22742         [ "$old_md5" == "$new_md5" ] ||
22743                 error "$old_md5 != $new_md5"
22744
22745         # Skip free space checks with ZFS
22746         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22747                 local mdtfree2=$(do_facet $facet \
22748                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22749                 [ $mdtfree2 -gt $mdtfree1 ] ||
22750                         error "MDS space is not freed after DOM mirror deletion"
22751         fi
22752         return 0
22753 }
22754 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22755
22756 test_272e() {
22757         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22758                 skip "Need MDS version at least 2.12.55"
22759
22760         local dom=$DIR/$tdir/$tfile
22761         mkdir -p $DIR/$tdir
22762         $LFS setstripe -c 2 $dom
22763
22764         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22765                 error "failed to write data into $dom"
22766         local old_md5=$(md5sum $dom)
22767         cancel_lru_locks
22768
22769         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22770                 error "failed mirroring to the DOM layout"
22771         $LFS mirror resync $dom ||
22772                 error "failed mirror resync"
22773         $LFS mirror split --mirror-id 1 -d $dom ||
22774                 error "failed mirror split"
22775
22776         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22777                 error "MDT stripe wasn't set"
22778
22779         cancel_lru_locks
22780         local new_md5=$(md5sum $dom)
22781         [ "$old_md5" == "$new_md5" ] ||
22782                 error "$old_md5 != $new_md5"
22783
22784         return 0
22785 }
22786 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22787
22788 test_272f() {
22789         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22790                 skip "Need MDS version at least 2.12.55"
22791
22792         local dom=$DIR/$tdir/$tfile
22793         mkdir -p $DIR/$tdir
22794         $LFS setstripe -c 2 $dom
22795
22796         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22797                 error "failed to write data into $dom"
22798         local old_md5=$(md5sum $dom)
22799         cancel_lru_locks
22800
22801         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22802                 error "failed migrating to the DOM file"
22803
22804         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22805                 error "MDT stripe wasn't set"
22806
22807         cancel_lru_locks
22808         local new_md5=$(md5sum $dom)
22809         [ "$old_md5" != "$new_md5" ] &&
22810                 error "$old_md5 != $new_md5"
22811
22812         return 0
22813 }
22814 run_test 272f "DoM migration: OST-striped file to DOM file"
22815
22816 test_273a() {
22817         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22818                 skip "Need MDS version at least 2.11.50"
22819
22820         # Layout swap cannot be done if either file has DOM component,
22821         # this will never be supported, migration should be used instead
22822
22823         local dom=$DIR/$tdir/$tfile
22824         mkdir -p $DIR/$tdir
22825
22826         $LFS setstripe -c2 ${dom}_plain
22827         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22828         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22829                 error "can swap layout with DoM component"
22830         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22831                 error "can swap layout with DoM component"
22832
22833         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22834         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22835                 error "can swap layout with DoM component"
22836         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22837                 error "can swap layout with DoM component"
22838         return 0
22839 }
22840 run_test 273a "DoM: layout swapping should fail with DOM"
22841
22842 test_273b() {
22843         mkdir -p $DIR/$tdir
22844         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22845
22846 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22847         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22848
22849         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22850 }
22851 run_test 273b "DoM: race writeback and object destroy"
22852
22853 test_275() {
22854         remote_ost_nodsh && skip "remote OST with nodsh"
22855         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22856                 skip "Need OST version >= 2.10.57"
22857
22858         local file=$DIR/$tfile
22859         local oss
22860
22861         oss=$(comma_list $(osts_nodes))
22862
22863         dd if=/dev/urandom of=$file bs=1M count=2 ||
22864                 error "failed to create a file"
22865         cancel_lru_locks osc
22866
22867         #lock 1
22868         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22869                 error "failed to read a file"
22870
22871 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22872         $LCTL set_param fail_loc=0x8000031f
22873
22874         cancel_lru_locks osc &
22875         sleep 1
22876
22877 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22878         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22879         #IO takes another lock, but matches the PENDING one
22880         #and places it to the IO RPC
22881         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22882                 error "failed to read a file with PENDING lock"
22883 }
22884 run_test 275 "Read on a canceled duplicate lock"
22885
22886 test_276() {
22887         remote_ost_nodsh && skip "remote OST with nodsh"
22888         local pid
22889
22890         do_facet ost1 "(while true; do \
22891                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22892                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22893         pid=$!
22894
22895         for LOOP in $(seq 20); do
22896                 stop ost1
22897                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22898         done
22899         kill -9 $pid
22900         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
22901                 rm $TMP/sanity_276_pid"
22902 }
22903 run_test 276 "Race between mount and obd_statfs"
22904
22905 test_277() {
22906         $LCTL set_param ldlm.namespaces.*.lru_size=0
22907         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22908         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22909                         grep ^used_mb | awk '{print $2}')
22910         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
22911         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
22912                 oflag=direct conv=notrunc
22913         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22914                         grep ^used_mb | awk '{print $2}')
22915         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
22916 }
22917 run_test 277 "Direct IO shall drop page cache"
22918
22919 test_278() {
22920         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22921         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22922         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
22923                 skip "needs the same host for mdt1 mdt2" && return
22924
22925         local pid1
22926         local pid2
22927
22928 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22929         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22930         stop mds2 &
22931         pid2=$!
22932
22933         stop mds1
22934
22935         echo "Starting MDTs"
22936         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22937         wait $pid2
22938 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
22939 #will return NULL
22940         do_facet mds2 $LCTL set_param fail_loc=0
22941
22942         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
22943         wait_recovery_complete mds2
22944 }
22945 run_test 278 "Race starting MDS between MDTs stop/start"
22946
22947 test_280() {
22948         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
22949                 skip "Need MGS version at least 2.13.52"
22950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22951         combined_mgs_mds || skip "needs combined MGS/MDT"
22952
22953         umount_client $MOUNT
22954 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
22955         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
22956
22957         mount_client $MOUNT &
22958         sleep 1
22959         stop mgs || error "stop mgs failed"
22960         #for a race mgs would crash
22961         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
22962         # make sure we unmount client before remounting
22963         wait
22964         umount_client $MOUNT
22965         mount_client $MOUNT || error "mount client failed"
22966 }
22967 run_test 280 "Race between MGS umount and client llog processing"
22968
22969 cleanup_test_300() {
22970         trap 0
22971         umask $SAVE_UMASK
22972 }
22973 test_striped_dir() {
22974         local mdt_index=$1
22975         local stripe_count
22976         local stripe_index
22977
22978         mkdir -p $DIR/$tdir
22979
22980         SAVE_UMASK=$(umask)
22981         trap cleanup_test_300 RETURN EXIT
22982
22983         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
22984                                                 $DIR/$tdir/striped_dir ||
22985                 error "set striped dir error"
22986
22987         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
22988         [ "$mode" = "755" ] || error "expect 755 got $mode"
22989
22990         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
22991                 error "getdirstripe failed"
22992         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
22993         if [ "$stripe_count" != "2" ]; then
22994                 error "1:stripe_count is $stripe_count, expect 2"
22995         fi
22996         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
22997         if [ "$stripe_count" != "2" ]; then
22998                 error "2:stripe_count is $stripe_count, expect 2"
22999         fi
23000
23001         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23002         if [ "$stripe_index" != "$mdt_index" ]; then
23003                 error "stripe_index is $stripe_index, expect $mdt_index"
23004         fi
23005
23006         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23007                 error "nlink error after create striped dir"
23008
23009         mkdir $DIR/$tdir/striped_dir/a
23010         mkdir $DIR/$tdir/striped_dir/b
23011
23012         stat $DIR/$tdir/striped_dir/a ||
23013                 error "create dir under striped dir failed"
23014         stat $DIR/$tdir/striped_dir/b ||
23015                 error "create dir under striped dir failed"
23016
23017         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23018                 error "nlink error after mkdir"
23019
23020         rmdir $DIR/$tdir/striped_dir/a
23021         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23022                 error "nlink error after rmdir"
23023
23024         rmdir $DIR/$tdir/striped_dir/b
23025         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23026                 error "nlink error after rmdir"
23027
23028         chattr +i $DIR/$tdir/striped_dir
23029         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23030                 error "immutable flags not working under striped dir!"
23031         chattr -i $DIR/$tdir/striped_dir
23032
23033         rmdir $DIR/$tdir/striped_dir ||
23034                 error "rmdir striped dir error"
23035
23036         cleanup_test_300
23037
23038         true
23039 }
23040
23041 test_300a() {
23042         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23043                 skip "skipped for lustre < 2.7.0"
23044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23045         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23046
23047         test_striped_dir 0 || error "failed on striped dir on MDT0"
23048         test_striped_dir 1 || error "failed on striped dir on MDT0"
23049 }
23050 run_test 300a "basic striped dir sanity test"
23051
23052 test_300b() {
23053         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23054                 skip "skipped for lustre < 2.7.0"
23055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23056         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23057
23058         local i
23059         local mtime1
23060         local mtime2
23061         local mtime3
23062
23063         test_mkdir $DIR/$tdir || error "mkdir fail"
23064         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23065                 error "set striped dir error"
23066         for i in {0..9}; do
23067                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23068                 sleep 1
23069                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23070                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23071                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23072                 sleep 1
23073                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23074                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23075                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23076         done
23077         true
23078 }
23079 run_test 300b "check ctime/mtime for striped dir"
23080
23081 test_300c() {
23082         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23083                 skip "skipped for lustre < 2.7.0"
23084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23085         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23086
23087         local file_count
23088
23089         mkdir_on_mdt0 $DIR/$tdir
23090         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23091                 error "set striped dir error"
23092
23093         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23094                 error "chown striped dir failed"
23095
23096         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23097                 error "create 5k files failed"
23098
23099         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23100
23101         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23102
23103         rm -rf $DIR/$tdir
23104 }
23105 run_test 300c "chown && check ls under striped directory"
23106
23107 test_300d() {
23108         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23109                 skip "skipped for lustre < 2.7.0"
23110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23111         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23112
23113         local stripe_count
23114         local file
23115
23116         mkdir -p $DIR/$tdir
23117         $LFS setstripe -c 2 $DIR/$tdir
23118
23119         #local striped directory
23120         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23121                 error "set striped dir error"
23122         #look at the directories for debug purposes
23123         ls -l $DIR/$tdir
23124         $LFS getdirstripe $DIR/$tdir
23125         ls -l $DIR/$tdir/striped_dir
23126         $LFS getdirstripe $DIR/$tdir/striped_dir
23127         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23128                 error "create 10 files failed"
23129
23130         #remote striped directory
23131         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23132                 error "set striped dir error"
23133         #look at the directories for debug purposes
23134         ls -l $DIR/$tdir
23135         $LFS getdirstripe $DIR/$tdir
23136         ls -l $DIR/$tdir/remote_striped_dir
23137         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23138         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23139                 error "create 10 files failed"
23140
23141         for file in $(find $DIR/$tdir); do
23142                 stripe_count=$($LFS getstripe -c $file)
23143                 [ $stripe_count -eq 2 ] ||
23144                         error "wrong stripe $stripe_count for $file"
23145         done
23146
23147         rm -rf $DIR/$tdir
23148 }
23149 run_test 300d "check default stripe under striped directory"
23150
23151 test_300e() {
23152         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23153                 skip "Need MDS version at least 2.7.55"
23154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23155         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23156
23157         local stripe_count
23158         local file
23159
23160         mkdir -p $DIR/$tdir
23161
23162         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23163                 error "set striped dir error"
23164
23165         touch $DIR/$tdir/striped_dir/a
23166         touch $DIR/$tdir/striped_dir/b
23167         touch $DIR/$tdir/striped_dir/c
23168
23169         mkdir $DIR/$tdir/striped_dir/dir_a
23170         mkdir $DIR/$tdir/striped_dir/dir_b
23171         mkdir $DIR/$tdir/striped_dir/dir_c
23172
23173         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23174                 error "set striped adir under striped dir error"
23175
23176         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23177                 error "set striped bdir under striped dir error"
23178
23179         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23180                 error "set striped cdir under striped dir error"
23181
23182         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23183                 error "rename dir under striped dir fails"
23184
23185         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23186                 error "rename dir under different stripes fails"
23187
23188         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23189                 error "rename file under striped dir should succeed"
23190
23191         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23192                 error "rename dir under striped dir should succeed"
23193
23194         rm -rf $DIR/$tdir
23195 }
23196 run_test 300e "check rename under striped directory"
23197
23198 test_300f() {
23199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23200         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23201         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23202                 skip "Need MDS version at least 2.7.55"
23203
23204         local stripe_count
23205         local file
23206
23207         rm -rf $DIR/$tdir
23208         mkdir -p $DIR/$tdir
23209
23210         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23211                 error "set striped dir error"
23212
23213         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23214                 error "set striped dir error"
23215
23216         touch $DIR/$tdir/striped_dir/a
23217         mkdir $DIR/$tdir/striped_dir/dir_a
23218         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23219                 error "create striped dir under striped dir fails"
23220
23221         touch $DIR/$tdir/striped_dir1/b
23222         mkdir $DIR/$tdir/striped_dir1/dir_b
23223         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23224                 error "create striped dir under striped dir fails"
23225
23226         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23227                 error "rename dir under different striped dir should fail"
23228
23229         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23230                 error "rename striped dir under diff striped dir should fail"
23231
23232         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23233                 error "rename file under diff striped dirs fails"
23234
23235         rm -rf $DIR/$tdir
23236 }
23237 run_test 300f "check rename cross striped directory"
23238
23239 test_300_check_default_striped_dir()
23240 {
23241         local dirname=$1
23242         local default_count=$2
23243         local default_index=$3
23244         local stripe_count
23245         local stripe_index
23246         local dir_stripe_index
23247         local dir
23248
23249         echo "checking $dirname $default_count $default_index"
23250         $LFS setdirstripe -D -c $default_count -i $default_index \
23251                                 -H all_char $DIR/$tdir/$dirname ||
23252                 error "set default stripe on striped dir error"
23253         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23254         [ $stripe_count -eq $default_count ] ||
23255                 error "expect $default_count get $stripe_count for $dirname"
23256
23257         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23258         [ $stripe_index -eq $default_index ] ||
23259                 error "expect $default_index get $stripe_index for $dirname"
23260
23261         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23262                                                 error "create dirs failed"
23263
23264         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23265         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23266         for dir in $(find $DIR/$tdir/$dirname/*); do
23267                 stripe_count=$($LFS getdirstripe -c $dir)
23268                 (( $stripe_count == $default_count )) ||
23269                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23270                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23271                 error "stripe count $default_count != $stripe_count for $dir"
23272
23273                 stripe_index=$($LFS getdirstripe -i $dir)
23274                 [ $default_index -eq -1 ] ||
23275                         [ $stripe_index -eq $default_index ] ||
23276                         error "$stripe_index != $default_index for $dir"
23277
23278                 #check default stripe
23279                 stripe_count=$($LFS getdirstripe -D -c $dir)
23280                 [ $stripe_count -eq $default_count ] ||
23281                 error "default count $default_count != $stripe_count for $dir"
23282
23283                 stripe_index=$($LFS getdirstripe -D -i $dir)
23284                 [ $stripe_index -eq $default_index ] ||
23285                 error "default index $default_index != $stripe_index for $dir"
23286         done
23287         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23288 }
23289
23290 test_300g() {
23291         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23292         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23293                 skip "Need MDS version at least 2.7.55"
23294
23295         local dir
23296         local stripe_count
23297         local stripe_index
23298
23299         mkdir_on_mdt0 $DIR/$tdir
23300         mkdir $DIR/$tdir/normal_dir
23301
23302         #Checking when client cache stripe index
23303         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23304         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23305                 error "create striped_dir failed"
23306
23307         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23308                 error "create dir0 fails"
23309         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23310         [ $stripe_index -eq 0 ] ||
23311                 error "dir0 expect index 0 got $stripe_index"
23312
23313         mkdir $DIR/$tdir/striped_dir/dir1 ||
23314                 error "create dir1 fails"
23315         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23316         [ $stripe_index -eq 1 ] ||
23317                 error "dir1 expect index 1 got $stripe_index"
23318
23319         #check default stripe count/stripe index
23320         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23321         test_300_check_default_striped_dir normal_dir 1 0
23322         test_300_check_default_striped_dir normal_dir -1 1
23323         test_300_check_default_striped_dir normal_dir 2 -1
23324
23325         #delete default stripe information
23326         echo "delete default stripeEA"
23327         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23328                 error "set default stripe on striped dir error"
23329
23330         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23331         for dir in $(find $DIR/$tdir/normal_dir/*); do
23332                 stripe_count=$($LFS getdirstripe -c $dir)
23333                 [ $stripe_count -eq 0 ] ||
23334                         error "expect 1 get $stripe_count for $dir"
23335         done
23336 }
23337 run_test 300g "check default striped directory for normal directory"
23338
23339 test_300h() {
23340         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23341         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23342                 skip "Need MDS version at least 2.7.55"
23343
23344         local dir
23345         local stripe_count
23346
23347         mkdir $DIR/$tdir
23348         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23349                 error "set striped dir error"
23350
23351         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23352         test_300_check_default_striped_dir striped_dir 1 0
23353         test_300_check_default_striped_dir striped_dir -1 1
23354         test_300_check_default_striped_dir striped_dir 2 -1
23355
23356         #delete default stripe information
23357         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23358                 error "set default stripe on striped dir error"
23359
23360         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23361         for dir in $(find $DIR/$tdir/striped_dir/*); do
23362                 stripe_count=$($LFS getdirstripe -c $dir)
23363                 [ $stripe_count -eq 0 ] ||
23364                         error "expect 1 get $stripe_count for $dir"
23365         done
23366 }
23367 run_test 300h "check default striped directory for striped directory"
23368
23369 test_300i() {
23370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23371         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23372         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23373                 skip "Need MDS version at least 2.7.55"
23374
23375         local stripe_count
23376         local file
23377
23378         mkdir $DIR/$tdir
23379
23380         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23381                 error "set striped dir error"
23382
23383         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23384                 error "create files under striped dir failed"
23385
23386         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23387                 error "set striped hashdir error"
23388
23389         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23390                 error "create dir0 under hash dir failed"
23391         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23392                 error "create dir1 under hash dir failed"
23393         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23394                 error "create dir2 under hash dir failed"
23395
23396         # unfortunately, we need to umount to clear dir layout cache for now
23397         # once we fully implement dir layout, we can drop this
23398         umount_client $MOUNT || error "umount failed"
23399         mount_client $MOUNT || error "mount failed"
23400
23401         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23402         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23403         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
23404
23405         #set the stripe to be unknown hash type
23406         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
23407         $LCTL set_param fail_loc=0x1901
23408         for ((i = 0; i < 10; i++)); do
23409                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23410                         error "stat f-$i failed"
23411                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23412         done
23413
23414         touch $DIR/$tdir/striped_dir/f0 &&
23415                 error "create under striped dir with unknown hash should fail"
23416
23417         $LCTL set_param fail_loc=0
23418
23419         umount_client $MOUNT || error "umount failed"
23420         mount_client $MOUNT || error "mount failed"
23421
23422         return 0
23423 }
23424 run_test 300i "client handle unknown hash type striped directory"
23425
23426 test_300j() {
23427         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23428         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23429         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23430                 skip "Need MDS version at least 2.7.55"
23431
23432         local stripe_count
23433         local file
23434
23435         mkdir $DIR/$tdir
23436
23437         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23438         $LCTL set_param fail_loc=0x1702
23439         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23440                 error "set striped dir error"
23441
23442         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23443                 error "create files under striped dir failed"
23444
23445         $LCTL set_param fail_loc=0
23446
23447         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23448
23449         return 0
23450 }
23451 run_test 300j "test large update record"
23452
23453 test_300k() {
23454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23455         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23456         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23457                 skip "Need MDS version at least 2.7.55"
23458
23459         # this test needs a huge transaction
23460         local kb
23461         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23462              osd*.$FSNAME-MDT0000.kbytestotal")
23463         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23464
23465         local stripe_count
23466         local file
23467
23468         mkdir $DIR/$tdir
23469
23470         #define OBD_FAIL_LARGE_STRIPE   0x1703
23471         $LCTL set_param fail_loc=0x1703
23472         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23473                 error "set striped dir error"
23474         $LCTL set_param fail_loc=0
23475
23476         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23477                 error "getstripeddir fails"
23478         rm -rf $DIR/$tdir/striped_dir ||
23479                 error "unlink striped dir fails"
23480
23481         return 0
23482 }
23483 run_test 300k "test large striped directory"
23484
23485 test_300l() {
23486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23487         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23488         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23489                 skip "Need MDS version at least 2.7.55"
23490
23491         local stripe_index
23492
23493         test_mkdir -p $DIR/$tdir/striped_dir
23494         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23495                         error "chown $RUNAS_ID failed"
23496         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23497                 error "set default striped dir failed"
23498
23499         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23500         $LCTL set_param fail_loc=0x80000158
23501         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23502
23503         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23504         [ $stripe_index -eq 1 ] ||
23505                 error "expect 1 get $stripe_index for $dir"
23506 }
23507 run_test 300l "non-root user to create dir under striped dir with stale layout"
23508
23509 test_300m() {
23510         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23511         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23512         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23513                 skip "Need MDS version at least 2.7.55"
23514
23515         mkdir -p $DIR/$tdir/striped_dir
23516         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23517                 error "set default stripes dir error"
23518
23519         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23520
23521         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23522         [ $stripe_count -eq 0 ] ||
23523                         error "expect 0 get $stripe_count for a"
23524
23525         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23526                 error "set default stripes dir error"
23527
23528         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23529
23530         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23531         [ $stripe_count -eq 0 ] ||
23532                         error "expect 0 get $stripe_count for b"
23533
23534         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23535                 error "set default stripes dir error"
23536
23537         mkdir $DIR/$tdir/striped_dir/c &&
23538                 error "default stripe_index is invalid, mkdir c should fails"
23539
23540         rm -rf $DIR/$tdir || error "rmdir fails"
23541 }
23542 run_test 300m "setstriped directory on single MDT FS"
23543
23544 cleanup_300n() {
23545         local list=$(comma_list $(mdts_nodes))
23546
23547         trap 0
23548         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23549 }
23550
23551 test_300n() {
23552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23553         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23554         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23555                 skip "Need MDS version at least 2.7.55"
23556         remote_mds_nodsh && skip "remote MDS with nodsh"
23557
23558         local stripe_index
23559         local list=$(comma_list $(mdts_nodes))
23560
23561         trap cleanup_300n RETURN EXIT
23562         mkdir -p $DIR/$tdir
23563         chmod 777 $DIR/$tdir
23564         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23565                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23566                 error "create striped dir succeeds with gid=0"
23567
23568         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23569         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23570                 error "create striped dir fails with gid=-1"
23571
23572         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23573         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23574                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23575                 error "set default striped dir succeeds with gid=0"
23576
23577
23578         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23579         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23580                 error "set default striped dir fails with gid=-1"
23581
23582
23583         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23584         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23585                                         error "create test_dir fails"
23586         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23587                                         error "create test_dir1 fails"
23588         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23589                                         error "create test_dir2 fails"
23590         cleanup_300n
23591 }
23592 run_test 300n "non-root user to create dir under striped dir with default EA"
23593
23594 test_300o() {
23595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23596         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23597         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23598                 skip "Need MDS version at least 2.7.55"
23599
23600         local numfree1
23601         local numfree2
23602
23603         mkdir -p $DIR/$tdir
23604
23605         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23606         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23607         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23608                 skip "not enough free inodes $numfree1 $numfree2"
23609         fi
23610
23611         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23612         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23613         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23614                 skip "not enough free space $numfree1 $numfree2"
23615         fi
23616
23617         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23618                 error "setdirstripe fails"
23619
23620         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23621                 error "create dirs fails"
23622
23623         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23624         ls $DIR/$tdir/striped_dir > /dev/null ||
23625                 error "ls striped dir fails"
23626         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23627                 error "unlink big striped dir fails"
23628 }
23629 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23630
23631 test_300p() {
23632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23633         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23634         remote_mds_nodsh && skip "remote MDS with nodsh"
23635
23636         mkdir_on_mdt0 $DIR/$tdir
23637
23638         #define OBD_FAIL_OUT_ENOSPC     0x1704
23639         do_facet mds2 lctl set_param fail_loc=0x80001704
23640         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23641                  && error "create striped directory should fail"
23642
23643         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23644
23645         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23646         true
23647 }
23648 run_test 300p "create striped directory without space"
23649
23650 test_300q() {
23651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23652         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23653
23654         local fd=$(free_fd)
23655         local cmd="exec $fd<$tdir"
23656         cd $DIR
23657         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23658         eval $cmd
23659         cmd="exec $fd<&-"
23660         trap "eval $cmd" EXIT
23661         cd $tdir || error "cd $tdir fails"
23662         rmdir  ../$tdir || error "rmdir $tdir fails"
23663         mkdir local_dir && error "create dir succeeds"
23664         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23665         eval $cmd
23666         return 0
23667 }
23668 run_test 300q "create remote directory under orphan directory"
23669
23670 test_300r() {
23671         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23672                 skip "Need MDS version at least 2.7.55" && return
23673         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23674
23675         mkdir $DIR/$tdir
23676
23677         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23678                 error "set striped dir error"
23679
23680         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23681                 error "getstripeddir fails"
23682
23683         local stripe_count
23684         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23685                       awk '/lmv_stripe_count:/ { print $2 }')
23686
23687         [ $MDSCOUNT -ne $stripe_count ] &&
23688                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23689
23690         rm -rf $DIR/$tdir/striped_dir ||
23691                 error "unlink striped dir fails"
23692 }
23693 run_test 300r "test -1 striped directory"
23694
23695 test_300s_helper() {
23696         local count=$1
23697
23698         local stripe_dir=$DIR/$tdir/striped_dir.$count
23699
23700         $LFS mkdir -c $count $stripe_dir ||
23701                 error "lfs mkdir -c error"
23702
23703         $LFS getdirstripe $stripe_dir ||
23704                 error "lfs getdirstripe fails"
23705
23706         local stripe_count
23707         stripe_count=$($LFS getdirstripe $stripe_dir |
23708                       awk '/lmv_stripe_count:/ { print $2 }')
23709
23710         [ $count -ne $stripe_count ] &&
23711                 error_noexit "bad stripe count $stripe_count expected $count"
23712
23713         local dupe_stripes
23714         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23715                 awk '/0x/ {count[$1] += 1}; END {
23716                         for (idx in count) {
23717                                 if (count[idx]>1) {
23718                                         print "index " idx " count " count[idx]
23719                                 }
23720                         }
23721                 }')
23722
23723         if [[ -n "$dupe_stripes" ]] ; then
23724                 lfs getdirstripe $stripe_dir
23725                 error_noexit "Dupe MDT above: $dupe_stripes "
23726         fi
23727
23728         rm -rf $stripe_dir ||
23729                 error_noexit "unlink $stripe_dir fails"
23730 }
23731
23732 test_300s() {
23733         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23734                 skip "Need MDS version at least 2.7.55" && return
23735         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23736
23737         mkdir $DIR/$tdir
23738         for count in $(seq 2 $MDSCOUNT); do
23739                 test_300s_helper $count
23740         done
23741 }
23742 run_test 300s "test lfs mkdir -c without -i"
23743
23744 test_300t() {
23745         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
23746                 skip "need MDS 2.14.55 or later"
23747         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
23748
23749         local testdir="$DIR/$tdir/striped_dir"
23750         local dir1=$testdir/dir1
23751         local dir2=$testdir/dir2
23752
23753         mkdir -p $testdir
23754
23755         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
23756                 error "failed to set default stripe count for $testdir"
23757
23758         mkdir $dir1
23759         local stripe_count=$($LFS getdirstripe -c $dir1)
23760
23761         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
23762
23763         local max_count=$((MDSCOUNT - 1))
23764         local mdts=$(comma_list $(mdts_nodes))
23765
23766         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
23767         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
23768
23769         mkdir $dir2
23770         stripe_count=$($LFS getdirstripe -c $dir2)
23771
23772         (( $stripe_count == $max_count )) || error "wrong stripe count"
23773 }
23774 run_test 300t "test max_mdt_stripecount"
23775
23776 prepare_remote_file() {
23777         mkdir $DIR/$tdir/src_dir ||
23778                 error "create remote source failed"
23779
23780         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23781                  error "cp to remote source failed"
23782         touch $DIR/$tdir/src_dir/a
23783
23784         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23785                 error "create remote target dir failed"
23786
23787         touch $DIR/$tdir/tgt_dir/b
23788
23789         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23790                 error "rename dir cross MDT failed!"
23791
23792         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23793                 error "src_child still exists after rename"
23794
23795         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23796                 error "missing file(a) after rename"
23797
23798         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
23799                 error "diff after rename"
23800 }
23801
23802 test_310a() {
23803         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23805
23806         local remote_file=$DIR/$tdir/tgt_dir/b
23807
23808         mkdir -p $DIR/$tdir
23809
23810         prepare_remote_file || error "prepare remote file failed"
23811
23812         #open-unlink file
23813         $OPENUNLINK $remote_file $remote_file ||
23814                 error "openunlink $remote_file failed"
23815         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23816 }
23817 run_test 310a "open unlink remote file"
23818
23819 test_310b() {
23820         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23821         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23822
23823         local remote_file=$DIR/$tdir/tgt_dir/b
23824
23825         mkdir -p $DIR/$tdir
23826
23827         prepare_remote_file || error "prepare remote file failed"
23828
23829         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23830         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23831         $CHECKSTAT -t file $remote_file || error "check file failed"
23832 }
23833 run_test 310b "unlink remote file with multiple links while open"
23834
23835 test_310c() {
23836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23837         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23838
23839         local remote_file=$DIR/$tdir/tgt_dir/b
23840
23841         mkdir -p $DIR/$tdir
23842
23843         prepare_remote_file || error "prepare remote file failed"
23844
23845         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23846         multiop_bg_pause $remote_file O_uc ||
23847                         error "mulitop failed for remote file"
23848         MULTIPID=$!
23849         $MULTIOP $DIR/$tfile Ouc
23850         kill -USR1 $MULTIPID
23851         wait $MULTIPID
23852 }
23853 run_test 310c "open-unlink remote file with multiple links"
23854
23855 #LU-4825
23856 test_311() {
23857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23858         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23859         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23860                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23861         remote_mds_nodsh && skip "remote MDS with nodsh"
23862
23863         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23864         local mdts=$(comma_list $(mdts_nodes))
23865
23866         mkdir -p $DIR/$tdir
23867         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23868         createmany -o $DIR/$tdir/$tfile. 1000
23869
23870         # statfs data is not real time, let's just calculate it
23871         old_iused=$((old_iused + 1000))
23872
23873         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23874                         osp.*OST0000*MDT0000.create_count")
23875         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23876                                 osp.*OST0000*MDT0000.max_create_count")
23877         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23878
23879         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23880         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23881         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23882
23883         unlinkmany $DIR/$tdir/$tfile. 1000
23884
23885         do_nodes $mdts "$LCTL set_param -n \
23886                         osp.*OST0000*.max_create_count=$max_count"
23887         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23888                 do_nodes $mdts "$LCTL set_param -n \
23889                                 osp.*OST0000*.create_count=$count"
23890         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23891                         grep "=0" && error "create_count is zero"
23892
23893         local new_iused
23894         for i in $(seq 120); do
23895                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23896                 # system may be too busy to destroy all objs in time, use
23897                 # a somewhat small value to not fail autotest
23898                 [ $((old_iused - new_iused)) -gt 400 ] && break
23899                 sleep 1
23900         done
23901
23902         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
23903         [ $((old_iused - new_iused)) -gt 400 ] ||
23904                 error "objs not destroyed after unlink"
23905 }
23906 run_test 311 "disable OSP precreate, and unlink should destroy objs"
23907
23908 zfs_oid_to_objid()
23909 {
23910         local ost=$1
23911         local objid=$2
23912
23913         local vdevdir=$(dirname $(facet_vdevice $ost))
23914         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
23915         local zfs_zapid=$(do_facet $ost $cmd |
23916                           grep -w "/O/0/d$((objid%32))" -C 5 |
23917                           awk '/Object/{getline; print $1}')
23918         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
23919                           awk "/$objid = /"'{printf $3}')
23920
23921         echo $zfs_objid
23922 }
23923
23924 zfs_object_blksz() {
23925         local ost=$1
23926         local objid=$2
23927
23928         local vdevdir=$(dirname $(facet_vdevice $ost))
23929         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
23930         local blksz=$(do_facet $ost $cmd $objid |
23931                       awk '/dblk/{getline; printf $4}')
23932
23933         case "${blksz: -1}" in
23934                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
23935                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
23936                 *) ;;
23937         esac
23938
23939         echo $blksz
23940 }
23941
23942 test_312() { # LU-4856
23943         remote_ost_nodsh && skip "remote OST with nodsh"
23944         [ "$ost1_FSTYPE" = "zfs" ] ||
23945                 skip_env "the test only applies to zfs"
23946
23947         local max_blksz=$(do_facet ost1 \
23948                           $ZFS get -p recordsize $(facet_device ost1) |
23949                           awk '!/VALUE/{print $3}')
23950
23951         # to make life a little bit easier
23952         $LFS mkdir -c 1 -i 0 $DIR/$tdir
23953         $LFS setstripe -c 1 -i 0 $DIR/$tdir
23954
23955         local tf=$DIR/$tdir/$tfile
23956         touch $tf
23957         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23958
23959         # Get ZFS object id
23960         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23961         # block size change by sequential overwrite
23962         local bs
23963
23964         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
23965                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
23966
23967                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
23968                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
23969         done
23970         rm -f $tf
23971
23972         # block size change by sequential append write
23973         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
23974         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23975         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23976         local count
23977
23978         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
23979                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
23980                         oflag=sync conv=notrunc
23981
23982                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
23983                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
23984                         error "blksz error, actual $blksz, " \
23985                                 "expected: 2 * $count * $PAGE_SIZE"
23986         done
23987         rm -f $tf
23988
23989         # random write
23990         touch $tf
23991         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23992         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23993
23994         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
23995         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23996         [ $blksz -eq $PAGE_SIZE ] ||
23997                 error "blksz error: $blksz, expected: $PAGE_SIZE"
23998
23999         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24000         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24001         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
24002
24003         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24004         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24005         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
24006 }
24007 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24008
24009 test_313() {
24010         remote_ost_nodsh && skip "remote OST with nodsh"
24011
24012         local file=$DIR/$tfile
24013
24014         rm -f $file
24015         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24016
24017         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24018         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24019         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24020                 error "write should failed"
24021         do_facet ost1 "$LCTL set_param fail_loc=0"
24022         rm -f $file
24023 }
24024 run_test 313 "io should fail after last_rcvd update fail"
24025
24026 test_314() {
24027         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24028
24029         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24030         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24031         rm -f $DIR/$tfile
24032         wait_delete_completed
24033         do_facet ost1 "$LCTL set_param fail_loc=0"
24034 }
24035 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24036
24037 test_315() { # LU-618
24038         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24039
24040         local file=$DIR/$tfile
24041         rm -f $file
24042
24043         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24044                 error "multiop file write failed"
24045         $MULTIOP $file oO_RDONLY:r4063232_c &
24046         PID=$!
24047
24048         sleep 2
24049
24050         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24051         kill -USR1 $PID
24052
24053         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24054         rm -f $file
24055 }
24056 run_test 315 "read should be accounted"
24057
24058 test_316() {
24059         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24060         large_xattr_enabled || skip_env "ea_inode feature disabled"
24061
24062         rm -rf $DIR/$tdir/d
24063         mkdir -p $DIR/$tdir/d
24064         chown nobody $DIR/$tdir/d
24065         touch $DIR/$tdir/d/file
24066
24067         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
24068 }
24069 run_test 316 "lfs mv"
24070
24071 test_317() {
24072         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24073                 skip "Need MDS version at least 2.11.53"
24074         if [ "$ost1_FSTYPE" == "zfs" ]; then
24075                 skip "LU-10370: no implementation for ZFS"
24076         fi
24077
24078         local trunc_sz
24079         local grant_blk_size
24080
24081         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24082                         awk '/grant_block_size:/ { print $2; exit; }')
24083         #
24084         # Create File of size 5M. Truncate it to below size's and verify
24085         # blocks count.
24086         #
24087         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24088                 error "Create file $DIR/$tfile failed"
24089         stack_trap "rm -f $DIR/$tfile" EXIT
24090
24091         for trunc_sz in 2097152 4097 4000 509 0; do
24092                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24093                         error "truncate $tfile to $trunc_sz failed"
24094                 local sz=$(stat --format=%s $DIR/$tfile)
24095                 local blk=$(stat --format=%b $DIR/$tfile)
24096                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24097                                      grant_blk_size) * 8))
24098
24099                 if [[ $blk -ne $trunc_blk ]]; then
24100                         $(which stat) $DIR/$tfile
24101                         error "Expected Block $trunc_blk got $blk for $tfile"
24102                 fi
24103
24104                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24105                         error "Expected Size $trunc_sz got $sz for $tfile"
24106         done
24107
24108         #
24109         # sparse file test
24110         # Create file with a hole and write actual 65536 bytes which aligned
24111         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24112         #
24113         local bs=65536
24114         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24115                 error "Create file : $DIR/$tfile"
24116
24117         #
24118         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24119         # blocks. The block count must drop to 8.
24120         #
24121         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - \
24122                 ((bs - grant_blk_size) + 1)))
24123         $TRUNCATE $DIR/$tfile $trunc_sz ||
24124                 error "truncate $tfile to $trunc_sz failed"
24125
24126         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24127         sz=$(stat --format=%s $DIR/$tfile)
24128         blk=$(stat --format=%b $DIR/$tfile)
24129
24130         if [[ $blk -ne $trunc_bsz ]]; then
24131                 $(which stat) $DIR/$tfile
24132                 error "Expected Block $trunc_bsz got $blk for $tfile"
24133         fi
24134
24135         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24136                 error "Expected Size $trunc_sz got $sz for $tfile"
24137 }
24138 run_test 317 "Verify blocks get correctly update after truncate"
24139
24140 test_318() {
24141         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24142         local old_max_active=$($LCTL get_param -n \
24143                             ${llite_name}.max_read_ahead_async_active \
24144                             2>/dev/null)
24145
24146         $LCTL set_param llite.*.max_read_ahead_async_active=256
24147         local max_active=$($LCTL get_param -n \
24148                            ${llite_name}.max_read_ahead_async_active \
24149                            2>/dev/null)
24150         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24151
24152         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24153                 error "set max_read_ahead_async_active should succeed"
24154
24155         $LCTL set_param llite.*.max_read_ahead_async_active=512
24156         max_active=$($LCTL get_param -n \
24157                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24158         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24159
24160         # restore @max_active
24161         [ $old_max_active -ne 0 ] && $LCTL set_param \
24162                 llite.*.max_read_ahead_async_active=$old_max_active
24163
24164         local old_threshold=$($LCTL get_param -n \
24165                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24166         local max_per_file_mb=$($LCTL get_param -n \
24167                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24168
24169         local invalid=$(($max_per_file_mb + 1))
24170         $LCTL set_param \
24171                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24172                         && error "set $invalid should fail"
24173
24174         local valid=$(($invalid - 1))
24175         $LCTL set_param \
24176                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24177                         error "set $valid should succeed"
24178         local threshold=$($LCTL get_param -n \
24179                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24180         [ $threshold -eq $valid ] || error \
24181                 "expect threshold $valid got $threshold"
24182         $LCTL set_param \
24183                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24184 }
24185 run_test 318 "Verify async readahead tunables"
24186
24187 test_319() {
24188         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
24189
24190         local before=$(date +%s)
24191         local evict
24192         local mdir=$DIR/$tdir
24193         local file=$mdir/xxx
24194
24195         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24196         touch $file
24197
24198 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24199         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24200         $LFS mv -m1 $file &
24201
24202         sleep 1
24203         dd if=$file of=/dev/null
24204         wait
24205         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24206           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24207
24208         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24209 }
24210 run_test 319 "lost lease lock on migrate error"
24211
24212 test_398a() { # LU-4198
24213         local ost1_imp=$(get_osc_import_name client ost1)
24214         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24215                          cut -d'.' -f2)
24216
24217         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24218         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24219
24220         # request a new lock on client
24221         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24222
24223         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24224         local lock_count=$($LCTL get_param -n \
24225                            ldlm.namespaces.$imp_name.lru_size)
24226         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24227
24228         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24229
24230         # no lock cached, should use lockless IO and not enqueue new lock
24231         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24232         lock_count=$($LCTL get_param -n \
24233                      ldlm.namespaces.$imp_name.lru_size)
24234         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24235 }
24236 run_test 398a "direct IO should cancel lock otherwise lockless"
24237
24238 test_398b() { # LU-4198
24239         which fio || skip_env "no fio installed"
24240         $LFS setstripe -c -1 $DIR/$tfile
24241
24242         local size=12
24243         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24244
24245         local njobs=4
24246         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
24247         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24248                 --numjobs=$njobs --fallocate=none \
24249                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24250                 --filename=$DIR/$tfile &
24251         bg_pid=$!
24252
24253         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
24254         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
24255                 --numjobs=$njobs --fallocate=none \
24256                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24257                 --filename=$DIR/$tfile || true
24258         wait $bg_pid
24259
24260         rm -f $DIR/$tfile
24261 }
24262 run_test 398b "DIO and buffer IO race"
24263
24264 test_398c() { # LU-4198
24265         local ost1_imp=$(get_osc_import_name client ost1)
24266         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24267                          cut -d'.' -f2)
24268
24269         which fio || skip_env "no fio installed"
24270
24271         saved_debug=$($LCTL get_param -n debug)
24272         $LCTL set_param debug=0
24273
24274         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24275         ((size /= 1024)) # by megabytes
24276         ((size /= 2)) # write half of the OST at most
24277         [ $size -gt 40 ] && size=40 #reduce test time anyway
24278
24279         $LFS setstripe -c 1 $DIR/$tfile
24280
24281         # it seems like ldiskfs reserves more space than necessary if the
24282         # writing blocks are not mapped, so it extends the file firstly
24283         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24284         cancel_lru_locks osc
24285
24286         # clear and verify rpc_stats later
24287         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24288
24289         local njobs=4
24290         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24291         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24292                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24293                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24294                 --filename=$DIR/$tfile
24295         [ $? -eq 0 ] || error "fio write error"
24296
24297         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24298                 error "Locks were requested while doing AIO"
24299
24300         # get the percentage of 1-page I/O
24301         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24302                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24303                 awk '{print $7}')
24304         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24305
24306         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24307         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24308                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24309                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24310                 --filename=$DIR/$tfile
24311         [ $? -eq 0 ] || error "fio mixed read write error"
24312
24313         echo "AIO with large block size ${size}M"
24314         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24315                 --numjobs=1 --fallocate=none --ioengine=libaio \
24316                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24317                 --filename=$DIR/$tfile
24318         [ $? -eq 0 ] || error "fio large block size failed"
24319
24320         rm -f $DIR/$tfile
24321         $LCTL set_param debug="$saved_debug"
24322 }
24323 run_test 398c "run fio to test AIO"
24324
24325 test_398d() { #  LU-13846
24326         which aiocp || skip_env "no aiocp installed"
24327         local aio_file=$DIR/$tfile.aio
24328
24329         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24330
24331         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24332         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24333         stack_trap "rm -f $DIR/$tfile $aio_file"
24334
24335         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24336
24337         # make sure we don't crash and fail properly
24338         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24339                 error "aio not aligned with PAGE SIZE should fail"
24340
24341         rm -f $DIR/$tfile $aio_file
24342 }
24343 run_test 398d "run aiocp to verify block size > stripe size"
24344
24345 test_398e() {
24346         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24347         touch $DIR/$tfile.new
24348         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24349 }
24350 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24351
24352 test_398f() { #  LU-14687
24353         which aiocp || skip_env "no aiocp installed"
24354         local aio_file=$DIR/$tfile.aio
24355
24356         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24357
24358         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24359         stack_trap "rm -f $DIR/$tfile $aio_file"
24360
24361         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24362         $LCTL set_param fail_loc=0x1418
24363         # make sure we don't crash and fail properly
24364         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24365                 error "aio with page allocation failure succeeded"
24366         $LCTL set_param fail_loc=0
24367         diff $DIR/$tfile $aio_file
24368         [[ $? != 0 ]] || error "no diff after failed aiocp"
24369 }
24370 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24371
24372 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24373 # stripe and i/o size must be > stripe size
24374 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24375 # single RPC in flight.  This test shows async DIO submission is working by
24376 # showing multiple RPCs in flight.
24377 test_398g() { #  LU-13798
24378         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24379
24380         # We need to do some i/o first to acquire enough grant to put our RPCs
24381         # in flight; otherwise a new connection may not have enough grant
24382         # available
24383         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24384                 error "parallel dio failed"
24385         stack_trap "rm -f $DIR/$tfile"
24386
24387         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24388         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24389         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24390         stack_trap "$LCTL set_param -n $pages_per_rpc"
24391
24392         # Recreate file so it's empty
24393         rm -f $DIR/$tfile
24394         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24395         #Pause rpc completion to guarantee we see multiple rpcs in flight
24396         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24397         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24398         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24399
24400         # Clear rpc stats
24401         $LCTL set_param osc.*.rpc_stats=c
24402
24403         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24404                 error "parallel dio failed"
24405         stack_trap "rm -f $DIR/$tfile"
24406
24407         $LCTL get_param osc.*-OST0000-*.rpc_stats
24408         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24409                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24410                 grep "8:" | awk '{print $8}')
24411         # We look at the "8 rpcs in flight" field, and verify A) it is present
24412         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24413         # as expected for an 8M DIO to a file with 1M stripes.
24414         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24415
24416         # Verify turning off parallel dio works as expected
24417         # Clear rpc stats
24418         $LCTL set_param osc.*.rpc_stats=c
24419         $LCTL set_param llite.*.parallel_dio=0
24420         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24421
24422         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24423                 error "dio with parallel dio disabled failed"
24424
24425         # Ideally, we would see only one RPC in flight here, but there is an
24426         # unavoidable race between i/o completion and RPC in flight counting,
24427         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24428         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24429         # So instead we just verify it's always < 8.
24430         $LCTL get_param osc.*-OST0000-*.rpc_stats
24431         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24432                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24433                 grep '^$' -B1 | grep . | awk '{print $1}')
24434         [ $ret != "8:" ] ||
24435                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24436 }
24437 run_test 398g "verify parallel dio async RPC submission"
24438
24439 test_398h() { #  LU-13798
24440         local dio_file=$DIR/$tfile.dio
24441
24442         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24443
24444         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24445         stack_trap "rm -f $DIR/$tfile $dio_file"
24446
24447         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24448                 error "parallel dio failed"
24449         diff $DIR/$tfile $dio_file
24450         [[ $? == 0 ]] || error "file diff after aiocp"
24451 }
24452 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24453
24454 test_398i() { #  LU-13798
24455         local dio_file=$DIR/$tfile.dio
24456
24457         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24458
24459         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24460         stack_trap "rm -f $DIR/$tfile $dio_file"
24461
24462         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24463         $LCTL set_param fail_loc=0x1418
24464         # make sure we don't crash and fail properly
24465         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24466                 error "parallel dio page allocation failure succeeded"
24467         diff $DIR/$tfile $dio_file
24468         [[ $? != 0 ]] || error "no diff after failed aiocp"
24469 }
24470 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24471
24472 test_398j() { #  LU-13798
24473         # Stripe size > RPC size but less than i/o size tests split across
24474         # stripes and RPCs for individual i/o op
24475         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24476
24477         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24478         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24479         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24480         stack_trap "$LCTL set_param -n $pages_per_rpc"
24481
24482         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24483                 error "parallel dio write failed"
24484         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24485
24486         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24487                 error "parallel dio read failed"
24488         diff $DIR/$tfile $DIR/$tfile.2
24489         [[ $? == 0 ]] || error "file diff after parallel dio read"
24490 }
24491 run_test 398j "test parallel dio where stripe size > rpc_size"
24492
24493 test_398k() { #  LU-13798
24494         wait_delete_completed
24495         wait_mds_ost_sync
24496
24497         # 4 stripe file; we will cause out of space on OST0
24498         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24499
24500         # Fill OST0 (if it's not too large)
24501         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24502                    head -n1)
24503         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24504                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24505         fi
24506         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24507         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24508                 error "dd should fill OST0"
24509         stack_trap "rm -f $DIR/$tfile.1"
24510
24511         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24512         err=$?
24513
24514         ls -la $DIR/$tfile
24515         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24516                 error "file is not 0 bytes in size"
24517
24518         # dd above should not succeed, but don't error until here so we can
24519         # get debug info above
24520         [[ $err != 0 ]] ||
24521                 error "parallel dio write with enospc succeeded"
24522         stack_trap "rm -f $DIR/$tfile"
24523 }
24524 run_test 398k "test enospc on first stripe"
24525
24526 test_398l() { #  LU-13798
24527         wait_delete_completed
24528         wait_mds_ost_sync
24529
24530         # 4 stripe file; we will cause out of space on OST0
24531         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24532         # happens on the second i/o chunk we issue
24533         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24534
24535         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24536         stack_trap "rm -f $DIR/$tfile"
24537
24538         # Fill OST0 (if it's not too large)
24539         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24540                    head -n1)
24541         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24542                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24543         fi
24544         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24545         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24546                 error "dd should fill OST0"
24547         stack_trap "rm -f $DIR/$tfile.1"
24548
24549         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24550         err=$?
24551         stack_trap "rm -f $DIR/$tfile.2"
24552
24553         # Check that short write completed as expected
24554         ls -la $DIR/$tfile.2
24555         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24556                 error "file is not 1M in size"
24557
24558         # dd above should not succeed, but don't error until here so we can
24559         # get debug info above
24560         [[ $err != 0 ]] ||
24561                 error "parallel dio write with enospc succeeded"
24562
24563         # Truncate source file to same length as output file and diff them
24564         $TRUNCATE $DIR/$tfile 1048576
24565         diff $DIR/$tfile $DIR/$tfile.2
24566         [[ $? == 0 ]] || error "data incorrect after short write"
24567 }
24568 run_test 398l "test enospc on intermediate stripe/RPC"
24569
24570 test_398m() { #  LU-13798
24571         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24572
24573         # Set up failure on OST0, the first stripe:
24574         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24575         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24576         # So this fail_val specifies OST0
24577         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24578         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24579
24580         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24581                 error "parallel dio write with failure on first stripe succeeded"
24582         stack_trap "rm -f $DIR/$tfile"
24583         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24584
24585         # Place data in file for read
24586         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24587                 error "parallel dio write failed"
24588
24589         # Fail read on OST0, first stripe
24590         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24591         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24592         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24593                 error "parallel dio read with error on first stripe succeeded"
24594         rm -f $DIR/$tfile.2
24595         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24596
24597         # Switch to testing on OST1, second stripe
24598         # Clear file contents, maintain striping
24599         echo > $DIR/$tfile
24600         # Set up failure on OST1, second stripe:
24601         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24602         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24603
24604         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24605                 error "parallel dio write with failure on first stripe succeeded"
24606         stack_trap "rm -f $DIR/$tfile"
24607         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24608
24609         # Place data in file for read
24610         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24611                 error "parallel dio write failed"
24612
24613         # Fail read on OST1, second stripe
24614         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24615         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24616         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24617                 error "parallel dio read with error on first stripe succeeded"
24618         rm -f $DIR/$tfile.2
24619         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24620 }
24621 run_test 398m "test RPC failures with parallel dio"
24622
24623 # Parallel submission of DIO should not cause problems for append, but it's
24624 # important to verify.
24625 test_398n() { #  LU-13798
24626         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24627
24628         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24629                 error "dd to create source file failed"
24630         stack_trap "rm -f $DIR/$tfile"
24631
24632         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24633                 error "parallel dio write with failure on second stripe succeeded"
24634         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24635         diff $DIR/$tfile $DIR/$tfile.1
24636         [[ $? == 0 ]] || error "data incorrect after append"
24637
24638 }
24639 run_test 398n "test append with parallel DIO"
24640
24641 test_fake_rw() {
24642         local read_write=$1
24643         if [ "$read_write" = "write" ]; then
24644                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24645         elif [ "$read_write" = "read" ]; then
24646                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24647         else
24648                 error "argument error"
24649         fi
24650
24651         # turn off debug for performance testing
24652         local saved_debug=$($LCTL get_param -n debug)
24653         $LCTL set_param debug=0
24654
24655         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24656
24657         # get ost1 size - $FSNAME-OST0000
24658         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24659         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
24660         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
24661
24662         if [ "$read_write" = "read" ]; then
24663                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
24664         fi
24665
24666         local start_time=$(date +%s.%N)
24667         $dd_cmd bs=1M count=$blocks oflag=sync ||
24668                 error "real dd $read_write error"
24669         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
24670
24671         if [ "$read_write" = "write" ]; then
24672                 rm -f $DIR/$tfile
24673         fi
24674
24675         # define OBD_FAIL_OST_FAKE_RW           0x238
24676         do_facet ost1 $LCTL set_param fail_loc=0x238
24677
24678         local start_time=$(date +%s.%N)
24679         $dd_cmd bs=1M count=$blocks oflag=sync ||
24680                 error "fake dd $read_write error"
24681         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
24682
24683         if [ "$read_write" = "write" ]; then
24684                 # verify file size
24685                 cancel_lru_locks osc
24686                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
24687                         error "$tfile size not $blocks MB"
24688         fi
24689         do_facet ost1 $LCTL set_param fail_loc=0
24690
24691         echo "fake $read_write $duration_fake vs. normal $read_write" \
24692                 "$duration in seconds"
24693         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
24694                 error_not_in_vm "fake write is slower"
24695
24696         $LCTL set_param -n debug="$saved_debug"
24697         rm -f $DIR/$tfile
24698 }
24699 test_399a() { # LU-7655 for OST fake write
24700         remote_ost_nodsh && skip "remote OST with nodsh"
24701
24702         test_fake_rw write
24703 }
24704 run_test 399a "fake write should not be slower than normal write"
24705
24706 test_399b() { # LU-8726 for OST fake read
24707         remote_ost_nodsh && skip "remote OST with nodsh"
24708         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
24709                 skip_env "ldiskfs only test"
24710         fi
24711
24712         test_fake_rw read
24713 }
24714 run_test 399b "fake read should not be slower than normal read"
24715
24716 test_400a() { # LU-1606, was conf-sanity test_74
24717         if ! which $CC > /dev/null 2>&1; then
24718                 skip_env "$CC is not installed"
24719         fi
24720
24721         local extra_flags=''
24722         local out=$TMP/$tfile
24723         local prefix=/usr/include/lustre
24724         local prog
24725
24726         # Oleg removes c files in his test rig so test if any c files exist
24727         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24728                 skip_env "Needed c test files are missing"
24729
24730         if ! [[ -d $prefix ]]; then
24731                 # Assume we're running in tree and fixup the include path.
24732                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24733                 extra_flags+=" -L$LUSTRE/utils/.lib"
24734         fi
24735
24736         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24737                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24738                         error "client api broken"
24739         done
24740         rm -f $out
24741 }
24742 run_test 400a "Lustre client api program can compile and link"
24743
24744 test_400b() { # LU-1606, LU-5011
24745         local header
24746         local out=$TMP/$tfile
24747         local prefix=/usr/include/linux/lustre
24748
24749         # We use a hard coded prefix so that this test will not fail
24750         # when run in tree. There are headers in lustre/include/lustre/
24751         # that are not packaged (like lustre_idl.h) and have more
24752         # complicated include dependencies (like config.h and lnet/types.h).
24753         # Since this test about correct packaging we just skip them when
24754         # they don't exist (see below) rather than try to fixup cppflags.
24755
24756         if ! which $CC > /dev/null 2>&1; then
24757                 skip_env "$CC is not installed"
24758         fi
24759
24760         for header in $prefix/*.h; do
24761                 if ! [[ -f "$header" ]]; then
24762                         continue
24763                 fi
24764
24765                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24766                         continue # lustre_ioctl.h is internal header
24767                 fi
24768
24769                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24770                         error "cannot compile '$header'"
24771         done
24772         rm -f $out
24773 }
24774 run_test 400b "packaged headers can be compiled"
24775
24776 test_401a() { #LU-7437
24777         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
24778         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
24779
24780         #count the number of parameters by "list_param -R"
24781         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
24782         #count the number of parameters by listing proc files
24783         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
24784         echo "proc_dirs='$proc_dirs'"
24785         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
24786         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
24787                       sort -u | wc -l)
24788
24789         [ $params -eq $procs ] ||
24790                 error "found $params parameters vs. $procs proc files"
24791
24792         # test the list_param -D option only returns directories
24793         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
24794         #count the number of parameters by listing proc directories
24795         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
24796                 sort -u | wc -l)
24797
24798         [ $params -eq $procs ] ||
24799                 error "found $params parameters vs. $procs proc files"
24800 }
24801 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
24802
24803 test_401b() {
24804         # jobid_var may not allow arbitrary values, so use jobid_name
24805         # if available
24806         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24807                 local testname=jobid_name tmp='testing%p'
24808         else
24809                 local testname=jobid_var tmp=testing
24810         fi
24811
24812         local save=$($LCTL get_param -n $testname)
24813
24814         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
24815                 error "no error returned when setting bad parameters"
24816
24817         local jobid_new=$($LCTL get_param -n foe $testname baz)
24818         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
24819
24820         $LCTL set_param -n fog=bam $testname=$save bat=fog
24821         local jobid_old=$($LCTL get_param -n foe $testname bag)
24822         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
24823 }
24824 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
24825
24826 test_401c() {
24827         # jobid_var may not allow arbitrary values, so use jobid_name
24828         # if available
24829         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24830                 local testname=jobid_name
24831         else
24832                 local testname=jobid_var
24833         fi
24834
24835         local jobid_var_old=$($LCTL get_param -n $testname)
24836         local jobid_var_new
24837
24838         $LCTL set_param $testname= &&
24839                 error "no error returned for 'set_param a='"
24840
24841         jobid_var_new=$($LCTL get_param -n $testname)
24842         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24843                 error "$testname was changed by setting without value"
24844
24845         $LCTL set_param $testname &&
24846                 error "no error returned for 'set_param a'"
24847
24848         jobid_var_new=$($LCTL get_param -n $testname)
24849         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24850                 error "$testname was changed by setting without value"
24851 }
24852 run_test 401c "Verify 'lctl set_param' without value fails in either format."
24853
24854 test_401d() {
24855         # jobid_var may not allow arbitrary values, so use jobid_name
24856         # if available
24857         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24858                 local testname=jobid_name new_value='foo=bar%p'
24859         else
24860                 local testname=jobid_var new_valuie=foo=bar
24861         fi
24862
24863         local jobid_var_old=$($LCTL get_param -n $testname)
24864         local jobid_var_new
24865
24866         $LCTL set_param $testname=$new_value ||
24867                 error "'set_param a=b' did not accept a value containing '='"
24868
24869         jobid_var_new=$($LCTL get_param -n $testname)
24870         [[ "$jobid_var_new" == "$new_value" ]] ||
24871                 error "'set_param a=b' failed on a value containing '='"
24872
24873         # Reset the $testname to test the other format
24874         $LCTL set_param $testname=$jobid_var_old
24875         jobid_var_new=$($LCTL get_param -n $testname)
24876         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24877                 error "failed to reset $testname"
24878
24879         $LCTL set_param $testname $new_value ||
24880                 error "'set_param a b' did not accept a value containing '='"
24881
24882         jobid_var_new=$($LCTL get_param -n $testname)
24883         [[ "$jobid_var_new" == "$new_value" ]] ||
24884                 error "'set_param a b' failed on a value containing '='"
24885
24886         $LCTL set_param $testname $jobid_var_old
24887         jobid_var_new=$($LCTL get_param -n $testname)
24888         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24889                 error "failed to reset $testname"
24890 }
24891 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
24892
24893 test_401e() { # LU-14779
24894         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
24895                 error "lctl list_param MGC* failed"
24896         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
24897         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
24898                 error "lctl get_param lru_size failed"
24899 }
24900 run_test 401e "verify 'lctl get_param' works with NID in parameter"
24901
24902 test_402() {
24903         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
24904         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
24905                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
24906         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
24907                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
24908                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
24909         remote_mds_nodsh && skip "remote MDS with nodsh"
24910
24911         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
24912 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
24913         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
24914         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
24915                 echo "Touch failed - OK"
24916 }
24917 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
24918
24919 test_403() {
24920         local file1=$DIR/$tfile.1
24921         local file2=$DIR/$tfile.2
24922         local tfile=$TMP/$tfile
24923
24924         rm -f $file1 $file2 $tfile
24925
24926         touch $file1
24927         ln $file1 $file2
24928
24929         # 30 sec OBD_TIMEOUT in ll_getattr()
24930         # right before populating st_nlink
24931         $LCTL set_param fail_loc=0x80001409
24932         stat -c %h $file1 > $tfile &
24933
24934         # create an alias, drop all locks and reclaim the dentry
24935         < $file2
24936         cancel_lru_locks mdc
24937         cancel_lru_locks osc
24938         sysctl -w vm.drop_caches=2
24939
24940         wait
24941
24942         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
24943
24944         rm -f $tfile $file1 $file2
24945 }
24946 run_test 403 "i_nlink should not drop to zero due to aliasing"
24947
24948 test_404() { # LU-6601
24949         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
24950                 skip "Need server version newer than 2.8.52"
24951         remote_mds_nodsh && skip "remote MDS with nodsh"
24952
24953         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
24954                 awk '/osp .*-osc-MDT/ { print $4}')
24955
24956         local osp
24957         for osp in $mosps; do
24958                 echo "Deactivate: " $osp
24959                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
24960                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24961                         awk -vp=$osp '$4 == p { print $2 }')
24962                 [ $stat = IN ] || {
24963                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24964                         error "deactivate error"
24965                 }
24966                 echo "Activate: " $osp
24967                 do_facet $SINGLEMDS $LCTL --device %$osp activate
24968                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24969                         awk -vp=$osp '$4 == p { print $2 }')
24970                 [ $stat = UP ] || {
24971                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24972                         error "activate error"
24973                 }
24974         done
24975 }
24976 run_test 404 "validate manual {de}activated works properly for OSPs"
24977
24978 test_405() {
24979         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24980         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
24981                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
24982                         skip "Layout swap lock is not supported"
24983
24984         check_swap_layouts_support
24985         check_swap_layout_no_dom $DIR
24986
24987         test_mkdir $DIR/$tdir
24988         swap_lock_test -d $DIR/$tdir ||
24989                 error "One layout swap locked test failed"
24990 }
24991 run_test 405 "Various layout swap lock tests"
24992
24993 test_406() {
24994         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24995         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
24996         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
24997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24998         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
24999                 skip "Need MDS version at least 2.8.50"
25000
25001         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25002         local test_pool=$TESTNAME
25003
25004         pool_add $test_pool || error "pool_add failed"
25005         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25006                 error "pool_add_targets failed"
25007
25008         save_layout_restore_at_exit $MOUNT
25009
25010         # parent set default stripe count only, child will stripe from both
25011         # parent and fs default
25012         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25013                 error "setstripe $MOUNT failed"
25014         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25015         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25016         for i in $(seq 10); do
25017                 local f=$DIR/$tdir/$tfile.$i
25018                 touch $f || error "touch failed"
25019                 local count=$($LFS getstripe -c $f)
25020                 [ $count -eq $OSTCOUNT ] ||
25021                         error "$f stripe count $count != $OSTCOUNT"
25022                 local offset=$($LFS getstripe -i $f)
25023                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25024                 local size=$($LFS getstripe -S $f)
25025                 [ $size -eq $((def_stripe_size * 2)) ] ||
25026                         error "$f stripe size $size != $((def_stripe_size * 2))"
25027                 local pool=$($LFS getstripe -p $f)
25028                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25029         done
25030
25031         # change fs default striping, delete parent default striping, now child
25032         # will stripe from new fs default striping only
25033         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25034                 error "change $MOUNT default stripe failed"
25035         $LFS setstripe -c 0 $DIR/$tdir ||
25036                 error "delete $tdir default stripe failed"
25037         for i in $(seq 11 20); do
25038                 local f=$DIR/$tdir/$tfile.$i
25039                 touch $f || error "touch $f failed"
25040                 local count=$($LFS getstripe -c $f)
25041                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25042                 local offset=$($LFS getstripe -i $f)
25043                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25044                 local size=$($LFS getstripe -S $f)
25045                 [ $size -eq $def_stripe_size ] ||
25046                         error "$f stripe size $size != $def_stripe_size"
25047                 local pool=$($LFS getstripe -p $f)
25048                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25049         done
25050
25051         unlinkmany $DIR/$tdir/$tfile. 1 20
25052
25053         local f=$DIR/$tdir/$tfile
25054         pool_remove_all_targets $test_pool $f
25055         pool_remove $test_pool $f
25056 }
25057 run_test 406 "DNE support fs default striping"
25058
25059 test_407() {
25060         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25061         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25062                 skip "Need MDS version at least 2.8.55"
25063         remote_mds_nodsh && skip "remote MDS with nodsh"
25064
25065         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25066                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25067         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25068                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25069         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25070
25071         #define OBD_FAIL_DT_TXN_STOP    0x2019
25072         for idx in $(seq $MDSCOUNT); do
25073                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25074         done
25075         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25076         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25077                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25078         true
25079 }
25080 run_test 407 "transaction fail should cause operation fail"
25081
25082 test_408() {
25083         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25084
25085         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25086         lctl set_param fail_loc=0x8000040a
25087         # let ll_prepare_partial_page() fail
25088         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25089
25090         rm -f $DIR/$tfile
25091
25092         # create at least 100 unused inodes so that
25093         # shrink_icache_memory(0) should not return 0
25094         touch $DIR/$tfile-{0..100}
25095         rm -f $DIR/$tfile-{0..100}
25096         sync
25097
25098         echo 2 > /proc/sys/vm/drop_caches
25099 }
25100 run_test 408 "drop_caches should not hang due to page leaks"
25101
25102 test_409()
25103 {
25104         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25105
25106         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25107         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25108         touch $DIR/$tdir/guard || error "(2) Fail to create"
25109
25110         local PREFIX=$(str_repeat 'A' 128)
25111         echo "Create 1K hard links start at $(date)"
25112         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25113                 error "(3) Fail to hard link"
25114
25115         echo "Links count should be right although linkEA overflow"
25116         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25117         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25118         [ $linkcount -eq 1001 ] ||
25119                 error "(5) Unexpected hard links count: $linkcount"
25120
25121         echo "List all links start at $(date)"
25122         ls -l $DIR/$tdir/foo > /dev/null ||
25123                 error "(6) Fail to list $DIR/$tdir/foo"
25124
25125         echo "Unlink hard links start at $(date)"
25126         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25127                 error "(7) Fail to unlink"
25128         echo "Unlink hard links finished at $(date)"
25129 }
25130 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25131
25132 test_410()
25133 {
25134         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25135                 skip "Need client version at least 2.9.59"
25136         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25137                 skip "Need MODULES build"
25138
25139         # Create a file, and stat it from the kernel
25140         local testfile=$DIR/$tfile
25141         touch $testfile
25142
25143         local run_id=$RANDOM
25144         local my_ino=$(stat --format "%i" $testfile)
25145
25146         # Try to insert the module. This will always fail as the
25147         # module is designed to not be inserted.
25148         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25149             &> /dev/null
25150
25151         # Anything but success is a test failure
25152         dmesg | grep -q \
25153             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25154             error "no inode match"
25155 }
25156 run_test 410 "Test inode number returned from kernel thread"
25157
25158 cleanup_test411_cgroup() {
25159         trap 0
25160         rmdir "$1"
25161 }
25162
25163 test_411() {
25164         local cg_basedir=/sys/fs/cgroup/memory
25165         # LU-9966
25166         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25167                 skip "no setup for cgroup"
25168
25169         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25170                 error "test file creation failed"
25171         cancel_lru_locks osc
25172
25173         # Create a very small memory cgroup to force a slab allocation error
25174         local cgdir=$cg_basedir/osc_slab_alloc
25175         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25176         trap "cleanup_test411_cgroup $cgdir" EXIT
25177         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25178         echo 1M > $cgdir/memory.limit_in_bytes
25179
25180         # Should not LBUG, just be killed by oom-killer
25181         # dd will return 0 even allocation failure in some environment.
25182         # So don't check return value
25183         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25184         cleanup_test411_cgroup $cgdir
25185
25186         return 0
25187 }
25188 run_test 411 "Slab allocation error with cgroup does not LBUG"
25189
25190 test_412() {
25191         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25192         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25193                 skip "Need server version at least 2.10.55"
25194
25195         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25196                 error "mkdir failed"
25197         $LFS getdirstripe $DIR/$tdir
25198         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25199         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25200                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25201         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25202         [ $stripe_count -eq 2 ] ||
25203                 error "expect 2 get $stripe_count"
25204
25205         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25206
25207         local index
25208         local index2
25209
25210         # subdirs should be on the same MDT as parent
25211         for i in $(seq 0 $((MDSCOUNT - 1))); do
25212                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25213                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25214                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25215                 (( index == i )) || error "mdt$i/sub on MDT$index"
25216         done
25217
25218         # stripe offset -1, ditto
25219         for i in {1..10}; do
25220                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25221                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25222                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25223                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25224                 (( index == index2 )) ||
25225                         error "qos$i on MDT$index, sub on MDT$index2"
25226         done
25227
25228         local testdir=$DIR/$tdir/inherit
25229
25230         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25231         # inherit 2 levels
25232         for i in 1 2; do
25233                 testdir=$testdir/s$i
25234                 mkdir $testdir || error "mkdir $testdir failed"
25235                 index=$($LFS getstripe -m $testdir)
25236                 (( index == 1 )) ||
25237                         error "$testdir on MDT$index"
25238         done
25239
25240         # not inherit any more
25241         testdir=$testdir/s3
25242         mkdir $testdir || error "mkdir $testdir failed"
25243         getfattr -d -m dmv $testdir | grep dmv &&
25244                 error "default LMV set on $testdir" || true
25245 }
25246 run_test 412 "mkdir on specific MDTs"
25247
25248 generate_uneven_mdts() {
25249         local threshold=$1
25250         local lmv_qos_maxage
25251         local lod_qos_maxage
25252         local ffree
25253         local bavail
25254         local max
25255         local min
25256         local max_index
25257         local min_index
25258         local tmp
25259         local i
25260
25261         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25262         $LCTL set_param lmv.*.qos_maxage=1
25263         stack_trap "$LCTL set_param \
25264                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25265         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25266                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25267         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25268                 lod.*.mdt_qos_maxage=1
25269         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25270                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25271
25272         echo
25273         echo "Check for uneven MDTs: "
25274
25275         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25276         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25277         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25278
25279         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25280         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25281         max_index=0
25282         min_index=0
25283         for ((i = 1; i < ${#ffree[@]}; i++)); do
25284                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25285                 if [ $tmp -gt $max ]; then
25286                         max=$tmp
25287                         max_index=$i
25288                 fi
25289                 if [ $tmp -lt $min ]; then
25290                         min=$tmp
25291                         min_index=$i
25292                 fi
25293         done
25294
25295         (( ${ffree[min_index]} > 0 )) ||
25296                 skip "no free files in MDT$min_index"
25297         (( ${ffree[min_index]} < 10000000 )) ||
25298                 skip "too many free files in MDT$min_index"
25299
25300         # Check if we need to generate uneven MDTs
25301         local diff=$(((max - min) * 100 / min))
25302         local testdir=$DIR/$tdir-fillmdt
25303         local start
25304
25305         mkdir -p $testdir
25306
25307         i=0
25308         while (( diff < threshold )); do
25309                 # generate uneven MDTs, create till $threshold% diff
25310                 echo -n "weight diff=$diff% must be > $threshold% ..."
25311                 echo "Fill MDT$min_index with 1000 files: loop $i"
25312                 testdir=$DIR/$tdir-fillmdt/$i
25313                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
25314                         error "mkdir $testdir failed"
25315                 $LFS setstripe -E 1M -L mdt $testdir ||
25316                         error "setstripe $testdir failed"
25317                 start=$SECONDS
25318                 for F in f.{0..999}; do
25319                         dd if=/dev/zero of=$testdir/$F bs=64K count=1 > \
25320                                 /dev/null 2>&1 || error "dd $F failed"
25321                 done
25322
25323                 # wait for QOS to update
25324                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25325
25326                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25327                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25328                 max=$(((${ffree[max_index]} >> 8) * \
25329                         (${bavail[max_index]} * bsize >> 16)))
25330                 min=$(((${ffree[min_index]} >> 8) * \
25331                         (${bavail[min_index]} * bsize >> 16)))
25332                 diff=$(((max - min) * 100 / min))
25333                 i=$((i + 1))
25334         done
25335
25336         echo "MDT filesfree available: ${ffree[@]}"
25337         echo "MDT blocks available: ${bavail[@]}"
25338         echo "weight diff=$diff%"
25339 }
25340
25341 test_qos_mkdir() {
25342         local mkdir_cmd=$1
25343         local stripe_count=$2
25344         local mdts=$(comma_list $(mdts_nodes))
25345
25346         local testdir
25347         local lmv_qos_prio_free
25348         local lmv_qos_threshold_rr
25349         local lmv_qos_maxage
25350         local lod_qos_prio_free
25351         local lod_qos_threshold_rr
25352         local lod_qos_maxage
25353         local count
25354         local i
25355
25356         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25357         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25358         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25359                 head -n1)
25360         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25361         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25362         stack_trap "$LCTL set_param \
25363                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25364         stack_trap "$LCTL set_param \
25365                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25366         stack_trap "$LCTL set_param \
25367                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25368
25369         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25370                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25371         lod_qos_prio_free=${lod_qos_prio_free%%%}
25372         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25373                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25374         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25375         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25376                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25377         stack_trap "do_nodes $mdts $LCTL set_param \
25378                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25379         stack_trap "do_nodes $mdts $LCTL set_param \
25380                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25381         stack_trap "do_nodes $mdts $LCTL set_param \
25382                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25383
25384         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25385         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25386
25387         testdir=$DIR/$tdir-s$stripe_count/rr
25388
25389         local stripe_index=$($LFS getstripe -m $testdir)
25390         local test_mkdir_rr=true
25391
25392         getfattr -d -m dmv -e hex $testdir | grep dmv
25393         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25394                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25395                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25396                         test_mkdir_rr=false
25397         fi
25398
25399         echo
25400         $test_mkdir_rr &&
25401                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25402                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25403
25404         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25405         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25406                 eval $mkdir_cmd $testdir/subdir$i ||
25407                         error "$mkdir_cmd subdir$i failed"
25408         done
25409
25410         for (( i = 0; i < $MDSCOUNT; i++ )); do
25411                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25412                 echo "$count directories created on MDT$i"
25413                 if $test_mkdir_rr; then
25414                         (( $count == 100 )) ||
25415                                 error "subdirs are not evenly distributed"
25416                 elif (( $i == $stripe_index )); then
25417                         (( $count == 100 * MDSCOUNT )) ||
25418                                 error "$count subdirs created on MDT$i"
25419                 else
25420                         (( $count == 0 )) ||
25421                                 error "$count subdirs created on MDT$i"
25422                 fi
25423
25424                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25425                         count=$($LFS getdirstripe $testdir/* |
25426                                 grep -c -P "^\s+$i\t")
25427                         echo "$count stripes created on MDT$i"
25428                         # deviation should < 5% of average
25429                         (( $count >= 95 * stripe_count &&
25430                            $count <= 105 * stripe_count)) ||
25431                                 error "stripes are not evenly distributed"
25432                 fi
25433         done
25434
25435         echo
25436         echo "Check for uneven MDTs: "
25437
25438         local ffree
25439         local bavail
25440         local max
25441         local min
25442         local max_index
25443         local min_index
25444         local tmp
25445
25446         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25447         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25448         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25449
25450         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25451         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25452         max_index=0
25453         min_index=0
25454         for ((i = 1; i < ${#ffree[@]}; i++)); do
25455                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25456                 if [ $tmp -gt $max ]; then
25457                         max=$tmp
25458                         max_index=$i
25459                 fi
25460                 if [ $tmp -lt $min ]; then
25461                         min=$tmp
25462                         min_index=$i
25463                 fi
25464         done
25465
25466         (( ${ffree[min_index]} > 0 )) ||
25467                 skip "no free files in MDT$min_index"
25468         (( ${ffree[min_index]} < 10000000 )) ||
25469                 skip "too many free files in MDT$min_index"
25470
25471         echo "MDT filesfree available: ${ffree[@]}"
25472         echo "MDT blocks available: ${bavail[@]}"
25473         echo "weight diff=$(((max - min) * 100 / min))%"
25474         echo
25475         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25476
25477         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25478         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25479         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25480         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25481         # decrease statfs age, so that it can be updated in time
25482         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25483         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25484
25485         sleep 1
25486
25487         testdir=$DIR/$tdir-s$stripe_count/qos
25488         local num=200
25489
25490         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25491         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25492                 eval $mkdir_cmd $testdir/subdir$i ||
25493                         error "$mkdir_cmd subdir$i failed"
25494         done
25495
25496         max=0
25497         for (( i = 0; i < $MDSCOUNT; i++ )); do
25498                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25499                 (( count > max )) && max=$count
25500                 echo "$count directories created on MDT$i"
25501         done
25502
25503         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25504
25505         # D-value should > 10% of averge
25506         (( max - min > num / 10 )) ||
25507                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25508
25509         # ditto for stripes
25510         if (( stripe_count > 1 )); then
25511                 max=0
25512                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25513                         count=$($LFS getdirstripe $testdir/* |
25514                                 grep -c -P "^\s+$i\t")
25515                         (( count > max )) && max=$count
25516                         echo "$count stripes created on MDT$i"
25517                 done
25518
25519                 min=$($LFS getdirstripe $testdir/* |
25520                         grep -c -P "^\s+$min_index\t")
25521                 (( max - min > num * stripe_count / 10 )) ||
25522                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25523         fi
25524 }
25525
25526 most_full_mdt() {
25527         local ffree
25528         local bavail
25529         local bsize
25530         local min
25531         local min_index
25532         local tmp
25533
25534         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25535         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25536         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25537
25538         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25539         min_index=0
25540         for ((i = 1; i < ${#ffree[@]}; i++)); do
25541                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25542                 (( tmp < min )) && min=$tmp && min_index=$i
25543         done
25544
25545         echo -n $min_index
25546 }
25547
25548 test_413a() {
25549         [ $MDSCOUNT -lt 2 ] &&
25550                 skip "We need at least 2 MDTs for this test"
25551
25552         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25553                 skip "Need server version at least 2.12.52"
25554
25555         local stripe_count
25556
25557         generate_uneven_mdts 100
25558         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25559                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25560                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25561                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25562                         error "mkdir failed"
25563                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25564         done
25565 }
25566 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25567
25568 test_413b() {
25569         [ $MDSCOUNT -lt 2 ] &&
25570                 skip "We need at least 2 MDTs for this test"
25571
25572         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25573                 skip "Need server version at least 2.12.52"
25574
25575         local testdir
25576         local stripe_count
25577
25578         generate_uneven_mdts 100
25579         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25580                 testdir=$DIR/$tdir-s$stripe_count
25581                 mkdir $testdir || error "mkdir $testdir failed"
25582                 mkdir $testdir/rr || error "mkdir rr failed"
25583                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25584                         error "mkdir qos failed"
25585                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25586                         $testdir/rr || error "setdirstripe rr failed"
25587                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25588                         error "setdirstripe failed"
25589                 test_qos_mkdir "mkdir" $stripe_count
25590         done
25591 }
25592 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25593
25594 test_413c() {
25595         (( $MDSCOUNT >= 2 )) ||
25596                 skip "We need at least 2 MDTs for this test"
25597
25598         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25599                 skip "Need server version at least 2.14.51"
25600
25601         local testdir
25602         local inherit
25603         local inherit_rr
25604
25605         testdir=$DIR/${tdir}-s1
25606         mkdir $testdir || error "mkdir $testdir failed"
25607         mkdir $testdir/rr || error "mkdir rr failed"
25608         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25609         # default max_inherit is -1, default max_inherit_rr is 0
25610         $LFS setdirstripe -D -c 1 $testdir/rr ||
25611                 error "setdirstripe rr failed"
25612         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25613                 error "setdirstripe qos failed"
25614         test_qos_mkdir "mkdir" 1
25615
25616         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25617         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25618         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25619         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25620         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25621
25622         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25623         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25624         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25625         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25626         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25627         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25628         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25629                 error "level2 shouldn't have default LMV" || true
25630 }
25631 run_test 413c "mkdir with default LMV max inherit rr"
25632
25633 test_413d() {
25634         (( MDSCOUNT >= 2 )) ||
25635                 skip "We need at least 2 MDTs for this test"
25636
25637         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25638                 skip "Need server version at least 2.14.51"
25639
25640         local lmv_qos_threshold_rr
25641
25642         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25643                 head -n1)
25644         stack_trap "$LCTL set_param \
25645                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
25646
25647         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25648         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25649         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
25650                 error "$tdir shouldn't have default LMV"
25651         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
25652                 error "mkdir sub failed"
25653
25654         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
25655
25656         (( count == 100 )) || error "$count subdirs on MDT0"
25657 }
25658 run_test 413d "inherit ROOT default LMV"
25659
25660 test_413e() {
25661         (( MDSCOUNT >= 2 )) ||
25662                 skip "We need at least 2 MDTs for this test"
25663         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25664                 skip "Need server version at least 2.14.55"
25665
25666         local testdir=$DIR/$tdir
25667         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
25668         local max_inherit
25669         local sub_max_inherit
25670
25671         mkdir -p $testdir || error "failed to create $testdir"
25672
25673         # set default max-inherit to -1 if stripe count is 0 or 1
25674         $LFS setdirstripe -D -c 1 $testdir ||
25675                 error "failed to set default LMV"
25676         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25677         (( max_inherit == -1 )) ||
25678                 error "wrong max_inherit value $max_inherit"
25679
25680         # set default max_inherit to a fixed value if stripe count is not 0 or 1
25681         $LFS setdirstripe -D -c -1 $testdir ||
25682                 error "failed to set default LMV"
25683         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25684         (( max_inherit > 0 )) ||
25685                 error "wrong max_inherit value $max_inherit"
25686
25687         # and the subdir will decrease the max_inherit by 1
25688         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
25689         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
25690         (( sub_max_inherit == max_inherit - 1)) ||
25691                 error "wrong max-inherit of subdir $sub_max_inherit"
25692
25693         # check specified --max-inherit and warning message
25694         stack_trap "rm -f $tmpfile"
25695         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
25696                 error "failed to set default LMV"
25697         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25698         (( max_inherit == -1 )) ||
25699                 error "wrong max_inherit value $max_inherit"
25700
25701         # check the warning messages
25702         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
25703                 error "failed to detect warning string"
25704         fi
25705 }
25706 run_test 413e "check default max-inherit value"
25707
25708 test_413z() {
25709         local pids=""
25710         local subdir
25711         local pid
25712
25713         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
25714                 unlinkmany $subdir/f. 1000 &
25715                 pids="$pids $!"
25716         done
25717
25718         for pid in $pids; do
25719                 wait $pid
25720         done
25721 }
25722 run_test 413z "413 test cleanup"
25723
25724 test_414() {
25725 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
25726         $LCTL set_param fail_loc=0x80000521
25727         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25728         rm -f $DIR/$tfile
25729 }
25730 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
25731
25732 test_415() {
25733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25734         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25735                 skip "Need server version at least 2.11.52"
25736
25737         # LU-11102
25738         local total
25739         local setattr_pid
25740         local start_time
25741         local end_time
25742         local duration
25743
25744         total=500
25745         # this test may be slow on ZFS
25746         [ "$mds1_FSTYPE" == "zfs" ] && total=100
25747
25748         # though this test is designed for striped directory, let's test normal
25749         # directory too since lock is always saved as CoS lock.
25750         test_mkdir $DIR/$tdir || error "mkdir $tdir"
25751         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
25752
25753         (
25754                 while true; do
25755                         touch $DIR/$tdir
25756                 done
25757         ) &
25758         setattr_pid=$!
25759
25760         start_time=$(date +%s)
25761         for i in $(seq $total); do
25762                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
25763                         > /dev/null
25764         done
25765         end_time=$(date +%s)
25766         duration=$((end_time - start_time))
25767
25768         kill -9 $setattr_pid
25769
25770         echo "rename $total files took $duration sec"
25771         [ $duration -lt 100 ] || error "rename took $duration sec"
25772 }
25773 run_test 415 "lock revoke is not missing"
25774
25775 test_416() {
25776         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25777                 skip "Need server version at least 2.11.55"
25778
25779         # define OBD_FAIL_OSD_TXN_START    0x19a
25780         do_facet mds1 lctl set_param fail_loc=0x19a
25781
25782         lfs mkdir -c $MDSCOUNT $DIR/$tdir
25783
25784         true
25785 }
25786 run_test 416 "transaction start failure won't cause system hung"
25787
25788 cleanup_417() {
25789         trap 0
25790         do_nodes $(comma_list $(mdts_nodes)) \
25791                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
25792         do_nodes $(comma_list $(mdts_nodes)) \
25793                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
25794         do_nodes $(comma_list $(mdts_nodes)) \
25795                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
25796 }
25797
25798 test_417() {
25799         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25800         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
25801                 skip "Need MDS version at least 2.11.56"
25802
25803         trap cleanup_417 RETURN EXIT
25804
25805         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
25806         do_nodes $(comma_list $(mdts_nodes)) \
25807                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
25808         $LFS migrate -m 0 $DIR/$tdir.1 &&
25809                 error "migrate dir $tdir.1 should fail"
25810
25811         do_nodes $(comma_list $(mdts_nodes)) \
25812                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
25813         $LFS mkdir -i 1 $DIR/$tdir.2 &&
25814                 error "create remote dir $tdir.2 should fail"
25815
25816         do_nodes $(comma_list $(mdts_nodes)) \
25817                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
25818         $LFS mkdir -c 2 $DIR/$tdir.3 &&
25819                 error "create striped dir $tdir.3 should fail"
25820         true
25821 }
25822 run_test 417 "disable remote dir, striped dir and dir migration"
25823
25824 # Checks that the outputs of df [-i] and lfs df [-i] match
25825 #
25826 # usage: check_lfs_df <blocks | inodes> <mountpoint>
25827 check_lfs_df() {
25828         local dir=$2
25829         local inodes
25830         local df_out
25831         local lfs_df_out
25832         local count
25833         local passed=false
25834
25835         # blocks or inodes
25836         [ "$1" == "blocks" ] && inodes= || inodes="-i"
25837
25838         for count in {1..100}; do
25839                 do_nodes "$CLIENTS" \
25840                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25841                 sync; sleep 0.2
25842
25843                 # read the lines of interest
25844                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
25845                         error "df $inodes $dir | tail -n +2 failed"
25846                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
25847                         error "lfs df $inodes $dir | grep summary: failed"
25848
25849                 # skip first substrings of each output as they are different
25850                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
25851                 # compare the two outputs
25852                 passed=true
25853                 #  skip "available" on MDT until LU-13997 is fixed.
25854                 #for i in {1..5}; do
25855                 for i in 1 2 4 5; do
25856                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
25857                 done
25858                 $passed && break
25859         done
25860
25861         if ! $passed; then
25862                 df -P $inodes $dir
25863                 echo
25864                 lfs df $inodes $dir
25865                 error "df and lfs df $1 output mismatch: "      \
25866                       "df ${inodes}: ${df_out[*]}, "            \
25867                       "lfs df ${inodes}: ${lfs_df_out[*]}"
25868         fi
25869 }
25870
25871 test_418() {
25872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25873
25874         local dir=$DIR/$tdir
25875         local numfiles=$((RANDOM % 4096 + 2))
25876         local numblocks=$((RANDOM % 256 + 1))
25877
25878         wait_delete_completed
25879         test_mkdir $dir
25880
25881         # check block output
25882         check_lfs_df blocks $dir
25883         # check inode output
25884         check_lfs_df inodes $dir
25885
25886         # create a single file and retest
25887         echo "Creating a single file and testing"
25888         createmany -o $dir/$tfile- 1 &>/dev/null ||
25889                 error "creating 1 file in $dir failed"
25890         check_lfs_df blocks $dir
25891         check_lfs_df inodes $dir
25892
25893         # create a random number of files
25894         echo "Creating $((numfiles - 1)) files and testing"
25895         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
25896                 error "creating $((numfiles - 1)) files in $dir failed"
25897
25898         # write a random number of blocks to the first test file
25899         echo "Writing $numblocks 4K blocks and testing"
25900         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
25901                 count=$numblocks &>/dev/null ||
25902                 error "dd to $dir/${tfile}-0 failed"
25903
25904         # retest
25905         check_lfs_df blocks $dir
25906         check_lfs_df inodes $dir
25907
25908         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
25909                 error "unlinking $numfiles files in $dir failed"
25910 }
25911 run_test 418 "df and lfs df outputs match"
25912
25913 test_419()
25914 {
25915         local dir=$DIR/$tdir
25916
25917         mkdir -p $dir
25918         touch $dir/file
25919
25920         cancel_lru_locks mdc
25921
25922         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
25923         $LCTL set_param fail_loc=0x1410
25924         cat $dir/file
25925         $LCTL set_param fail_loc=0
25926         rm -rf $dir
25927 }
25928 run_test 419 "Verify open file by name doesn't crash kernel"
25929
25930 test_420()
25931 {
25932         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
25933                 skip "Need MDS version at least 2.12.53"
25934
25935         local SAVE_UMASK=$(umask)
25936         local dir=$DIR/$tdir
25937         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
25938
25939         mkdir -p $dir
25940         umask 0000
25941         mkdir -m03777 $dir/testdir
25942         ls -dn $dir/testdir
25943         # Need to remove trailing '.' when SELinux is enabled
25944         local dirperms=$(ls -dn $dir/testdir |
25945                          awk '{ sub(/\.$/, "", $1); print $1}')
25946         [ $dirperms == "drwxrwsrwt" ] ||
25947                 error "incorrect perms on $dir/testdir"
25948
25949         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
25950                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
25951         ls -n $dir/testdir/testfile
25952         local fileperms=$(ls -n $dir/testdir/testfile |
25953                           awk '{ sub(/\.$/, "", $1); print $1}')
25954         [ $fileperms == "-rwxr-xr-x" ] ||
25955                 error "incorrect perms on $dir/testdir/testfile"
25956
25957         umask $SAVE_UMASK
25958 }
25959 run_test 420 "clear SGID bit on non-directories for non-members"
25960
25961 test_421a() {
25962         local cnt
25963         local fid1
25964         local fid2
25965
25966         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25967                 skip "Need MDS version at least 2.12.54"
25968
25969         test_mkdir $DIR/$tdir
25970         createmany -o $DIR/$tdir/f 3
25971         cnt=$(ls -1 $DIR/$tdir | wc -l)
25972         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25973
25974         fid1=$(lfs path2fid $DIR/$tdir/f1)
25975         fid2=$(lfs path2fid $DIR/$tdir/f2)
25976         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
25977
25978         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
25979         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
25980
25981         cnt=$(ls -1 $DIR/$tdir | wc -l)
25982         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25983
25984         rm -f $DIR/$tdir/f3 || error "can't remove f3"
25985         createmany -o $DIR/$tdir/f 3
25986         cnt=$(ls -1 $DIR/$tdir | wc -l)
25987         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25988
25989         fid1=$(lfs path2fid $DIR/$tdir/f1)
25990         fid2=$(lfs path2fid $DIR/$tdir/f2)
25991         echo "remove using fsname $FSNAME"
25992         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
25993
25994         cnt=$(ls -1 $DIR/$tdir | wc -l)
25995         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25996 }
25997 run_test 421a "simple rm by fid"
25998
25999 test_421b() {
26000         local cnt
26001         local FID1
26002         local FID2
26003
26004         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26005                 skip "Need MDS version at least 2.12.54"
26006
26007         test_mkdir $DIR/$tdir
26008         createmany -o $DIR/$tdir/f 3
26009         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26010         MULTIPID=$!
26011
26012         FID1=$(lfs path2fid $DIR/$tdir/f1)
26013         FID2=$(lfs path2fid $DIR/$tdir/f2)
26014         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26015
26016         kill -USR1 $MULTIPID
26017         wait
26018
26019         cnt=$(ls $DIR/$tdir | wc -l)
26020         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26021 }
26022 run_test 421b "rm by fid on open file"
26023
26024 test_421c() {
26025         local cnt
26026         local FIDS
26027
26028         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26029                 skip "Need MDS version at least 2.12.54"
26030
26031         test_mkdir $DIR/$tdir
26032         createmany -o $DIR/$tdir/f 3
26033         touch $DIR/$tdir/$tfile
26034         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26035         cnt=$(ls -1 $DIR/$tdir | wc -l)
26036         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26037
26038         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26039         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26040
26041         cnt=$(ls $DIR/$tdir | wc -l)
26042         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26043 }
26044 run_test 421c "rm by fid against hardlinked files"
26045
26046 test_421d() {
26047         local cnt
26048         local FIDS
26049
26050         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26051                 skip "Need MDS version at least 2.12.54"
26052
26053         test_mkdir $DIR/$tdir
26054         createmany -o $DIR/$tdir/f 4097
26055         cnt=$(ls -1 $DIR/$tdir | wc -l)
26056         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26057
26058         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26059         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26060
26061         cnt=$(ls $DIR/$tdir | wc -l)
26062         rm -rf $DIR/$tdir
26063         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26064 }
26065 run_test 421d "rmfid en masse"
26066
26067 test_421e() {
26068         local cnt
26069         local FID
26070
26071         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26072         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26073                 skip "Need MDS version at least 2.12.54"
26074
26075         mkdir -p $DIR/$tdir
26076         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26077         createmany -o $DIR/$tdir/striped_dir/f 512
26078         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26079         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26080
26081         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26082                 sed "s/[/][^:]*://g")
26083         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26084
26085         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26086         rm -rf $DIR/$tdir
26087         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26088 }
26089 run_test 421e "rmfid in DNE"
26090
26091 test_421f() {
26092         local cnt
26093         local FID
26094
26095         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26096                 skip "Need MDS version at least 2.12.54"
26097
26098         test_mkdir $DIR/$tdir
26099         touch $DIR/$tdir/f
26100         cnt=$(ls -1 $DIR/$tdir | wc -l)
26101         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26102
26103         FID=$(lfs path2fid $DIR/$tdir/f)
26104         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26105         # rmfid should fail
26106         cnt=$(ls -1 $DIR/$tdir | wc -l)
26107         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26108
26109         chmod a+rw $DIR/$tdir
26110         ls -la $DIR/$tdir
26111         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26112         # rmfid should fail
26113         cnt=$(ls -1 $DIR/$tdir | wc -l)
26114         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26115
26116         rm -f $DIR/$tdir/f
26117         $RUNAS touch $DIR/$tdir/f
26118         FID=$(lfs path2fid $DIR/$tdir/f)
26119         echo "rmfid as root"
26120         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26121         cnt=$(ls -1 $DIR/$tdir | wc -l)
26122         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26123
26124         rm -f $DIR/$tdir/f
26125         $RUNAS touch $DIR/$tdir/f
26126         cnt=$(ls -1 $DIR/$tdir | wc -l)
26127         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26128         FID=$(lfs path2fid $DIR/$tdir/f)
26129         # rmfid w/o user_fid2path mount option should fail
26130         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26131         cnt=$(ls -1 $DIR/$tdir | wc -l)
26132         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26133
26134         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26135         stack_trap "rmdir $tmpdir"
26136         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26137                 error "failed to mount client'"
26138         stack_trap "umount_client $tmpdir"
26139
26140         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26141         # rmfid should succeed
26142         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26143         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26144
26145         # rmfid shouldn't allow to remove files due to dir's permission
26146         chmod a+rwx $tmpdir/$tdir
26147         touch $tmpdir/$tdir/f
26148         ls -la $tmpdir/$tdir
26149         FID=$(lfs path2fid $tmpdir/$tdir/f)
26150         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26151         return 0
26152 }
26153 run_test 421f "rmfid checks permissions"
26154
26155 test_421g() {
26156         local cnt
26157         local FIDS
26158
26159         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26160         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26161                 skip "Need MDS version at least 2.12.54"
26162
26163         mkdir -p $DIR/$tdir
26164         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26165         createmany -o $DIR/$tdir/striped_dir/f 512
26166         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26167         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26168
26169         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26170                 sed "s/[/][^:]*://g")
26171
26172         rm -f $DIR/$tdir/striped_dir/f1*
26173         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26174         removed=$((512 - cnt))
26175
26176         # few files have been just removed, so we expect
26177         # rmfid to fail on their fids
26178         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26179         [ $removed != $errors ] && error "$errors != $removed"
26180
26181         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26182         rm -rf $DIR/$tdir
26183         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26184 }
26185 run_test 421g "rmfid to return errors properly"
26186
26187 test_422() {
26188         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26189         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26190         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26191         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26192         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26193
26194         local amc=$(at_max_get client)
26195         local amo=$(at_max_get mds1)
26196         local timeout=`lctl get_param -n timeout`
26197
26198         at_max_set 0 client
26199         at_max_set 0 mds1
26200
26201 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26202         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26203                         fail_val=$(((2*timeout + 10)*1000))
26204         touch $DIR/$tdir/d3/file &
26205         sleep 2
26206 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26207         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26208                         fail_val=$((2*timeout + 5))
26209         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26210         local pid=$!
26211         sleep 1
26212         kill -9 $pid
26213         sleep $((2 * timeout))
26214         echo kill $pid
26215         kill -9 $pid
26216         lctl mark touch
26217         touch $DIR/$tdir/d2/file3
26218         touch $DIR/$tdir/d2/file4
26219         touch $DIR/$tdir/d2/file5
26220
26221         wait
26222         at_max_set $amc client
26223         at_max_set $amo mds1
26224
26225         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26226         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26227                 error "Watchdog is always throttled"
26228 }
26229 run_test 422 "kill a process with RPC in progress"
26230
26231 stat_test() {
26232     df -h $MOUNT &
26233     df -h $MOUNT &
26234     df -h $MOUNT &
26235     df -h $MOUNT &
26236     df -h $MOUNT &
26237     df -h $MOUNT &
26238 }
26239
26240 test_423() {
26241     local _stats
26242     # ensure statfs cache is expired
26243     sleep 2;
26244
26245     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26246     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26247
26248     return 0
26249 }
26250 run_test 423 "statfs should return a right data"
26251
26252 test_424() {
26253 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26254         $LCTL set_param fail_loc=0x80000522
26255         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26256         rm -f $DIR/$tfile
26257 }
26258 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26259
26260 test_425() {
26261         test_mkdir -c -1 $DIR/$tdir
26262         $LFS setstripe -c -1 $DIR/$tdir
26263
26264         lru_resize_disable "" 100
26265         stack_trap "lru_resize_enable" EXIT
26266
26267         sleep 5
26268
26269         for i in $(seq $((MDSCOUNT * 125))); do
26270                 local t=$DIR/$tdir/$tfile_$i
26271
26272                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26273                         error_noexit "Create file $t"
26274         done
26275         stack_trap "rm -rf $DIR/$tdir" EXIT
26276
26277         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26278                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26279                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26280
26281                 [ $lock_count -le $lru_size ] ||
26282                         error "osc lock count $lock_count > lru size $lru_size"
26283         done
26284
26285         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26286                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26287                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26288
26289                 [ $lock_count -le $lru_size ] ||
26290                         error "mdc lock count $lock_count > lru size $lru_size"
26291         done
26292 }
26293 run_test 425 "lock count should not exceed lru size"
26294
26295 test_426() {
26296         splice-test -r $DIR/$tfile
26297         splice-test -rd $DIR/$tfile
26298         splice-test $DIR/$tfile
26299         splice-test -d $DIR/$tfile
26300 }
26301 run_test 426 "splice test on Lustre"
26302
26303 test_427() {
26304         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26305         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26306                 skip "Need MDS version at least 2.12.4"
26307         local log
26308
26309         mkdir $DIR/$tdir
26310         mkdir $DIR/$tdir/1
26311         mkdir $DIR/$tdir/2
26312         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26313         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26314
26315         $LFS getdirstripe $DIR/$tdir/1/dir
26316
26317         #first setfattr for creating updatelog
26318         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26319
26320 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26321         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26322         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26323         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26324
26325         sleep 2
26326         fail mds2
26327         wait_recovery_complete mds2 $((2*TIMEOUT))
26328
26329         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26330         echo $log | grep "get update log failed" &&
26331                 error "update log corruption is detected" || true
26332 }
26333 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26334
26335 test_428() {
26336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26337         local cache_limit=$CACHE_MAX
26338
26339         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26340         $LCTL set_param -n llite.*.max_cached_mb=64
26341
26342         mkdir $DIR/$tdir
26343         $LFS setstripe -c 1 $DIR/$tdir
26344         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26345         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26346         #test write
26347         for f in $(seq 4); do
26348                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26349         done
26350         wait
26351
26352         cancel_lru_locks osc
26353         # Test read
26354         for f in $(seq 4); do
26355                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26356         done
26357         wait
26358 }
26359 run_test 428 "large block size IO should not hang"
26360
26361 test_429() { # LU-7915 / LU-10948
26362         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26363         local testfile=$DIR/$tfile
26364         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26365         local new_flag=1
26366         local first_rpc
26367         local second_rpc
26368         local third_rpc
26369
26370         $LCTL get_param $ll_opencache_threshold_count ||
26371                 skip "client does not have opencache parameter"
26372
26373         set_opencache $new_flag
26374         stack_trap "restore_opencache"
26375         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26376                 error "enable opencache failed"
26377         touch $testfile
26378         # drop MDC DLM locks
26379         cancel_lru_locks mdc
26380         # clear MDC RPC stats counters
26381         $LCTL set_param $mdc_rpcstats=clear
26382
26383         # According to the current implementation, we need to run 3 times
26384         # open & close file to verify if opencache is enabled correctly.
26385         # 1st, RPCs are sent for lookup/open and open handle is released on
26386         #      close finally.
26387         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26388         #      so open handle won't be released thereafter.
26389         # 3rd, No RPC is sent out.
26390         $MULTIOP $testfile oc || error "multiop failed"
26391         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26392         echo "1st: $first_rpc RPCs in flight"
26393
26394         $MULTIOP $testfile oc || error "multiop failed"
26395         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26396         echo "2nd: $second_rpc RPCs in flight"
26397
26398         $MULTIOP $testfile oc || error "multiop failed"
26399         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26400         echo "3rd: $third_rpc RPCs in flight"
26401
26402         #verify no MDC RPC is sent
26403         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26404 }
26405 run_test 429 "verify if opencache flag on client side does work"
26406
26407 lseek_test_430() {
26408         local offset
26409         local file=$1
26410
26411         # data at [200K, 400K)
26412         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26413                 error "256K->512K dd fails"
26414         # data at [2M, 3M)
26415         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26416                 error "2M->3M dd fails"
26417         # data at [4M, 5M)
26418         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26419                 error "4M->5M dd fails"
26420         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26421         # start at first component hole #1
26422         printf "Seeking hole from 1000 ... "
26423         offset=$(lseek_test -l 1000 $file)
26424         echo $offset
26425         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26426         printf "Seeking data from 1000 ... "
26427         offset=$(lseek_test -d 1000 $file)
26428         echo $offset
26429         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26430
26431         # start at first component data block
26432         printf "Seeking hole from 300000 ... "
26433         offset=$(lseek_test -l 300000 $file)
26434         echo $offset
26435         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26436         printf "Seeking data from 300000 ... "
26437         offset=$(lseek_test -d 300000 $file)
26438         echo $offset
26439         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26440
26441         # start at the first component but beyond end of object size
26442         printf "Seeking hole from 1000000 ... "
26443         offset=$(lseek_test -l 1000000 $file)
26444         echo $offset
26445         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26446         printf "Seeking data from 1000000 ... "
26447         offset=$(lseek_test -d 1000000 $file)
26448         echo $offset
26449         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26450
26451         # start at second component stripe 2 (empty file)
26452         printf "Seeking hole from 1500000 ... "
26453         offset=$(lseek_test -l 1500000 $file)
26454         echo $offset
26455         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26456         printf "Seeking data from 1500000 ... "
26457         offset=$(lseek_test -d 1500000 $file)
26458         echo $offset
26459         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26460
26461         # start at second component stripe 1 (all data)
26462         printf "Seeking hole from 3000000 ... "
26463         offset=$(lseek_test -l 3000000 $file)
26464         echo $offset
26465         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26466         printf "Seeking data from 3000000 ... "
26467         offset=$(lseek_test -d 3000000 $file)
26468         echo $offset
26469         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26470
26471         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26472                 error "2nd dd fails"
26473         echo "Add data block at 640K...1280K"
26474
26475         # start at before new data block, in hole
26476         printf "Seeking hole from 600000 ... "
26477         offset=$(lseek_test -l 600000 $file)
26478         echo $offset
26479         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26480         printf "Seeking data from 600000 ... "
26481         offset=$(lseek_test -d 600000 $file)
26482         echo $offset
26483         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26484
26485         # start at the first component new data block
26486         printf "Seeking hole from 1000000 ... "
26487         offset=$(lseek_test -l 1000000 $file)
26488         echo $offset
26489         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26490         printf "Seeking data from 1000000 ... "
26491         offset=$(lseek_test -d 1000000 $file)
26492         echo $offset
26493         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26494
26495         # start at second component stripe 2, new data
26496         printf "Seeking hole from 1200000 ... "
26497         offset=$(lseek_test -l 1200000 $file)
26498         echo $offset
26499         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26500         printf "Seeking data from 1200000 ... "
26501         offset=$(lseek_test -d 1200000 $file)
26502         echo $offset
26503         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
26504
26505         # start beyond file end
26506         printf "Using offset > filesize ... "
26507         lseek_test -l 4000000 $file && error "lseek should fail"
26508         printf "Using offset > filesize ... "
26509         lseek_test -d 4000000 $file && error "lseek should fail"
26510
26511         printf "Done\n\n"
26512 }
26513
26514 test_430a() {
26515         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
26516                 skip "MDT does not support SEEK_HOLE"
26517
26518         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26519                 skip "OST does not support SEEK_HOLE"
26520
26521         local file=$DIR/$tdir/$tfile
26522
26523         mkdir -p $DIR/$tdir
26524
26525         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
26526         # OST stripe #1 will have continuous data at [1M, 3M)
26527         # OST stripe #2 is empty
26528         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
26529         lseek_test_430 $file
26530         rm $file
26531         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
26532         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
26533         lseek_test_430 $file
26534         rm $file
26535         $LFS setstripe -c2 -S 512K $file
26536         echo "Two stripes, stripe size 512K"
26537         lseek_test_430 $file
26538         rm $file
26539         # FLR with stale mirror
26540         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
26541                        -N -c2 -S 1M $file
26542         echo "Mirrored file:"
26543         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
26544         echo "Plain 2 stripes 1M"
26545         lseek_test_430 $file
26546         rm $file
26547 }
26548 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
26549
26550 test_430b() {
26551         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26552                 skip "OST does not support SEEK_HOLE"
26553
26554         local offset
26555         local file=$DIR/$tdir/$tfile
26556
26557         mkdir -p $DIR/$tdir
26558         # Empty layout lseek should fail
26559         $MCREATE $file
26560         # seek from 0
26561         printf "Seeking hole from 0 ... "
26562         lseek_test -l 0 $file && error "lseek should fail"
26563         printf "Seeking data from 0 ... "
26564         lseek_test -d 0 $file && error "lseek should fail"
26565         rm $file
26566
26567         # 1M-hole file
26568         $LFS setstripe -E 1M -c2 -E eof $file
26569         $TRUNCATE $file 1048576
26570         printf "Seeking hole from 1000000 ... "
26571         offset=$(lseek_test -l 1000000 $file)
26572         echo $offset
26573         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26574         printf "Seeking data from 1000000 ... "
26575         lseek_test -d 1000000 $file && error "lseek should fail"
26576         rm $file
26577
26578         # full component followed by non-inited one
26579         $LFS setstripe -E 1M -c2 -E eof $file
26580         dd if=/dev/urandom of=$file bs=1M count=1
26581         printf "Seeking hole from 1000000 ... "
26582         offset=$(lseek_test -l 1000000 $file)
26583         echo $offset
26584         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26585         printf "Seeking hole from 1048576 ... "
26586         lseek_test -l 1048576 $file && error "lseek should fail"
26587         # init second component and truncate back
26588         echo "123" >> $file
26589         $TRUNCATE $file 1048576
26590         printf "Seeking hole from 1000000 ... "
26591         offset=$(lseek_test -l 1000000 $file)
26592         echo $offset
26593         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26594         printf "Seeking hole from 1048576 ... "
26595         lseek_test -l 1048576 $file && error "lseek should fail"
26596         # boundary checks for big values
26597         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
26598         offset=$(lseek_test -d 0 $file.10g)
26599         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
26600         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
26601         offset=$(lseek_test -d 0 $file.100g)
26602         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
26603         return 0
26604 }
26605 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
26606
26607 test_430c() {
26608         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26609                 skip "OST does not support SEEK_HOLE"
26610
26611         local file=$DIR/$tdir/$tfile
26612         local start
26613
26614         mkdir -p $DIR/$tdir
26615         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
26616
26617         # cp version 8.33+ prefers lseek over fiemap
26618         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
26619                 start=$SECONDS
26620                 time cp $file /dev/null
26621                 (( SECONDS - start < 5 )) ||
26622                         error "cp: too long runtime $((SECONDS - start))"
26623
26624         fi
26625         # tar version 1.29+ supports SEEK_HOLE/DATA
26626         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
26627                 start=$SECONDS
26628                 time tar cS $file - | cat > /dev/null
26629                 (( SECONDS - start < 5 )) ||
26630                         error "tar: too long runtime $((SECONDS - start))"
26631         fi
26632 }
26633 run_test 430c "lseek: external tools check"
26634
26635 test_431() { # LU-14187
26636         local file=$DIR/$tdir/$tfile
26637
26638         mkdir -p $DIR/$tdir
26639         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
26640         dd if=/dev/urandom of=$file bs=4k count=1
26641         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
26642         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
26643         #define OBD_FAIL_OST_RESTART_IO 0x251
26644         do_facet ost1 "$LCTL set_param fail_loc=0x251"
26645         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
26646         cp $file $file.0
26647         cancel_lru_locks
26648         sync_all_data
26649         echo 3 > /proc/sys/vm/drop_caches
26650         diff  $file $file.0 || error "data diff"
26651 }
26652 run_test 431 "Restart transaction for IO"
26653
26654 cleanup_test_432() {
26655         do_facet mgs $LCTL nodemap_activate 0
26656         wait_nm_sync active
26657 }
26658
26659 test_432() {
26660         local tmpdir=$TMP/dir432
26661
26662         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
26663                 skip "Need MDS version at least 2.14.52"
26664
26665         stack_trap cleanup_test_432 EXIT
26666         mkdir $DIR/$tdir
26667         mkdir $tmpdir
26668
26669         do_facet mgs $LCTL nodemap_activate 1
26670         wait_nm_sync active
26671         do_facet mgs $LCTL nodemap_modify --name default \
26672                 --property admin --value 1
26673         do_facet mgs $LCTL nodemap_modify --name default \
26674                 --property trusted --value 1
26675         cancel_lru_locks mdc
26676         wait_nm_sync default admin_nodemap
26677         wait_nm_sync default trusted_nodemap
26678
26679         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
26680                grep -ci "Operation not permitted") -ne 0 ]; then
26681                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
26682         fi
26683 }
26684 run_test 432 "mv dir from outside Lustre"
26685
26686 prep_801() {
26687         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26688         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26689                 skip "Need server version at least 2.9.55"
26690
26691         start_full_debug_logging
26692 }
26693
26694 post_801() {
26695         stop_full_debug_logging
26696 }
26697
26698 barrier_stat() {
26699         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26700                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26701                            awk '/The barrier for/ { print $7 }')
26702                 echo $st
26703         else
26704                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
26705                 echo \'$st\'
26706         fi
26707 }
26708
26709 barrier_expired() {
26710         local expired
26711
26712         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26713                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26714                           awk '/will be expired/ { print $7 }')
26715         else
26716                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
26717         fi
26718
26719         echo $expired
26720 }
26721
26722 test_801a() {
26723         prep_801
26724
26725         echo "Start barrier_freeze at: $(date)"
26726         #define OBD_FAIL_BARRIER_DELAY          0x2202
26727         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26728         # Do not reduce barrier time - See LU-11873
26729         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
26730
26731         sleep 2
26732         local b_status=$(barrier_stat)
26733         echo "Got barrier status at: $(date)"
26734         [ "$b_status" = "'freezing_p1'" ] ||
26735                 error "(1) unexpected barrier status $b_status"
26736
26737         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26738         wait
26739         b_status=$(barrier_stat)
26740         [ "$b_status" = "'frozen'" ] ||
26741                 error "(2) unexpected barrier status $b_status"
26742
26743         local expired=$(barrier_expired)
26744         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
26745         sleep $((expired + 3))
26746
26747         b_status=$(barrier_stat)
26748         [ "$b_status" = "'expired'" ] ||
26749                 error "(3) unexpected barrier status $b_status"
26750
26751         # Do not reduce barrier time - See LU-11873
26752         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
26753                 error "(4) fail to freeze barrier"
26754
26755         b_status=$(barrier_stat)
26756         [ "$b_status" = "'frozen'" ] ||
26757                 error "(5) unexpected barrier status $b_status"
26758
26759         echo "Start barrier_thaw at: $(date)"
26760         #define OBD_FAIL_BARRIER_DELAY          0x2202
26761         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26762         do_facet mgs $LCTL barrier_thaw $FSNAME &
26763
26764         sleep 2
26765         b_status=$(barrier_stat)
26766         echo "Got barrier status at: $(date)"
26767         [ "$b_status" = "'thawing'" ] ||
26768                 error "(6) unexpected barrier status $b_status"
26769
26770         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26771         wait
26772         b_status=$(barrier_stat)
26773         [ "$b_status" = "'thawed'" ] ||
26774                 error "(7) unexpected barrier status $b_status"
26775
26776         #define OBD_FAIL_BARRIER_FAILURE        0x2203
26777         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
26778         do_facet mgs $LCTL barrier_freeze $FSNAME
26779
26780         b_status=$(barrier_stat)
26781         [ "$b_status" = "'failed'" ] ||
26782                 error "(8) unexpected barrier status $b_status"
26783
26784         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
26785         do_facet mgs $LCTL barrier_thaw $FSNAME
26786
26787         post_801
26788 }
26789 run_test 801a "write barrier user interfaces and stat machine"
26790
26791 test_801b() {
26792         prep_801
26793
26794         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26795         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
26796         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
26797         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
26798         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
26799
26800         cancel_lru_locks mdc
26801
26802         # 180 seconds should be long enough
26803         do_facet mgs $LCTL barrier_freeze $FSNAME 180
26804
26805         local b_status=$(barrier_stat)
26806         [ "$b_status" = "'frozen'" ] ||
26807                 error "(6) unexpected barrier status $b_status"
26808
26809         mkdir $DIR/$tdir/d0/d10 &
26810         mkdir_pid=$!
26811
26812         touch $DIR/$tdir/d1/f13 &
26813         touch_pid=$!
26814
26815         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
26816         ln_pid=$!
26817
26818         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
26819         mv_pid=$!
26820
26821         rm -f $DIR/$tdir/d4/f12 &
26822         rm_pid=$!
26823
26824         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
26825
26826         # To guarantee taht the 'stat' is not blocked
26827         b_status=$(barrier_stat)
26828         [ "$b_status" = "'frozen'" ] ||
26829                 error "(8) unexpected barrier status $b_status"
26830
26831         # let above commands to run at background
26832         sleep 5
26833
26834         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
26835         ps -p $touch_pid || error "(10) touch should be blocked"
26836         ps -p $ln_pid || error "(11) link should be blocked"
26837         ps -p $mv_pid || error "(12) rename should be blocked"
26838         ps -p $rm_pid || error "(13) unlink should be blocked"
26839
26840         b_status=$(barrier_stat)
26841         [ "$b_status" = "'frozen'" ] ||
26842                 error "(14) unexpected barrier status $b_status"
26843
26844         do_facet mgs $LCTL barrier_thaw $FSNAME
26845         b_status=$(barrier_stat)
26846         [ "$b_status" = "'thawed'" ] ||
26847                 error "(15) unexpected barrier status $b_status"
26848
26849         wait $mkdir_pid || error "(16) mkdir should succeed"
26850         wait $touch_pid || error "(17) touch should succeed"
26851         wait $ln_pid || error "(18) link should succeed"
26852         wait $mv_pid || error "(19) rename should succeed"
26853         wait $rm_pid || error "(20) unlink should succeed"
26854
26855         post_801
26856 }
26857 run_test 801b "modification will be blocked by write barrier"
26858
26859 test_801c() {
26860         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26861
26862         prep_801
26863
26864         stop mds2 || error "(1) Fail to stop mds2"
26865
26866         do_facet mgs $LCTL barrier_freeze $FSNAME 30
26867
26868         local b_status=$(barrier_stat)
26869         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
26870                 do_facet mgs $LCTL barrier_thaw $FSNAME
26871                 error "(2) unexpected barrier status $b_status"
26872         }
26873
26874         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26875                 error "(3) Fail to rescan barrier bitmap"
26876
26877         # Do not reduce barrier time - See LU-11873
26878         do_facet mgs $LCTL barrier_freeze $FSNAME 20
26879
26880         b_status=$(barrier_stat)
26881         [ "$b_status" = "'frozen'" ] ||
26882                 error "(4) unexpected barrier status $b_status"
26883
26884         do_facet mgs $LCTL barrier_thaw $FSNAME
26885         b_status=$(barrier_stat)
26886         [ "$b_status" = "'thawed'" ] ||
26887                 error "(5) unexpected barrier status $b_status"
26888
26889         local devname=$(mdsdevname 2)
26890
26891         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
26892
26893         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26894                 error "(7) Fail to rescan barrier bitmap"
26895
26896         post_801
26897 }
26898 run_test 801c "rescan barrier bitmap"
26899
26900 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
26901 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
26902 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
26903 saved_MOUNT_OPTS=$MOUNT_OPTS
26904
26905 cleanup_802a() {
26906         trap 0
26907
26908         stopall
26909         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
26910         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
26911         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
26912         MOUNT_OPTS=$saved_MOUNT_OPTS
26913         setupall
26914 }
26915
26916 test_802a() {
26917         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
26918         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26919         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26920                 skip "Need server version at least 2.9.55"
26921
26922         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
26923
26924         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26925
26926         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26927                 error "(2) Fail to copy"
26928
26929         trap cleanup_802a EXIT
26930
26931         # sync by force before remount as readonly
26932         sync; sync_all_data; sleep 3; sync_all_data
26933
26934         stopall
26935
26936         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
26937         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
26938         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
26939
26940         echo "Mount the server as read only"
26941         setupall server_only || error "(3) Fail to start servers"
26942
26943         echo "Mount client without ro should fail"
26944         mount_client $MOUNT &&
26945                 error "(4) Mount client without 'ro' should fail"
26946
26947         echo "Mount client with ro should succeed"
26948         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
26949         mount_client $MOUNT ||
26950                 error "(5) Mount client with 'ro' should succeed"
26951
26952         echo "Modify should be refused"
26953         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26954
26955         echo "Read should be allowed"
26956         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26957                 error "(7) Read should succeed under ro mode"
26958
26959         cleanup_802a
26960 }
26961 run_test 802a "simulate readonly device"
26962
26963 test_802b() {
26964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26965         remote_mds_nodsh && skip "remote MDS with nodsh"
26966
26967         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
26968                 skip "readonly option not available"
26969
26970         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
26971
26972         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26973                 error "(2) Fail to copy"
26974
26975         # write back all cached data before setting MDT to readonly
26976         cancel_lru_locks
26977         sync_all_data
26978
26979         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
26980         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
26981
26982         echo "Modify should be refused"
26983         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26984
26985         echo "Read should be allowed"
26986         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26987                 error "(7) Read should succeed under ro mode"
26988
26989         # disable readonly
26990         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
26991 }
26992 run_test 802b "be able to set MDTs to readonly"
26993
26994 test_803a() {
26995         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26996         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26997                 skip "MDS needs to be newer than 2.10.54"
26998
26999         mkdir_on_mdt0 $DIR/$tdir
27000         # Create some objects on all MDTs to trigger related logs objects
27001         for idx in $(seq $MDSCOUNT); do
27002                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27003                         $DIR/$tdir/dir${idx} ||
27004                         error "Fail to create $DIR/$tdir/dir${idx}"
27005         done
27006
27007         sync; sleep 3
27008         wait_delete_completed # ensure old test cleanups are finished
27009         echo "before create:"
27010         $LFS df -i $MOUNT
27011         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27012
27013         for i in {1..10}; do
27014                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27015                         error "Fail to create $DIR/$tdir/foo$i"
27016         done
27017
27018         sync; sleep 3
27019         echo "after create:"
27020         $LFS df -i $MOUNT
27021         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27022
27023         # allow for an llog to be cleaned up during the test
27024         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27025                 error "before ($before_used) + 10 > after ($after_used)"
27026
27027         for i in {1..10}; do
27028                 rm -rf $DIR/$tdir/foo$i ||
27029                         error "Fail to remove $DIR/$tdir/foo$i"
27030         done
27031
27032         sleep 3 # avoid MDT return cached statfs
27033         wait_delete_completed
27034         echo "after unlink:"
27035         $LFS df -i $MOUNT
27036         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27037
27038         # allow for an llog to be created during the test
27039         [ $after_used -le $((before_used + 1)) ] ||
27040                 error "after ($after_used) > before ($before_used) + 1"
27041 }
27042 run_test 803a "verify agent object for remote object"
27043
27044 test_803b() {
27045         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27046         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27047                 skip "MDS needs to be newer than 2.13.56"
27048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27049
27050         for i in $(seq 0 $((MDSCOUNT - 1))); do
27051                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27052         done
27053
27054         local before=0
27055         local after=0
27056
27057         local tmp
27058
27059         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27060         for i in $(seq 0 $((MDSCOUNT - 1))); do
27061                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27062                         awk '/getattr/ { print $2 }')
27063                 before=$((before + tmp))
27064         done
27065         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27066         for i in $(seq 0 $((MDSCOUNT - 1))); do
27067                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27068                         awk '/getattr/ { print $2 }')
27069                 after=$((after + tmp))
27070         done
27071
27072         [ $before -eq $after ] || error "getattr count $before != $after"
27073 }
27074 run_test 803b "remote object can getattr from cache"
27075
27076 test_804() {
27077         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27078         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27079                 skip "MDS needs to be newer than 2.10.54"
27080         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27081
27082         mkdir -p $DIR/$tdir
27083         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27084                 error "Fail to create $DIR/$tdir/dir0"
27085
27086         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27087         local dev=$(mdsdevname 2)
27088
27089         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27090                 grep ${fid} || error "NOT found agent entry for dir0"
27091
27092         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27093                 error "Fail to create $DIR/$tdir/dir1"
27094
27095         touch $DIR/$tdir/dir1/foo0 ||
27096                 error "Fail to create $DIR/$tdir/dir1/foo0"
27097         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27098         local rc=0
27099
27100         for idx in $(seq $MDSCOUNT); do
27101                 dev=$(mdsdevname $idx)
27102                 do_facet mds${idx} \
27103                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27104                         grep ${fid} && rc=$idx
27105         done
27106
27107         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27108                 error "Fail to rename foo0 to foo1"
27109         if [ $rc -eq 0 ]; then
27110                 for idx in $(seq $MDSCOUNT); do
27111                         dev=$(mdsdevname $idx)
27112                         do_facet mds${idx} \
27113                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27114                         grep ${fid} && rc=$idx
27115                 done
27116         fi
27117
27118         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27119                 error "Fail to rename foo1 to foo2"
27120         if [ $rc -eq 0 ]; then
27121                 for idx in $(seq $MDSCOUNT); do
27122                         dev=$(mdsdevname $idx)
27123                         do_facet mds${idx} \
27124                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27125                         grep ${fid} && rc=$idx
27126                 done
27127         fi
27128
27129         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27130
27131         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27132                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27133         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27134                 error "Fail to rename foo2 to foo0"
27135         unlink $DIR/$tdir/dir1/foo0 ||
27136                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27137         rm -rf $DIR/$tdir/dir0 ||
27138                 error "Fail to rm $DIR/$tdir/dir0"
27139
27140         for idx in $(seq $MDSCOUNT); do
27141                 dev=$(mdsdevname $idx)
27142                 rc=0
27143
27144                 stop mds${idx}
27145                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27146                         rc=$?
27147                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27148                         error "mount mds$idx failed"
27149                 df $MOUNT > /dev/null 2>&1
27150
27151                 # e2fsck should not return error
27152                 [ $rc -eq 0 ] ||
27153                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27154         done
27155 }
27156 run_test 804 "verify agent entry for remote entry"
27157
27158 cleanup_805() {
27159         do_facet $SINGLEMDS zfs set quota=$old $fsset
27160         unlinkmany $DIR/$tdir/f- 1000000
27161         trap 0
27162 }
27163
27164 test_805() {
27165         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
27166         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
27167         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
27168                 skip "netfree not implemented before 0.7"
27169         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
27170                 skip "Need MDS version at least 2.10.57"
27171
27172         local fsset
27173         local freekb
27174         local usedkb
27175         local old
27176         local quota
27177         local pref="osd-zfs.$FSNAME-MDT0000."
27178
27179         # limit available space on MDS dataset to meet nospace issue
27180         # quickly. then ZFS 0.7.2 can use reserved space if asked
27181         # properly (using netfree flag in osd_declare_destroy()
27182         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
27183         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
27184                 gawk '{print $3}')
27185         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
27186         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
27187         let "usedkb=usedkb-freekb"
27188         let "freekb=freekb/2"
27189         if let "freekb > 5000"; then
27190                 let "freekb=5000"
27191         fi
27192         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
27193         trap cleanup_805 EXIT
27194         mkdir_on_mdt0 $DIR/$tdir
27195         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
27196                 error "Can't set PFL layout"
27197         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27198         rm -rf $DIR/$tdir || error "not able to remove"
27199         do_facet $SINGLEMDS zfs set quota=$old $fsset
27200         trap 0
27201 }
27202 run_test 805 "ZFS can remove from full fs"
27203
27204 # Size-on-MDS test
27205 check_lsom_data()
27206 {
27207         local file=$1
27208         local expect=$(stat -c %s $file)
27209
27210         check_lsom_size $1 $expect
27211
27212         local blocks=$($LFS getsom -b $file)
27213         expect=$(stat -c %b $file)
27214         [[ $blocks == $expect ]] ||
27215                 error "$file expected blocks: $expect, got: $blocks"
27216 }
27217
27218 check_lsom_size()
27219 {
27220         local size
27221         local expect=$2
27222
27223         cancel_lru_locks mdc
27224
27225         size=$($LFS getsom -s $1)
27226         [[ $size == $expect ]] ||
27227                 error "$file expected size: $expect, got: $size"
27228 }
27229
27230 test_806() {
27231         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27232                 skip "Need MDS version at least 2.11.52"
27233
27234         local bs=1048576
27235
27236         touch $DIR/$tfile || error "touch $tfile failed"
27237
27238         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27239         save_lustre_params client "llite.*.xattr_cache" > $save
27240         lctl set_param llite.*.xattr_cache=0
27241         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27242
27243         # single-threaded write
27244         echo "Test SOM for single-threaded write"
27245         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27246                 error "write $tfile failed"
27247         check_lsom_size $DIR/$tfile $bs
27248
27249         local num=32
27250         local size=$(($num * $bs))
27251         local offset=0
27252         local i
27253
27254         echo "Test SOM for single client multi-threaded($num) write"
27255         $TRUNCATE $DIR/$tfile 0
27256         for ((i = 0; i < $num; i++)); do
27257                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27258                 local pids[$i]=$!
27259                 offset=$((offset + $bs))
27260         done
27261         for (( i=0; i < $num; i++ )); do
27262                 wait ${pids[$i]}
27263         done
27264         check_lsom_size $DIR/$tfile $size
27265
27266         $TRUNCATE $DIR/$tfile 0
27267         for ((i = 0; i < $num; i++)); do
27268                 offset=$((offset - $bs))
27269                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27270                 local pids[$i]=$!
27271         done
27272         for (( i=0; i < $num; i++ )); do
27273                 wait ${pids[$i]}
27274         done
27275         check_lsom_size $DIR/$tfile $size
27276
27277         # multi-client writes
27278         num=$(get_node_count ${CLIENTS//,/ })
27279         size=$(($num * $bs))
27280         offset=0
27281         i=0
27282
27283         echo "Test SOM for multi-client ($num) writes"
27284         $TRUNCATE $DIR/$tfile 0
27285         for client in ${CLIENTS//,/ }; do
27286                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27287                 local pids[$i]=$!
27288                 i=$((i + 1))
27289                 offset=$((offset + $bs))
27290         done
27291         for (( i=0; i < $num; i++ )); do
27292                 wait ${pids[$i]}
27293         done
27294         check_lsom_size $DIR/$tfile $offset
27295
27296         i=0
27297         $TRUNCATE $DIR/$tfile 0
27298         for client in ${CLIENTS//,/ }; do
27299                 offset=$((offset - $bs))
27300                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27301                 local pids[$i]=$!
27302                 i=$((i + 1))
27303         done
27304         for (( i=0; i < $num; i++ )); do
27305                 wait ${pids[$i]}
27306         done
27307         check_lsom_size $DIR/$tfile $size
27308
27309         # verify truncate
27310         echo "Test SOM for truncate"
27311         $TRUNCATE $DIR/$tfile 1048576
27312         check_lsom_size $DIR/$tfile 1048576
27313         $TRUNCATE $DIR/$tfile 1234
27314         check_lsom_size $DIR/$tfile 1234
27315
27316         # verify SOM blocks count
27317         echo "Verify SOM block count"
27318         $TRUNCATE $DIR/$tfile 0
27319         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27320                 error "failed to write file $tfile"
27321         check_lsom_data $DIR/$tfile
27322 }
27323 run_test 806 "Verify Lazy Size on MDS"
27324
27325 test_807() {
27326         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27327         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27328                 skip "Need MDS version at least 2.11.52"
27329
27330         # Registration step
27331         changelog_register || error "changelog_register failed"
27332         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27333         changelog_users $SINGLEMDS | grep -q $cl_user ||
27334                 error "User $cl_user not found in changelog_users"
27335
27336         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27337         save_lustre_params client "llite.*.xattr_cache" > $save
27338         lctl set_param llite.*.xattr_cache=0
27339         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27340
27341         rm -rf $DIR/$tdir || error "rm $tdir failed"
27342         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27343         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27344         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27345         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27346                 error "truncate $tdir/trunc failed"
27347
27348         local bs=1048576
27349         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27350                 error "write $tfile failed"
27351
27352         # multi-client wirtes
27353         local num=$(get_node_count ${CLIENTS//,/ })
27354         local offset=0
27355         local i=0
27356
27357         echo "Test SOM for multi-client ($num) writes"
27358         touch $DIR/$tfile || error "touch $tfile failed"
27359         $TRUNCATE $DIR/$tfile 0
27360         for client in ${CLIENTS//,/ }; do
27361                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27362                 local pids[$i]=$!
27363                 i=$((i + 1))
27364                 offset=$((offset + $bs))
27365         done
27366         for (( i=0; i < $num; i++ )); do
27367                 wait ${pids[$i]}
27368         done
27369
27370         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27371         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27372         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27373         check_lsom_data $DIR/$tdir/trunc
27374         check_lsom_data $DIR/$tdir/single_dd
27375         check_lsom_data $DIR/$tfile
27376
27377         rm -rf $DIR/$tdir
27378         # Deregistration step
27379         changelog_deregister || error "changelog_deregister failed"
27380 }
27381 run_test 807 "verify LSOM syncing tool"
27382
27383 check_som_nologged()
27384 {
27385         local lines=$($LFS changelog $FSNAME-MDT0000 |
27386                 grep 'x=trusted.som' | wc -l)
27387         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27388 }
27389
27390 test_808() {
27391         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27392                 skip "Need MDS version at least 2.11.55"
27393
27394         # Registration step
27395         changelog_register || error "changelog_register failed"
27396
27397         touch $DIR/$tfile || error "touch $tfile failed"
27398         check_som_nologged
27399
27400         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27401                 error "write $tfile failed"
27402         check_som_nologged
27403
27404         $TRUNCATE $DIR/$tfile 1234
27405         check_som_nologged
27406
27407         $TRUNCATE $DIR/$tfile 1048576
27408         check_som_nologged
27409
27410         # Deregistration step
27411         changelog_deregister || error "changelog_deregister failed"
27412 }
27413 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27414
27415 check_som_nodata()
27416 {
27417         $LFS getsom $1
27418         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27419 }
27420
27421 test_809() {
27422         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27423                 skip "Need MDS version at least 2.11.56"
27424
27425         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27426                 error "failed to create DoM-only file $DIR/$tfile"
27427         touch $DIR/$tfile || error "touch $tfile failed"
27428         check_som_nodata $DIR/$tfile
27429
27430         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27431                 error "write $tfile failed"
27432         check_som_nodata $DIR/$tfile
27433
27434         $TRUNCATE $DIR/$tfile 1234
27435         check_som_nodata $DIR/$tfile
27436
27437         $TRUNCATE $DIR/$tfile 4097
27438         check_som_nodata $DIR/$file
27439 }
27440 run_test 809 "Verify no SOM xattr store for DoM-only files"
27441
27442 test_810() {
27443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27444         $GSS && skip_env "could not run with gss"
27445         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27446                 skip "OST < 2.12.58 doesn't align checksum"
27447
27448         set_checksums 1
27449         stack_trap "set_checksums $ORIG_CSUM" EXIT
27450         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27451
27452         local csum
27453         local before
27454         local after
27455         for csum in $CKSUM_TYPES; do
27456                 #define OBD_FAIL_OSC_NO_GRANT   0x411
27457                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
27458                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
27459                         eval set -- $i
27460                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
27461                         before=$(md5sum $DIR/$tfile)
27462                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
27463                         after=$(md5sum $DIR/$tfile)
27464                         [ "$before" == "$after" ] ||
27465                                 error "$csum: $before != $after bs=$1 seek=$2"
27466                 done
27467         done
27468 }
27469 run_test 810 "partial page writes on ZFS (LU-11663)"
27470
27471 test_812a() {
27472         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27473                 skip "OST < 2.12.51 doesn't support this fail_loc"
27474
27475         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27476         # ensure ost1 is connected
27477         stat $DIR/$tfile >/dev/null || error "can't stat"
27478         wait_osc_import_state client ost1 FULL
27479         # no locks, no reqs to let the connection idle
27480         cancel_lru_locks osc
27481
27482         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27483 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27484         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27485         wait_osc_import_state client ost1 CONNECTING
27486         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27487
27488         stat $DIR/$tfile >/dev/null || error "can't stat file"
27489 }
27490 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
27491
27492 test_812b() { # LU-12378
27493         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27494                 skip "OST < 2.12.51 doesn't support this fail_loc"
27495
27496         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
27497         # ensure ost1 is connected
27498         stat $DIR/$tfile >/dev/null || error "can't stat"
27499         wait_osc_import_state client ost1 FULL
27500         # no locks, no reqs to let the connection idle
27501         cancel_lru_locks osc
27502
27503         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27504 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27505         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27506         wait_osc_import_state client ost1 CONNECTING
27507         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27508
27509         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
27510         wait_osc_import_state client ost1 IDLE
27511 }
27512 run_test 812b "do not drop no resend request for idle connect"
27513
27514 test_812c() {
27515         local old
27516
27517         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
27518
27519         $LFS setstripe -c 1 -o 0 $DIR/$tfile
27520         $LFS getstripe $DIR/$tfile
27521         $LCTL set_param osc.*.idle_timeout=10
27522         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
27523         # ensure ost1 is connected
27524         stat $DIR/$tfile >/dev/null || error "can't stat"
27525         wait_osc_import_state client ost1 FULL
27526         # no locks, no reqs to let the connection idle
27527         cancel_lru_locks osc
27528
27529 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
27530         $LCTL set_param fail_loc=0x80000533
27531         sleep 15
27532         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
27533 }
27534 run_test 812c "idle import vs lock enqueue race"
27535
27536 test_813() {
27537         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
27538         [ -z "$file_heat_sav" ] && skip "no file heat support"
27539
27540         local readsample
27541         local writesample
27542         local readbyte
27543         local writebyte
27544         local readsample1
27545         local writesample1
27546         local readbyte1
27547         local writebyte1
27548
27549         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
27550         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
27551
27552         $LCTL set_param -n llite.*.file_heat=1
27553         echo "Turn on file heat"
27554         echo "Period second: $period_second, Decay percentage: $decay_pct"
27555
27556         echo "QQQQ" > $DIR/$tfile
27557         echo "QQQQ" > $DIR/$tfile
27558         echo "QQQQ" > $DIR/$tfile
27559         cat $DIR/$tfile > /dev/null
27560         cat $DIR/$tfile > /dev/null
27561         cat $DIR/$tfile > /dev/null
27562         cat $DIR/$tfile > /dev/null
27563
27564         local out=$($LFS heat_get $DIR/$tfile)
27565
27566         $LFS heat_get $DIR/$tfile
27567         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27568         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27569         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27570         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27571
27572         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
27573         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
27574         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
27575         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
27576
27577         sleep $((period_second + 3))
27578         echo "Sleep $((period_second + 3)) seconds..."
27579         # The recursion formula to calculate the heat of the file f is as
27580         # follow:
27581         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
27582         # Where Hi is the heat value in the period between time points i*I and
27583         # (i+1)*I; Ci is the access count in the period; the symbol P refers
27584         # to the weight of Ci.
27585         out=$($LFS heat_get $DIR/$tfile)
27586         $LFS heat_get $DIR/$tfile
27587         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27588         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27589         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27590         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27591
27592         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
27593                 error "read sample ($readsample) is wrong"
27594         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
27595                 error "write sample ($writesample) is wrong"
27596         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
27597                 error "read bytes ($readbyte) is wrong"
27598         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
27599                 error "write bytes ($writebyte) is wrong"
27600
27601         echo "QQQQ" > $DIR/$tfile
27602         echo "QQQQ" > $DIR/$tfile
27603         echo "QQQQ" > $DIR/$tfile
27604         cat $DIR/$tfile > /dev/null
27605         cat $DIR/$tfile > /dev/null
27606         cat $DIR/$tfile > /dev/null
27607         cat $DIR/$tfile > /dev/null
27608
27609         sleep $((period_second + 3))
27610         echo "Sleep $((period_second + 3)) seconds..."
27611
27612         out=$($LFS heat_get $DIR/$tfile)
27613         $LFS heat_get $DIR/$tfile
27614         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27615         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27616         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27617         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27618
27619         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
27620                 4 * $decay_pct) / 100") -eq 1 ] ||
27621                 error "read sample ($readsample1) is wrong"
27622         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
27623                 3 * $decay_pct) / 100") -eq 1 ] ||
27624                 error "write sample ($writesample1) is wrong"
27625         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
27626                 20 * $decay_pct) / 100") -eq 1 ] ||
27627                 error "read bytes ($readbyte1) is wrong"
27628         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
27629                 15 * $decay_pct) / 100") -eq 1 ] ||
27630                 error "write bytes ($writebyte1) is wrong"
27631
27632         echo "Turn off file heat for the file $DIR/$tfile"
27633         $LFS heat_set -o $DIR/$tfile
27634
27635         echo "QQQQ" > $DIR/$tfile
27636         echo "QQQQ" > $DIR/$tfile
27637         echo "QQQQ" > $DIR/$tfile
27638         cat $DIR/$tfile > /dev/null
27639         cat $DIR/$tfile > /dev/null
27640         cat $DIR/$tfile > /dev/null
27641         cat $DIR/$tfile > /dev/null
27642
27643         out=$($LFS heat_get $DIR/$tfile)
27644         $LFS heat_get $DIR/$tfile
27645         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27646         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27647         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27648         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27649
27650         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27651         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27652         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27653         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27654
27655         echo "Trun on file heat for the file $DIR/$tfile"
27656         $LFS heat_set -O $DIR/$tfile
27657
27658         echo "QQQQ" > $DIR/$tfile
27659         echo "QQQQ" > $DIR/$tfile
27660         echo "QQQQ" > $DIR/$tfile
27661         cat $DIR/$tfile > /dev/null
27662         cat $DIR/$tfile > /dev/null
27663         cat $DIR/$tfile > /dev/null
27664         cat $DIR/$tfile > /dev/null
27665
27666         out=$($LFS heat_get $DIR/$tfile)
27667         $LFS heat_get $DIR/$tfile
27668         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27669         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27670         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27671         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27672
27673         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
27674         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
27675         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
27676         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
27677
27678         $LFS heat_set -c $DIR/$tfile
27679         $LCTL set_param -n llite.*.file_heat=0
27680         echo "Turn off file heat support for the Lustre filesystem"
27681
27682         echo "QQQQ" > $DIR/$tfile
27683         echo "QQQQ" > $DIR/$tfile
27684         echo "QQQQ" > $DIR/$tfile
27685         cat $DIR/$tfile > /dev/null
27686         cat $DIR/$tfile > /dev/null
27687         cat $DIR/$tfile > /dev/null
27688         cat $DIR/$tfile > /dev/null
27689
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         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27698         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27699         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27700         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27701
27702         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
27703         rm -f $DIR/$tfile
27704 }
27705 run_test 813 "File heat verfication"
27706
27707 test_814()
27708 {
27709         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
27710         echo -n y >> $DIR/$tfile
27711         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
27712         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
27713 }
27714 run_test 814 "sparse cp works as expected (LU-12361)"
27715
27716 test_815()
27717 {
27718         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
27719         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
27720 }
27721 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
27722
27723 test_816() {
27724         local ost1_imp=$(get_osc_import_name client ost1)
27725         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27726                          cut -d'.' -f2)
27727
27728         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27729         # ensure ost1 is connected
27730
27731         stat $DIR/$tfile >/dev/null || error "can't stat"
27732         wait_osc_import_state client ost1 FULL
27733         # no locks, no reqs to let the connection idle
27734         cancel_lru_locks osc
27735         lru_resize_disable osc
27736         local before
27737         local now
27738         before=$($LCTL get_param -n \
27739                  ldlm.namespaces.$imp_name.lru_size)
27740
27741         wait_osc_import_state client ost1 IDLE
27742         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
27743         now=$($LCTL get_param -n \
27744               ldlm.namespaces.$imp_name.lru_size)
27745         [ $before == $now ] || error "lru_size changed $before != $now"
27746 }
27747 run_test 816 "do not reset lru_resize on idle reconnect"
27748
27749 cleanup_817() {
27750         umount $tmpdir
27751         exportfs -u localhost:$DIR/nfsexp
27752         rm -rf $DIR/nfsexp
27753 }
27754
27755 test_817() {
27756         systemctl restart nfs-server.service || skip "failed to restart nfsd"
27757
27758         mkdir -p $DIR/nfsexp
27759         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
27760                 error "failed to export nfs"
27761
27762         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
27763         stack_trap cleanup_817 EXIT
27764
27765         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
27766                 error "failed to mount nfs to $tmpdir"
27767
27768         cp /bin/true $tmpdir
27769         $DIR/nfsexp/true || error "failed to execute 'true' command"
27770 }
27771 run_test 817 "nfsd won't cache write lock for exec file"
27772
27773 test_818() {
27774         test_mkdir -i0 -c1 $DIR/$tdir
27775         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
27776         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
27777         stop $SINGLEMDS
27778
27779         # restore osp-syn threads
27780         stack_trap "fail $SINGLEMDS"
27781
27782         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
27783         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
27784         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
27785                 error "start $SINGLEMDS failed"
27786         rm -rf $DIR/$tdir
27787
27788         local testid=$(echo $TESTNAME | tr '_' ' ')
27789
27790         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
27791                 grep "run LFSCK" || error "run LFSCK is not suggested"
27792 }
27793 run_test 818 "unlink with failed llog"
27794
27795 test_819a() {
27796         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27797         cancel_lru_locks osc
27798         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27799         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27800         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
27801         rm -f $TDIR/$tfile
27802 }
27803 run_test 819a "too big niobuf in read"
27804
27805 test_819b() {
27806         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27807         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27808         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27809         cancel_lru_locks osc
27810         sleep 1
27811         rm -f $TDIR/$tfile
27812 }
27813 run_test 819b "too big niobuf in write"
27814
27815
27816 function test_820_start_ost() {
27817         sleep 5
27818
27819         for num in $(seq $OSTCOUNT); do
27820                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
27821         done
27822 }
27823
27824 test_820() {
27825         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27826
27827         mkdir $DIR/$tdir
27828         umount_client $MOUNT || error "umount failed"
27829         for num in $(seq $OSTCOUNT); do
27830                 stop ost$num
27831         done
27832
27833         # mount client with no active OSTs
27834         # so that the client can't initialize max LOV EA size
27835         # from OSC notifications
27836         mount_client $MOUNT || error "mount failed"
27837         # delay OST starting to keep this 0 max EA size for a while
27838         test_820_start_ost &
27839
27840         # create a directory on MDS2
27841         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
27842                 error "Failed to create directory"
27843         # open intent should update default EA size
27844         # see mdc_update_max_ea_from_body()
27845         # notice this is the very first RPC to MDS2
27846         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
27847         ret=$?
27848         echo $out
27849         # With SSK, this situation can lead to -EPERM being returned.
27850         # In that case, simply retry.
27851         if [ $ret -ne 0 ] && $SHARED_KEY; then
27852                 if echo "$out" | grep -q "not permitted"; then
27853                         cp /etc/services $DIR/$tdir/mds2
27854                         ret=$?
27855                 fi
27856         fi
27857         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
27858 }
27859 run_test 820 "update max EA from open intent"
27860
27861 test_822() {
27862         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27863
27864         save_lustre_params mds1 \
27865                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27866         do_facet $SINGLEMDS "$LCTL set_param -n \
27867                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
27868         do_facet $SINGLEMDS "$LCTL set_param -n \
27869                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
27870
27871         # wait for statfs update to clear OS_STATFS_NOPRECREATE
27872         local maxage=$(do_facet mds1 $LCTL get_param -n \
27873                        osp.$FSNAME-OST0000*MDT0000.maxage)
27874         sleep $((maxage + 1))
27875
27876         #define OBD_FAIL_NET_ERROR_RPC          0x532
27877         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
27878
27879         stack_trap "restore_lustre_params < $p; rm $p"
27880
27881         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
27882                       osp.$FSNAME-OST0000*MDT0000.create_count")
27883         for i in $(seq 1 $count); do
27884                 touch $DIR/$tfile.${i} || error "touch failed"
27885         done
27886 }
27887 run_test 822 "test precreate failure"
27888
27889 test_823() {
27890         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27891         local OST_MAX_PRECREATE=20000
27892
27893         save_lustre_params mds1 \
27894                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27895         do_facet $SINGLEMDS "$LCTL set_param -n \
27896                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
27897         do_facet $SINGLEMDS "$LCTL set_param -n \
27898                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
27899
27900         stack_trap "restore_lustre_params < $p; rm $p"
27901
27902         do_facet $SINGLEMDS "$LCTL set_param -n \
27903                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
27904
27905         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27906                       osp.$FSNAME-OST0000*MDT0000.create_count")
27907         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27908                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
27909         local expect_count=$(((($max/2)/256) * 256))
27910
27911         log "setting create_count to 100200:"
27912         log " -result- count: $count with max: $max, expecting: $expect_count"
27913
27914         [[ $count -eq expect_count ]] ||
27915                 error "Create count not set to max precreate."
27916 }
27917 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
27918
27919 test_831() {
27920         local sync_changes=$(do_facet $SINGLEMDS \
27921                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
27922
27923         [ "$sync_changes" -gt 100 ] &&
27924                 skip "Sync changes $sync_changes > 100 already"
27925
27926         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27927
27928         $LFS mkdir -i 0 $DIR/$tdir
27929         $LFS setstripe -c 1 -i 0 $DIR/$tdir
27930
27931         save_lustre_params mds1 \
27932                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
27933         save_lustre_params mds1 \
27934                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
27935
27936         do_facet mds1 "$LCTL set_param -n \
27937                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
27938                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
27939         stack_trap "restore_lustre_params < $p" EXIT
27940
27941         createmany -o $DIR/$tdir/f- 1000
27942         unlinkmany $DIR/$tdir/f- 1000 &
27943         local UNLINK_PID=$!
27944
27945         while sleep 1; do
27946                 sync_changes=$(do_facet mds1 \
27947                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
27948                 # the check in the code is racy, fail the test
27949                 # if the value above the limit by 10.
27950                 [ $sync_changes -gt 110 ] && {
27951                         kill -2 $UNLINK_PID
27952                         wait
27953                         error "osp changes throttling failed, $sync_changes>110"
27954                 }
27955                 kill -0 $UNLINK_PID 2> /dev/null || break
27956         done
27957         wait
27958 }
27959 run_test 831 "throttling unlink/setattr queuing on OSP"
27960
27961 #
27962 # tests that do cleanup/setup should be run at the end
27963 #
27964
27965 test_900() {
27966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27967         local ls
27968
27969         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
27970         $LCTL set_param fail_loc=0x903
27971
27972         cancel_lru_locks MGC
27973
27974         FAIL_ON_ERROR=true cleanup
27975         FAIL_ON_ERROR=true setup
27976 }
27977 run_test 900 "umount should not race with any mgc requeue thread"
27978
27979 # LUS-6253/LU-11185
27980 test_901() {
27981         local old
27982         local count
27983         local oldc
27984         local newc
27985         local olds
27986         local news
27987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27988
27989         # some get_param have a bug to handle dot in param name
27990         cancel_lru_locks MGC
27991         old=$(mount -t lustre | wc -l)
27992         # 1 config+sptlrpc
27993         # 2 params
27994         # 3 nodemap
27995         # 4 IR
27996         old=$((old * 4))
27997         oldc=0
27998         count=0
27999         while [ $old -ne $oldc ]; do
28000                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28001                 sleep 1
28002                 ((count++))
28003                 if [ $count -ge $TIMEOUT ]; then
28004                         error "too large timeout"
28005                 fi
28006         done
28007         umount_client $MOUNT || error "umount failed"
28008         mount_client $MOUNT || error "mount failed"
28009         cancel_lru_locks MGC
28010         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28011
28012         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28013
28014         return 0
28015 }
28016 run_test 901 "don't leak a mgc lock on client umount"
28017
28018 # LU-13377
28019 test_902() {
28020         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28021                 skip "client does not have LU-13377 fix"
28022         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28023         $LCTL set_param fail_loc=0x1415
28024         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28025         cancel_lru_locks osc
28026         rm -f $DIR/$tfile
28027 }
28028 run_test 902 "test short write doesn't hang lustre"
28029
28030 # LU-14711
28031 test_903() {
28032         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28033         echo "blah" > $DIR/${tfile}-2
28034         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28035         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28036         $LCTL set_param fail_loc=0x417 fail_val=20
28037
28038         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28039         sleep 1 # To start the destroy
28040         wait_destroy_complete 150 || error "Destroy taking too long"
28041         cat $DIR/$tfile > /dev/null || error "Evicted"
28042 }
28043 run_test 903 "Test long page discard does not cause evictions"
28044
28045 test_904() {
28046         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28047         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28048                 grep -q project || skip "skip project quota not supported"
28049
28050         local testfile="$DIR/$tdir/$tfile"
28051         local xattr="trusted.projid"
28052         local projid
28053
28054         mkdir -p $DIR/$tdir
28055         touch $testfile
28056         #should be hidden when projid is 0
28057         $LFS project -p 0 $testfile ||
28058                 error "set $testfile project id failed"
28059         getfattr -m - $testfile | grep $xattr &&
28060                 error "do not show trusted.projid with project ID 0"
28061
28062         #still can getxattr explicitly
28063         projid=$(getfattr -n $xattr $testfile |
28064                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28065         [ $projid == "0" ] ||
28066                 error "projid expected 0 not $projid"
28067
28068         #set the projid via setxattr
28069         setfattr -n $xattr -v "1000" $testfile ||
28070                 error "setattr failed with $?"
28071         projid=($($LFS project $testfile))
28072         [ ${projid[0]} == "1000" ] ||
28073                 error "projid expected 1000 not $projid"
28074
28075         #check the new projid via getxattr
28076         $LFS project -p 1001 $testfile ||
28077                 error "set $testfile project id failed"
28078         projid=$(getfattr -n $xattr $testfile |
28079                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28080         [ $projid == "1001" ] ||
28081                 error "projid expected 1001 not $projid"
28082
28083         #try to set invalid projid
28084         setfattr -n $xattr -v "4294967295" $testfile &&
28085                 error "set invalid projid should fail"
28086
28087         #remove the xattr means setting projid to 0
28088         setfattr -x $xattr $testfile ||
28089                 error "setfattr failed with $?"
28090         projid=($($LFS project $testfile))
28091         [ ${projid[0]} == "0" ] ||
28092                 error "projid expected 0 not $projid"
28093
28094         #should be hidden when parent has inherit flag and same projid
28095         $LFS project -srp 1002 $DIR/$tdir ||
28096                 error "set $tdir project id failed"
28097         getfattr -m - $testfile | grep $xattr &&
28098                 error "do not show trusted.projid with inherit flag"
28099
28100         #still can getxattr explicitly
28101         projid=$(getfattr -n $xattr $testfile |
28102                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28103         [ $projid == "1002" ] ||
28104                 error "projid expected 1002 not $projid"
28105 }
28106 run_test 904 "virtual project ID xattr"
28107
28108 complete $SECONDS
28109 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28110 check_and_cleanup_lustre
28111 if [ "$I_MOUNTED" != "yes" ]; then
28112         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28113 fi
28114 exit_status