Whamcloud - gitweb
LU-13468 fld: repeat rpc in fld_client_rpc after EAGAIN
[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 run_test 65n "don't inherit default layout from root for new subdirectories"
9397
9398 # bug 2543 - update blocks count on client
9399 test_66() {
9400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9401
9402         COUNT=${COUNT:-8}
9403         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9404         sync; sync_all_data; sync; sync_all_data
9405         cancel_lru_locks osc
9406         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9407         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9408 }
9409 run_test 66 "update inode blocks count on client ==============="
9410
9411 meminfo() {
9412         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9413 }
9414
9415 swap_used() {
9416         swapon -s | awk '($1 == "'$1'") { print $4 }'
9417 }
9418
9419 # bug5265, obdfilter oa2dentry return -ENOENT
9420 # #define OBD_FAIL_SRV_ENOENT 0x217
9421 test_69() {
9422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9423         remote_ost_nodsh && skip "remote OST with nodsh"
9424
9425         f="$DIR/$tfile"
9426         $LFS setstripe -c 1 -i 0 $f
9427
9428         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9429
9430         do_facet ost1 lctl set_param fail_loc=0x217
9431         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9432         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9433
9434         do_facet ost1 lctl set_param fail_loc=0
9435         $DIRECTIO write $f 0 2 || error "write error"
9436
9437         cancel_lru_locks osc
9438         $DIRECTIO read $f 0 1 || error "read error"
9439
9440         do_facet ost1 lctl set_param fail_loc=0x217
9441         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9442
9443         do_facet ost1 lctl set_param fail_loc=0
9444         rm -f $f
9445 }
9446 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9447
9448 test_71() {
9449         test_mkdir $DIR/$tdir
9450         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9451         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9452 }
9453 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9454
9455 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9457         [ "$RUNAS_ID" = "$UID" ] &&
9458                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9459         # Check that testing environment is properly set up. Skip if not
9460         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9461                 skip_env "User $RUNAS_ID does not exist - skipping"
9462
9463         touch $DIR/$tfile
9464         chmod 777 $DIR/$tfile
9465         chmod ug+s $DIR/$tfile
9466         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9467                 error "$RUNAS dd $DIR/$tfile failed"
9468         # See if we are still setuid/sgid
9469         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9470                 error "S/gid is not dropped on write"
9471         # Now test that MDS is updated too
9472         cancel_lru_locks mdc
9473         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9474                 error "S/gid is not dropped on MDS"
9475         rm -f $DIR/$tfile
9476 }
9477 run_test 72a "Test that remove suid works properly (bug5695) ===="
9478
9479 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9480         local perm
9481
9482         [ "$RUNAS_ID" = "$UID" ] &&
9483                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9484         [ "$RUNAS_ID" -eq 0 ] &&
9485                 skip_env "RUNAS_ID = 0 -- skipping"
9486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9487         # Check that testing environment is properly set up. Skip if not
9488         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9489                 skip_env "User $RUNAS_ID does not exist - skipping"
9490
9491         touch $DIR/${tfile}-f{g,u}
9492         test_mkdir $DIR/${tfile}-dg
9493         test_mkdir $DIR/${tfile}-du
9494         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9495         chmod g+s $DIR/${tfile}-{f,d}g
9496         chmod u+s $DIR/${tfile}-{f,d}u
9497         for perm in 777 2777 4777; do
9498                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9499                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9500                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9501                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9502         done
9503         true
9504 }
9505 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9506
9507 # bug 3462 - multiple simultaneous MDC requests
9508 test_73() {
9509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9510
9511         test_mkdir $DIR/d73-1
9512         test_mkdir $DIR/d73-2
9513         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9514         pid1=$!
9515
9516         lctl set_param fail_loc=0x80000129
9517         $MULTIOP $DIR/d73-1/f73-2 Oc &
9518         sleep 1
9519         lctl set_param fail_loc=0
9520
9521         $MULTIOP $DIR/d73-2/f73-3 Oc &
9522         pid3=$!
9523
9524         kill -USR1 $pid1
9525         wait $pid1 || return 1
9526
9527         sleep 25
9528
9529         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9530         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9531         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9532
9533         rm -rf $DIR/d73-*
9534 }
9535 run_test 73 "multiple MDC requests (should not deadlock)"
9536
9537 test_74a() { # bug 6149, 6184
9538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9539
9540         touch $DIR/f74a
9541         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9542         #
9543         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9544         # will spin in a tight reconnection loop
9545         $LCTL set_param fail_loc=0x8000030e
9546         # get any lock that won't be difficult - lookup works.
9547         ls $DIR/f74a
9548         $LCTL set_param fail_loc=0
9549         rm -f $DIR/f74a
9550         true
9551 }
9552 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9553
9554 test_74b() { # bug 13310
9555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9556
9557         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9558         #
9559         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9560         # will spin in a tight reconnection loop
9561         $LCTL set_param fail_loc=0x8000030e
9562         # get a "difficult" lock
9563         touch $DIR/f74b
9564         $LCTL set_param fail_loc=0
9565         rm -f $DIR/f74b
9566         true
9567 }
9568 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9569
9570 test_74c() {
9571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9572
9573         #define OBD_FAIL_LDLM_NEW_LOCK
9574         $LCTL set_param fail_loc=0x319
9575         touch $DIR/$tfile && error "touch successful"
9576         $LCTL set_param fail_loc=0
9577         true
9578 }
9579 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9580
9581 slab_lic=/sys/kernel/slab/lustre_inode_cache
9582 num_objects() {
9583         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9584         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9585                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9586 }
9587
9588 test_76a() { # Now for b=20433, added originally in b=1443
9589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9590
9591         cancel_lru_locks osc
9592         # there may be some slab objects cached per core
9593         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9594         local before=$(num_objects)
9595         local count=$((512 * cpus))
9596         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9597         local margin=$((count / 10))
9598         if [[ -f $slab_lic/aliases ]]; then
9599                 local aliases=$(cat $slab_lic/aliases)
9600                 (( aliases > 0 )) && margin=$((margin * aliases))
9601         fi
9602
9603         echo "before slab objects: $before"
9604         for i in $(seq $count); do
9605                 touch $DIR/$tfile
9606                 rm -f $DIR/$tfile
9607         done
9608         cancel_lru_locks osc
9609         local after=$(num_objects)
9610         echo "created: $count, after slab objects: $after"
9611         # shared slab counts are not very accurate, allow significant margin
9612         # the main goal is that the cache growth is not permanently > $count
9613         while (( after > before + margin )); do
9614                 sleep 1
9615                 after=$(num_objects)
9616                 wait=$((wait + 1))
9617                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9618                 if (( wait > 60 )); then
9619                         error "inode slab grew from $before+$margin to $after"
9620                 fi
9621         done
9622 }
9623 run_test 76a "confirm clients recycle inodes properly ===="
9624
9625 test_76b() {
9626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9627         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9628
9629         local count=512
9630         local before=$(num_objects)
9631
9632         for i in $(seq $count); do
9633                 mkdir $DIR/$tdir
9634                 rmdir $DIR/$tdir
9635         done
9636
9637         local after=$(num_objects)
9638         local wait=0
9639
9640         while (( after > before )); do
9641                 sleep 1
9642                 after=$(num_objects)
9643                 wait=$((wait + 1))
9644                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9645                 if (( wait > 60 )); then
9646                         error "inode slab grew from $before to $after"
9647                 fi
9648         done
9649
9650         echo "slab objects before: $before, after: $after"
9651 }
9652 run_test 76b "confirm clients recycle directory inodes properly ===="
9653
9654 export ORIG_CSUM=""
9655 set_checksums()
9656 {
9657         # Note: in sptlrpc modes which enable its own bulk checksum, the
9658         # original crc32_le bulk checksum will be automatically disabled,
9659         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9660         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9661         # In this case set_checksums() will not be no-op, because sptlrpc
9662         # bulk checksum will be enabled all through the test.
9663
9664         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9665         lctl set_param -n osc.*.checksums $1
9666         return 0
9667 }
9668
9669 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9670                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9671 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9672                              tr -d [] | head -n1)}
9673 set_checksum_type()
9674 {
9675         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9676         rc=$?
9677         log "set checksum type to $1, rc = $rc"
9678         return $rc
9679 }
9680
9681 get_osc_checksum_type()
9682 {
9683         # arugment 1: OST name, like OST0000
9684         ost=$1
9685         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9686                         sed 's/.*\[\(.*\)\].*/\1/g')
9687         rc=$?
9688         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9689         echo $checksum_type
9690 }
9691
9692 F77_TMP=$TMP/f77-temp
9693 F77SZ=8
9694 setup_f77() {
9695         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9696                 error "error writing to $F77_TMP"
9697 }
9698
9699 test_77a() { # bug 10889
9700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9701         $GSS && skip_env "could not run with gss"
9702
9703         [ ! -f $F77_TMP ] && setup_f77
9704         set_checksums 1
9705         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9706         set_checksums 0
9707         rm -f $DIR/$tfile
9708 }
9709 run_test 77a "normal checksum read/write operation"
9710
9711 test_77b() { # bug 10889
9712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9713         $GSS && skip_env "could not run with gss"
9714
9715         [ ! -f $F77_TMP ] && setup_f77
9716         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9717         $LCTL set_param fail_loc=0x80000409
9718         set_checksums 1
9719
9720         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9721                 error "dd error: $?"
9722         $LCTL set_param fail_loc=0
9723
9724         for algo in $CKSUM_TYPES; do
9725                 cancel_lru_locks osc
9726                 set_checksum_type $algo
9727                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9728                 $LCTL set_param fail_loc=0x80000408
9729                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9730                 $LCTL set_param fail_loc=0
9731         done
9732         set_checksums 0
9733         set_checksum_type $ORIG_CSUM_TYPE
9734         rm -f $DIR/$tfile
9735 }
9736 run_test 77b "checksum error on client write, read"
9737
9738 cleanup_77c() {
9739         trap 0
9740         set_checksums 0
9741         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9742         $check_ost &&
9743                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9744         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9745         $check_ost && [ -n "$ost_file_prefix" ] &&
9746                 do_facet ost1 rm -f ${ost_file_prefix}\*
9747 }
9748
9749 test_77c() {
9750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9751         $GSS && skip_env "could not run with gss"
9752         remote_ost_nodsh && skip "remote OST with nodsh"
9753
9754         local bad1
9755         local osc_file_prefix
9756         local osc_file
9757         local check_ost=false
9758         local ost_file_prefix
9759         local ost_file
9760         local orig_cksum
9761         local dump_cksum
9762         local fid
9763
9764         # ensure corruption will occur on first OSS/OST
9765         $LFS setstripe -i 0 $DIR/$tfile
9766
9767         [ ! -f $F77_TMP ] && setup_f77
9768         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9769                 error "dd write error: $?"
9770         fid=$($LFS path2fid $DIR/$tfile)
9771
9772         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9773         then
9774                 check_ost=true
9775                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9776                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9777         else
9778                 echo "OSS do not support bulk pages dump upon error"
9779         fi
9780
9781         osc_file_prefix=$($LCTL get_param -n debug_path)
9782         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9783
9784         trap cleanup_77c EXIT
9785
9786         set_checksums 1
9787         # enable bulk pages dump upon error on Client
9788         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9789         # enable bulk pages dump upon error on OSS
9790         $check_ost &&
9791                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9792
9793         # flush Client cache to allow next read to reach OSS
9794         cancel_lru_locks osc
9795
9796         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9797         $LCTL set_param fail_loc=0x80000408
9798         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9799         $LCTL set_param fail_loc=0
9800
9801         rm -f $DIR/$tfile
9802
9803         # check cksum dump on Client
9804         osc_file=$(ls ${osc_file_prefix}*)
9805         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9806         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9807         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9808         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9809         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9810                      cksum)
9811         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9812         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9813                 error "dump content does not match on Client"
9814
9815         $check_ost || skip "No need to check cksum dump on OSS"
9816
9817         # check cksum dump on OSS
9818         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9819         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9820         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9821         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9822         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9823                 error "dump content does not match on OSS"
9824
9825         cleanup_77c
9826 }
9827 run_test 77c "checksum error on client read with debug"
9828
9829 test_77d() { # bug 10889
9830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9831         $GSS && skip_env "could not run with gss"
9832
9833         stack_trap "rm -f $DIR/$tfile"
9834         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9835         $LCTL set_param fail_loc=0x80000409
9836         set_checksums 1
9837         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9838                 error "direct write: rc=$?"
9839         $LCTL set_param fail_loc=0
9840         set_checksums 0
9841
9842         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9843         $LCTL set_param fail_loc=0x80000408
9844         set_checksums 1
9845         cancel_lru_locks osc
9846         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9847                 error "direct read: rc=$?"
9848         $LCTL set_param fail_loc=0
9849         set_checksums 0
9850 }
9851 run_test 77d "checksum error on OST direct write, read"
9852
9853 test_77f() { # bug 10889
9854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9855         $GSS && skip_env "could not run with gss"
9856
9857         set_checksums 1
9858         stack_trap "rm -f $DIR/$tfile"
9859         for algo in $CKSUM_TYPES; do
9860                 cancel_lru_locks osc
9861                 set_checksum_type $algo
9862                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9863                 $LCTL set_param fail_loc=0x409
9864                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9865                         error "direct write succeeded"
9866                 $LCTL set_param fail_loc=0
9867         done
9868         set_checksum_type $ORIG_CSUM_TYPE
9869         set_checksums 0
9870 }
9871 run_test 77f "repeat checksum error on write (expect error)"
9872
9873 test_77g() { # bug 10889
9874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9875         $GSS && skip_env "could not run with gss"
9876         remote_ost_nodsh && skip "remote OST with nodsh"
9877
9878         [ ! -f $F77_TMP ] && setup_f77
9879
9880         local file=$DIR/$tfile
9881         stack_trap "rm -f $file" EXIT
9882
9883         $LFS setstripe -c 1 -i 0 $file
9884         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9885         do_facet ost1 lctl set_param fail_loc=0x8000021a
9886         set_checksums 1
9887         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9888                 error "write error: rc=$?"
9889         do_facet ost1 lctl set_param fail_loc=0
9890         set_checksums 0
9891
9892         cancel_lru_locks osc
9893         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9894         do_facet ost1 lctl set_param fail_loc=0x8000021b
9895         set_checksums 1
9896         cmp $F77_TMP $file || error "file compare failed"
9897         do_facet ost1 lctl set_param fail_loc=0
9898         set_checksums 0
9899 }
9900 run_test 77g "checksum error on OST write, read"
9901
9902 test_77k() { # LU-10906
9903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9904         $GSS && skip_env "could not run with gss"
9905
9906         local cksum_param="osc.$FSNAME*.checksums"
9907         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9908         local checksum
9909         local i
9910
9911         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9912         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9913         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9914
9915         for i in 0 1; do
9916                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9917                         error "failed to set checksum=$i on MGS"
9918                 wait_update $HOSTNAME "$get_checksum" $i
9919                 #remount
9920                 echo "remount client, checksum should be $i"
9921                 remount_client $MOUNT || error "failed to remount client"
9922                 checksum=$(eval $get_checksum)
9923                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9924         done
9925         # remove persistent param to avoid races with checksum mountopt below
9926         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9927                 error "failed to delete checksum on MGS"
9928
9929         for opt in "checksum" "nochecksum"; do
9930                 #remount with mount option
9931                 echo "remount client with option $opt, checksum should be $i"
9932                 umount_client $MOUNT || error "failed to umount client"
9933                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9934                         error "failed to mount client with option '$opt'"
9935                 checksum=$(eval $get_checksum)
9936                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9937                 i=$((i - 1))
9938         done
9939
9940         remount_client $MOUNT || error "failed to remount client"
9941 }
9942 run_test 77k "enable/disable checksum correctly"
9943
9944 test_77l() {
9945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9946         $GSS && skip_env "could not run with gss"
9947
9948         set_checksums 1
9949         stack_trap "set_checksums $ORIG_CSUM" EXIT
9950         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9951
9952         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9953
9954         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9955         for algo in $CKSUM_TYPES; do
9956                 set_checksum_type $algo || error "fail to set checksum type $algo"
9957                 osc_algo=$(get_osc_checksum_type OST0000)
9958                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9959
9960                 # no locks, no reqs to let the connection idle
9961                 cancel_lru_locks osc
9962                 lru_resize_disable osc
9963                 wait_osc_import_state client ost1 IDLE
9964
9965                 # ensure ost1 is connected
9966                 stat $DIR/$tfile >/dev/null || error "can't stat"
9967                 wait_osc_import_state client ost1 FULL
9968
9969                 osc_algo=$(get_osc_checksum_type OST0000)
9970                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9971         done
9972         return 0
9973 }
9974 run_test 77l "preferred checksum type is remembered after reconnected"
9975
9976 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9977 rm -f $F77_TMP
9978 unset F77_TMP
9979
9980 test_77m() {
9981         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
9982                 skip "Need at least version 2.14.52"
9983         local param=checksum_speed
9984
9985         $LCTL get_param $param || error "reading $param failed"
9986
9987         csum_speeds=$($LCTL get_param -n $param)
9988
9989         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
9990                 error "known checksum types are missing"
9991 }
9992 run_test 77m "Verify checksum_speed is correctly read"
9993
9994 check_filefrag_77n() {
9995         local nr_ext=0
9996         local starts=()
9997         local ends=()
9998
9999         while read extidx a b start end rest; do
10000                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10001                         nr_ext=$(( $nr_ext + 1 ))
10002                         starts+=( ${start%..} )
10003                         ends+=( ${end%:} )
10004                 fi
10005         done < <( filefrag -sv $1 )
10006
10007         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10008         return 1
10009 }
10010
10011 test_77n() {
10012         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10013
10014         touch $DIR/$tfile
10015         $TRUNCATE $DIR/$tfile 0
10016         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10017         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10018         check_filefrag_77n $DIR/$tfile ||
10019                 skip "$tfile blocks not contiguous around hole"
10020
10021         set_checksums 1
10022         stack_trap "set_checksums $ORIG_CSUM" EXIT
10023         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10024         stack_trap "rm -f $DIR/$tfile"
10025
10026         for algo in $CKSUM_TYPES; do
10027                 if [[ "$algo" =~ ^t10 ]]; then
10028                         set_checksum_type $algo ||
10029                                 error "fail to set checksum type $algo"
10030                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10031                                 error "fail to read $tfile with $algo"
10032                 fi
10033         done
10034         rm -f $DIR/$tfile
10035         return 0
10036 }
10037 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10038
10039 test_77o() {
10040         (( $CLIENT_VERSION >= $(version_code 2.14.54) )) ||
10041                 skip "Need at least version 2.14.54"
10042         local ofd=obdfilter
10043         local mdt=mdt
10044
10045         # print OST checksum_type
10046         echo "$ofd.$FSNAME-*.checksum_type:"
10047         do_nodes $(comma_list $(osts_nodes)) \
10048                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10049
10050         # print MDT checksum_type
10051         echo "$mdt.$FSNAME-*.checksum_type:"
10052         do_nodes $(comma_list $(mdts_nodes)) \
10053                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10054
10055         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10056                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10057
10058         (( $o_count == $OSTCOUNT )) ||
10059                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10060
10061         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10062                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10063
10064         (( $m_count == $MDSCOUNT )) ||
10065                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10066 }
10067 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10068
10069 cleanup_test_78() {
10070         trap 0
10071         rm -f $DIR/$tfile
10072 }
10073
10074 test_78() { # bug 10901
10075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10076         remote_ost || skip_env "local OST"
10077
10078         NSEQ=5
10079         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10080         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10081         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10082         echo "MemTotal: $MEMTOTAL"
10083
10084         # reserve 256MB of memory for the kernel and other running processes,
10085         # and then take 1/2 of the remaining memory for the read/write buffers.
10086         if [ $MEMTOTAL -gt 512 ] ;then
10087                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10088         else
10089                 # for those poor memory-starved high-end clusters...
10090                 MEMTOTAL=$((MEMTOTAL / 2))
10091         fi
10092         echo "Mem to use for directio: $MEMTOTAL"
10093
10094         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10095         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10096         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10097         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10098                 head -n1)
10099         echo "Smallest OST: $SMALLESTOST"
10100         [[ $SMALLESTOST -lt 10240 ]] &&
10101                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10102
10103         trap cleanup_test_78 EXIT
10104
10105         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10106                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10107
10108         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10109         echo "File size: $F78SIZE"
10110         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10111         for i in $(seq 1 $NSEQ); do
10112                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10113                 echo directIO rdwr round $i of $NSEQ
10114                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10115         done
10116
10117         cleanup_test_78
10118 }
10119 run_test 78 "handle large O_DIRECT writes correctly ============"
10120
10121 test_79() { # bug 12743
10122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10123
10124         wait_delete_completed
10125
10126         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10127         BKFREE=$(calc_osc_kbytes kbytesfree)
10128         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10129
10130         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10131         DFTOTAL=`echo $STRING | cut -d, -f1`
10132         DFUSED=`echo $STRING  | cut -d, -f2`
10133         DFAVAIL=`echo $STRING | cut -d, -f3`
10134         DFFREE=$(($DFTOTAL - $DFUSED))
10135
10136         ALLOWANCE=$((64 * $OSTCOUNT))
10137
10138         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10139            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10140                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10141         fi
10142         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10143            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10144                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10145         fi
10146         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10147            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10148                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10149         fi
10150 }
10151 run_test 79 "df report consistency check ======================="
10152
10153 test_80() { # bug 10718
10154         remote_ost_nodsh && skip "remote OST with nodsh"
10155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10156
10157         # relax strong synchronous semantics for slow backends like ZFS
10158         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10159                 local soc="obdfilter.*.sync_lock_cancel"
10160                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10161
10162                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10163                 if [ -z "$save" ]; then
10164                         soc="obdfilter.*.sync_on_lock_cancel"
10165                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10166                 fi
10167
10168                 if [ "$save" != "never" ]; then
10169                         local hosts=$(comma_list $(osts_nodes))
10170
10171                         do_nodes $hosts $LCTL set_param $soc=never
10172                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10173                 fi
10174         fi
10175
10176         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10177         sync; sleep 1; sync
10178         local before=$(date +%s)
10179         cancel_lru_locks osc
10180         local after=$(date +%s)
10181         local diff=$((after - before))
10182         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10183
10184         rm -f $DIR/$tfile
10185 }
10186 run_test 80 "Page eviction is equally fast at high offsets too"
10187
10188 test_81a() { # LU-456
10189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10190         remote_ost_nodsh && skip "remote OST with nodsh"
10191
10192         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10193         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10194         do_facet ost1 lctl set_param fail_loc=0x80000228
10195
10196         # write should trigger a retry and success
10197         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10198         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10199         RC=$?
10200         if [ $RC -ne 0 ] ; then
10201                 error "write should success, but failed for $RC"
10202         fi
10203 }
10204 run_test 81a "OST should retry write when get -ENOSPC ==============="
10205
10206 test_81b() { # LU-456
10207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10208         remote_ost_nodsh && skip "remote OST with nodsh"
10209
10210         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10211         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10212         do_facet ost1 lctl set_param fail_loc=0x228
10213
10214         # write should retry several times and return -ENOSPC finally
10215         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10216         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10217         RC=$?
10218         ENOSPC=28
10219         if [ $RC -ne $ENOSPC ] ; then
10220                 error "dd should fail for -ENOSPC, but succeed."
10221         fi
10222 }
10223 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10224
10225 test_99() {
10226         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10227
10228         test_mkdir $DIR/$tdir.cvsroot
10229         chown $RUNAS_ID $DIR/$tdir.cvsroot
10230
10231         cd $TMP
10232         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10233
10234         cd /etc/init.d
10235         # some versions of cvs import exit(1) when asked to import links or
10236         # files they can't read.  ignore those files.
10237         local toignore=$(find . -type l -printf '-I %f\n' -o \
10238                          ! -perm /4 -printf '-I %f\n')
10239         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10240                 $tdir.reposname vtag rtag
10241
10242         cd $DIR
10243         test_mkdir $DIR/$tdir.reposname
10244         chown $RUNAS_ID $DIR/$tdir.reposname
10245         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10246
10247         cd $DIR/$tdir.reposname
10248         $RUNAS touch foo99
10249         $RUNAS cvs add -m 'addmsg' foo99
10250         $RUNAS cvs update
10251         $RUNAS cvs commit -m 'nomsg' foo99
10252         rm -fr $DIR/$tdir.cvsroot
10253 }
10254 run_test 99 "cvs strange file/directory operations"
10255
10256 test_100() {
10257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10258         [[ "$NETTYPE" =~ tcp ]] ||
10259                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10260         remote_ost_nodsh && skip "remote OST with nodsh"
10261         remote_mds_nodsh && skip "remote MDS with nodsh"
10262         remote_servers ||
10263                 skip "useless for local single node setup"
10264
10265         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10266                 [ "$PROT" != "tcp" ] && continue
10267                 RPORT=$(echo $REMOTE | cut -d: -f2)
10268                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10269
10270                 rc=0
10271                 LPORT=`echo $LOCAL | cut -d: -f2`
10272                 if [ $LPORT -ge 1024 ]; then
10273                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10274                         netstat -tna
10275                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10276                 fi
10277         done
10278         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10279 }
10280 run_test 100 "check local port using privileged port ==========="
10281
10282 function get_named_value()
10283 {
10284     local tag=$1
10285
10286     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10287 }
10288
10289 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10290                    awk '/^max_cached_mb/ { print $2 }')
10291
10292 cleanup_101a() {
10293         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10294         trap 0
10295 }
10296
10297 test_101a() {
10298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10299
10300         local s
10301         local discard
10302         local nreads=10000
10303         local cache_limit=32
10304
10305         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10306         trap cleanup_101a EXIT
10307         $LCTL set_param -n llite.*.read_ahead_stats=0
10308         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10309
10310         #
10311         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10312         #
10313         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10314         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10315
10316         discard=0
10317         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10318                    get_named_value 'read.but.discarded'); do
10319                         discard=$(($discard + $s))
10320         done
10321         cleanup_101a
10322
10323         $LCTL get_param osc.*-osc*.rpc_stats
10324         $LCTL get_param llite.*.read_ahead_stats
10325
10326         # Discard is generally zero, but sometimes a few random reads line up
10327         # and trigger larger readahead, which is wasted & leads to discards.
10328         if [[ $(($discard)) -gt $nreads ]]; then
10329                 error "too many ($discard) discarded pages"
10330         fi
10331         rm -f $DIR/$tfile || true
10332 }
10333 run_test 101a "check read-ahead for random reads"
10334
10335 setup_test101bc() {
10336         test_mkdir $DIR/$tdir
10337         local ssize=$1
10338         local FILE_LENGTH=$2
10339         STRIPE_OFFSET=0
10340
10341         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10342
10343         local list=$(comma_list $(osts_nodes))
10344         set_osd_param $list '' read_cache_enable 0
10345         set_osd_param $list '' writethrough_cache_enable 0
10346
10347         trap cleanup_test101bc EXIT
10348         # prepare the read-ahead file
10349         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10350
10351         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10352                                 count=$FILE_SIZE_MB 2> /dev/null
10353
10354 }
10355
10356 cleanup_test101bc() {
10357         trap 0
10358         rm -rf $DIR/$tdir
10359         rm -f $DIR/$tfile
10360
10361         local list=$(comma_list $(osts_nodes))
10362         set_osd_param $list '' read_cache_enable 1
10363         set_osd_param $list '' writethrough_cache_enable 1
10364 }
10365
10366 calc_total() {
10367         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10368 }
10369
10370 ra_check_101() {
10371         local READ_SIZE=$1
10372         local STRIPE_SIZE=$2
10373         local FILE_LENGTH=$3
10374         local RA_INC=1048576
10375         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
10376         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
10377                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
10378         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
10379                   get_named_value 'read.but.discarded' | calc_total)
10380         if [[ $DISCARD -gt $discard_limit ]]; then
10381                 $LCTL get_param llite.*.read_ahead_stats
10382                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
10383         else
10384                 echo "Read-ahead success for size ${READ_SIZE}"
10385         fi
10386 }
10387
10388 test_101b() {
10389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10390         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10391
10392         local STRIPE_SIZE=1048576
10393         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10394
10395         if [ $SLOW == "yes" ]; then
10396                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10397         else
10398                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10399         fi
10400
10401         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10402
10403         # prepare the read-ahead file
10404         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10405         cancel_lru_locks osc
10406         for BIDX in 2 4 8 16 32 64 128 256
10407         do
10408                 local BSIZE=$((BIDX*4096))
10409                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10410                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10411                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10412                 $LCTL set_param -n llite.*.read_ahead_stats=0
10413                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10414                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10415                 cancel_lru_locks osc
10416                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10417         done
10418         cleanup_test101bc
10419         true
10420 }
10421 run_test 101b "check stride-io mode read-ahead ================="
10422
10423 test_101c() {
10424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10425
10426         local STRIPE_SIZE=1048576
10427         local FILE_LENGTH=$((STRIPE_SIZE*100))
10428         local nreads=10000
10429         local rsize=65536
10430         local osc_rpc_stats
10431
10432         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10433
10434         cancel_lru_locks osc
10435         $LCTL set_param osc.*.rpc_stats=0
10436         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10437         $LCTL get_param osc.*.rpc_stats
10438         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10439                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10440                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10441                 local size
10442
10443                 if [ $lines -le 20 ]; then
10444                         echo "continue debug"
10445                         continue
10446                 fi
10447                 for size in 1 2 4 8; do
10448                         local rpc=$(echo "$stats" |
10449                                     awk '($1 == "'$size':") {print $2; exit; }')
10450                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10451                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10452                 done
10453                 echo "$osc_rpc_stats check passed!"
10454         done
10455         cleanup_test101bc
10456         true
10457 }
10458 run_test 101c "check stripe_size aligned read-ahead"
10459
10460 test_101d() {
10461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10462
10463         local file=$DIR/$tfile
10464         local sz_MB=${FILESIZE_101d:-80}
10465         local ra_MB=${READAHEAD_MB:-40}
10466
10467         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10468         [ $free_MB -lt $sz_MB ] &&
10469                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10470
10471         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10472         $LFS setstripe -c -1 $file || error "setstripe failed"
10473
10474         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10475         echo Cancel LRU locks on lustre client to flush the client cache
10476         cancel_lru_locks osc
10477
10478         echo Disable read-ahead
10479         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10480         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10481         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10482         $LCTL get_param -n llite.*.max_read_ahead_mb
10483
10484         echo "Reading the test file $file with read-ahead disabled"
10485         local sz_KB=$((sz_MB * 1024 / 4))
10486         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10487         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10488         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10489                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10490
10491         echo "Cancel LRU locks on lustre client to flush the client cache"
10492         cancel_lru_locks osc
10493         echo Enable read-ahead with ${ra_MB}MB
10494         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10495
10496         echo "Reading the test file $file with read-ahead enabled"
10497         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10498                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10499
10500         echo "read-ahead disabled time read $raOFF"
10501         echo "read-ahead enabled time read $raON"
10502
10503         rm -f $file
10504         wait_delete_completed
10505
10506         # use awk for this check instead of bash because it handles decimals
10507         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10508                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10509 }
10510 run_test 101d "file read with and without read-ahead enabled"
10511
10512 test_101e() {
10513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10514
10515         local file=$DIR/$tfile
10516         local size_KB=500  #KB
10517         local count=100
10518         local bsize=1024
10519
10520         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10521         local need_KB=$((count * size_KB))
10522         [[ $free_KB -le $need_KB ]] &&
10523                 skip_env "Need free space $need_KB, have $free_KB"
10524
10525         echo "Creating $count ${size_KB}K test files"
10526         for ((i = 0; i < $count; i++)); do
10527                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10528         done
10529
10530         echo "Cancel LRU locks on lustre client to flush the client cache"
10531         cancel_lru_locks $OSC
10532
10533         echo "Reset readahead stats"
10534         $LCTL set_param -n llite.*.read_ahead_stats=0
10535
10536         for ((i = 0; i < $count; i++)); do
10537                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10538         done
10539
10540         $LCTL get_param llite.*.max_cached_mb
10541         $LCTL get_param llite.*.read_ahead_stats
10542         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10543                      get_named_value 'misses' | calc_total)
10544
10545         for ((i = 0; i < $count; i++)); do
10546                 rm -rf $file.$i 2>/dev/null
10547         done
10548
10549         #10000 means 20% reads are missing in readahead
10550         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10551 }
10552 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10553
10554 test_101f() {
10555         which iozone || skip_env "no iozone installed"
10556
10557         local old_debug=$($LCTL get_param debug)
10558         old_debug=${old_debug#*=}
10559         $LCTL set_param debug="reada mmap"
10560
10561         # create a test file
10562         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10563
10564         echo Cancel LRU locks on lustre client to flush the client cache
10565         cancel_lru_locks osc
10566
10567         echo Reset readahead stats
10568         $LCTL set_param -n llite.*.read_ahead_stats=0
10569
10570         echo mmap read the file with small block size
10571         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10572                 > /dev/null 2>&1
10573
10574         echo checking missing pages
10575         $LCTL get_param llite.*.read_ahead_stats
10576         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10577                         get_named_value 'misses' | calc_total)
10578
10579         $LCTL set_param debug="$old_debug"
10580         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10581         rm -f $DIR/$tfile
10582 }
10583 run_test 101f "check mmap read performance"
10584
10585 test_101g_brw_size_test() {
10586         local mb=$1
10587         local pages=$((mb * 1048576 / PAGE_SIZE))
10588         local file=$DIR/$tfile
10589
10590         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10591                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10592         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10593                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10594                         return 2
10595         done
10596
10597         stack_trap "rm -f $file" EXIT
10598         $LCTL set_param -n osc.*.rpc_stats=0
10599
10600         # 10 RPCs should be enough for the test
10601         local count=10
10602         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10603                 { error "dd write ${mb} MB blocks failed"; return 3; }
10604         cancel_lru_locks osc
10605         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10606                 { error "dd write ${mb} MB blocks failed"; return 4; }
10607
10608         # calculate number of full-sized read and write RPCs
10609         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10610                 sed -n '/pages per rpc/,/^$/p' |
10611                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10612                 END { print reads,writes }'))
10613         # allow one extra full-sized read RPC for async readahead
10614         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10615                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10616         [[ ${rpcs[1]} == $count ]] ||
10617                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10618 }
10619
10620 test_101g() {
10621         remote_ost_nodsh && skip "remote OST with nodsh"
10622
10623         local rpcs
10624         local osts=$(get_facets OST)
10625         local list=$(comma_list $(osts_nodes))
10626         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10627         local brw_size="obdfilter.*.brw_size"
10628
10629         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10630
10631         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10632
10633         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10634                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10635                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10636            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10637                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10638                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10639
10640                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10641                         suffix="M"
10642
10643                 if [[ $orig_mb -lt 16 ]]; then
10644                         save_lustre_params $osts "$brw_size" > $p
10645                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10646                                 error "set 16MB RPC size failed"
10647
10648                         echo "remount client to enable new RPC size"
10649                         remount_client $MOUNT || error "remount_client failed"
10650                 fi
10651
10652                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10653                 # should be able to set brw_size=12, but no rpc_stats for that
10654                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10655         fi
10656
10657         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10658
10659         if [[ $orig_mb -lt 16 ]]; then
10660                 restore_lustre_params < $p
10661                 remount_client $MOUNT || error "remount_client restore failed"
10662         fi
10663
10664         rm -f $p $DIR/$tfile
10665 }
10666 run_test 101g "Big bulk(4/16 MiB) readahead"
10667
10668 test_101h() {
10669         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10670
10671         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10672                 error "dd 70M file failed"
10673         echo Cancel LRU locks on lustre client to flush the client cache
10674         cancel_lru_locks osc
10675
10676         echo "Reset readahead stats"
10677         $LCTL set_param -n llite.*.read_ahead_stats 0
10678
10679         echo "Read 10M of data but cross 64M bundary"
10680         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10681         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10682                      get_named_value 'misses' | calc_total)
10683         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10684         rm -f $p $DIR/$tfile
10685 }
10686 run_test 101h "Readahead should cover current read window"
10687
10688 test_101i() {
10689         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10690                 error "dd 10M file failed"
10691
10692         local max_per_file_mb=$($LCTL get_param -n \
10693                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10694         cancel_lru_locks osc
10695         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10696         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10697                 error "set max_read_ahead_per_file_mb to 1 failed"
10698
10699         echo "Reset readahead stats"
10700         $LCTL set_param llite.*.read_ahead_stats=0
10701
10702         dd if=$DIR/$tfile of=/dev/null bs=2M
10703
10704         $LCTL get_param llite.*.read_ahead_stats
10705         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10706                      awk '/misses/ { print $2 }')
10707         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10708         rm -f $DIR/$tfile
10709 }
10710 run_test 101i "allow current readahead to exceed reservation"
10711
10712 test_101j() {
10713         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10714                 error "setstripe $DIR/$tfile failed"
10715         local file_size=$((1048576 * 16))
10716         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10717         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10718
10719         echo Disable read-ahead
10720         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10721
10722         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10723         for blk in $PAGE_SIZE 1048576 $file_size; do
10724                 cancel_lru_locks osc
10725                 echo "Reset readahead stats"
10726                 $LCTL set_param -n llite.*.read_ahead_stats=0
10727                 local count=$(($file_size / $blk))
10728                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10729                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10730                              get_named_value 'failed.to.fast.read' | calc_total)
10731                 $LCTL get_param -n llite.*.read_ahead_stats
10732                 [ $miss -eq $count ] || error "expected $count got $miss"
10733         done
10734
10735         rm -f $p $DIR/$tfile
10736 }
10737 run_test 101j "A complete read block should be submitted when no RA"
10738
10739 setup_test102() {
10740         test_mkdir $DIR/$tdir
10741         chown $RUNAS_ID $DIR/$tdir
10742         STRIPE_SIZE=65536
10743         STRIPE_OFFSET=1
10744         STRIPE_COUNT=$OSTCOUNT
10745         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10746
10747         trap cleanup_test102 EXIT
10748         cd $DIR
10749         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10750         cd $DIR/$tdir
10751         for num in 1 2 3 4; do
10752                 for count in $(seq 1 $STRIPE_COUNT); do
10753                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10754                                 local size=`expr $STRIPE_SIZE \* $num`
10755                                 local file=file"$num-$idx-$count"
10756                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10757                         done
10758                 done
10759         done
10760
10761         cd $DIR
10762         $1 tar cf $TMP/f102.tar $tdir --xattrs
10763 }
10764
10765 cleanup_test102() {
10766         trap 0
10767         rm -f $TMP/f102.tar
10768         rm -rf $DIR/d0.sanity/d102
10769 }
10770
10771 test_102a() {
10772         [ "$UID" != 0 ] && skip "must run as root"
10773         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10774                 skip_env "must have user_xattr"
10775
10776         [ -z "$(which setfattr 2>/dev/null)" ] &&
10777                 skip_env "could not find setfattr"
10778
10779         local testfile=$DIR/$tfile
10780
10781         touch $testfile
10782         echo "set/get xattr..."
10783         setfattr -n trusted.name1 -v value1 $testfile ||
10784                 error "setfattr -n trusted.name1=value1 $testfile failed"
10785         getfattr -n trusted.name1 $testfile 2> /dev/null |
10786           grep "trusted.name1=.value1" ||
10787                 error "$testfile missing trusted.name1=value1"
10788
10789         setfattr -n user.author1 -v author1 $testfile ||
10790                 error "setfattr -n user.author1=author1 $testfile failed"
10791         getfattr -n user.author1 $testfile 2> /dev/null |
10792           grep "user.author1=.author1" ||
10793                 error "$testfile missing trusted.author1=author1"
10794
10795         echo "listxattr..."
10796         setfattr -n trusted.name2 -v value2 $testfile ||
10797                 error "$testfile unable to set trusted.name2"
10798         setfattr -n trusted.name3 -v value3 $testfile ||
10799                 error "$testfile unable to set trusted.name3"
10800         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10801             grep "trusted.name" | wc -l) -eq 3 ] ||
10802                 error "$testfile missing 3 trusted.name xattrs"
10803
10804         setfattr -n user.author2 -v author2 $testfile ||
10805                 error "$testfile unable to set user.author2"
10806         setfattr -n user.author3 -v author3 $testfile ||
10807                 error "$testfile unable to set user.author3"
10808         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10809             grep "user.author" | wc -l) -eq 3 ] ||
10810                 error "$testfile missing 3 user.author xattrs"
10811
10812         echo "remove xattr..."
10813         setfattr -x trusted.name1 $testfile ||
10814                 error "$testfile error deleting trusted.name1"
10815         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10816                 error "$testfile did not delete trusted.name1 xattr"
10817
10818         setfattr -x user.author1 $testfile ||
10819                 error "$testfile error deleting user.author1"
10820         echo "set lustre special xattr ..."
10821         $LFS setstripe -c1 $testfile
10822         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10823                 awk -F "=" '/trusted.lov/ { print $2 }' )
10824         setfattr -n "trusted.lov" -v $lovea $testfile ||
10825                 error "$testfile doesn't ignore setting trusted.lov again"
10826         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10827                 error "$testfile allow setting invalid trusted.lov"
10828         rm -f $testfile
10829 }
10830 run_test 102a "user xattr test =================================="
10831
10832 check_102b_layout() {
10833         local layout="$*"
10834         local testfile=$DIR/$tfile
10835
10836         echo "test layout '$layout'"
10837         $LFS setstripe $layout $testfile || error "setstripe failed"
10838         $LFS getstripe -y $testfile
10839
10840         echo "get/set/list trusted.lov xattr ..." # b=10930
10841         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10842         [[ "$value" =~ "trusted.lov" ]] ||
10843                 error "can't get trusted.lov from $testfile"
10844         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10845                 error "getstripe failed"
10846
10847         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10848
10849         value=$(cut -d= -f2 <<<$value)
10850         # LU-13168: truncated xattr should fail if short lov_user_md header
10851         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10852                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10853         for len in $lens; do
10854                 echo "setfattr $len $testfile.2"
10855                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10856                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10857         done
10858         local stripe_size=$($LFS getstripe -S $testfile.2)
10859         local stripe_count=$($LFS getstripe -c $testfile.2)
10860         [[ $stripe_size -eq 65536 ]] ||
10861                 error "stripe size $stripe_size != 65536"
10862         [[ $stripe_count -eq $stripe_count_orig ]] ||
10863                 error "stripe count $stripe_count != $stripe_count_orig"
10864         rm $testfile $testfile.2
10865 }
10866
10867 test_102b() {
10868         [ -z "$(which setfattr 2>/dev/null)" ] &&
10869                 skip_env "could not find setfattr"
10870         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10871
10872         # check plain layout
10873         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10874
10875         # and also check composite layout
10876         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10877
10878 }
10879 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10880
10881 test_102c() {
10882         [ -z "$(which setfattr 2>/dev/null)" ] &&
10883                 skip_env "could not find setfattr"
10884         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10885
10886         # b10930: get/set/list lustre.lov xattr
10887         echo "get/set/list lustre.lov xattr ..."
10888         test_mkdir $DIR/$tdir
10889         chown $RUNAS_ID $DIR/$tdir
10890         local testfile=$DIR/$tdir/$tfile
10891         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10892                 error "setstripe failed"
10893         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10894                 error "getstripe failed"
10895         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10896         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10897
10898         local testfile2=${testfile}2
10899         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10900                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10901
10902         $RUNAS $MCREATE $testfile2
10903         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10904         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10905         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10906         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10907         [ $stripe_count -eq $STRIPECOUNT ] ||
10908                 error "stripe count $stripe_count != $STRIPECOUNT"
10909 }
10910 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10911
10912 compare_stripe_info1() {
10913         local stripe_index_all_zero=true
10914
10915         for num in 1 2 3 4; do
10916                 for count in $(seq 1 $STRIPE_COUNT); do
10917                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10918                                 local size=$((STRIPE_SIZE * num))
10919                                 local file=file"$num-$offset-$count"
10920                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10921                                 [[ $stripe_size -ne $size ]] &&
10922                                     error "$file: size $stripe_size != $size"
10923                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10924                                 # allow fewer stripes to be created, ORI-601
10925                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10926                                     error "$file: count $stripe_count != $count"
10927                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10928                                 [[ $stripe_index -ne 0 ]] &&
10929                                         stripe_index_all_zero=false
10930                         done
10931                 done
10932         done
10933         $stripe_index_all_zero &&
10934                 error "all files are being extracted starting from OST index 0"
10935         return 0
10936 }
10937
10938 have_xattrs_include() {
10939         tar --help | grep -q xattrs-include &&
10940                 echo --xattrs-include="lustre.*"
10941 }
10942
10943 test_102d() {
10944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10945         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10946
10947         XINC=$(have_xattrs_include)
10948         setup_test102
10949         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10950         cd $DIR/$tdir/$tdir
10951         compare_stripe_info1
10952 }
10953 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10954
10955 test_102f() {
10956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10957         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10958
10959         XINC=$(have_xattrs_include)
10960         setup_test102
10961         test_mkdir $DIR/$tdir.restore
10962         cd $DIR
10963         tar cf - --xattrs $tdir | tar xf - \
10964                 -C $DIR/$tdir.restore --xattrs $XINC
10965         cd $DIR/$tdir.restore/$tdir
10966         compare_stripe_info1
10967 }
10968 run_test 102f "tar copy files, not keep osts"
10969
10970 grow_xattr() {
10971         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10972                 skip "must have user_xattr"
10973         [ -z "$(which setfattr 2>/dev/null)" ] &&
10974                 skip_env "could not find setfattr"
10975         [ -z "$(which getfattr 2>/dev/null)" ] &&
10976                 skip_env "could not find getfattr"
10977
10978         local xsize=${1:-1024}  # in bytes
10979         local file=$DIR/$tfile
10980         local value="$(generate_string $xsize)"
10981         local xbig=trusted.big
10982         local toobig=$2
10983
10984         touch $file
10985         log "save $xbig on $file"
10986         if [ -z "$toobig" ]
10987         then
10988                 setfattr -n $xbig -v $value $file ||
10989                         error "saving $xbig on $file failed"
10990         else
10991                 setfattr -n $xbig -v $value $file &&
10992                         error "saving $xbig on $file succeeded"
10993                 return 0
10994         fi
10995
10996         local orig=$(get_xattr_value $xbig $file)
10997         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10998
10999         local xsml=trusted.sml
11000         log "save $xsml on $file"
11001         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11002
11003         local new=$(get_xattr_value $xbig $file)
11004         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11005
11006         log "grow $xsml on $file"
11007         setfattr -n $xsml -v "$value" $file ||
11008                 error "growing $xsml on $file failed"
11009
11010         new=$(get_xattr_value $xbig $file)
11011         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11012         log "$xbig still valid after growing $xsml"
11013
11014         rm -f $file
11015 }
11016
11017 test_102h() { # bug 15777
11018         grow_xattr 1024
11019 }
11020 run_test 102h "grow xattr from inside inode to external block"
11021
11022 test_102ha() {
11023         large_xattr_enabled || skip_env "ea_inode feature disabled"
11024
11025         echo "setting xattr of max xattr size: $(max_xattr_size)"
11026         grow_xattr $(max_xattr_size)
11027
11028         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11029         echo "This should fail:"
11030         grow_xattr $(($(max_xattr_size) + 10)) 1
11031 }
11032 run_test 102ha "grow xattr from inside inode to external inode"
11033
11034 test_102i() { # bug 17038
11035         [ -z "$(which getfattr 2>/dev/null)" ] &&
11036                 skip "could not find getfattr"
11037
11038         touch $DIR/$tfile
11039         ln -s $DIR/$tfile $DIR/${tfile}link
11040         getfattr -n trusted.lov $DIR/$tfile ||
11041                 error "lgetxattr on $DIR/$tfile failed"
11042         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11043                 grep -i "no such attr" ||
11044                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11045         rm -f $DIR/$tfile $DIR/${tfile}link
11046 }
11047 run_test 102i "lgetxattr test on symbolic link ============"
11048
11049 test_102j() {
11050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11051         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11052
11053         XINC=$(have_xattrs_include)
11054         setup_test102 "$RUNAS"
11055         chown $RUNAS_ID $DIR/$tdir
11056         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11057         cd $DIR/$tdir/$tdir
11058         compare_stripe_info1 "$RUNAS"
11059 }
11060 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11061
11062 test_102k() {
11063         [ -z "$(which setfattr 2>/dev/null)" ] &&
11064                 skip "could not find setfattr"
11065
11066         touch $DIR/$tfile
11067         # b22187 just check that does not crash for regular file.
11068         setfattr -n trusted.lov $DIR/$tfile
11069         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11070         local test_kdir=$DIR/$tdir
11071         test_mkdir $test_kdir
11072         local default_size=$($LFS getstripe -S $test_kdir)
11073         local default_count=$($LFS getstripe -c $test_kdir)
11074         local default_offset=$($LFS getstripe -i $test_kdir)
11075         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11076                 error 'dir setstripe failed'
11077         setfattr -n trusted.lov $test_kdir
11078         local stripe_size=$($LFS getstripe -S $test_kdir)
11079         local stripe_count=$($LFS getstripe -c $test_kdir)
11080         local stripe_offset=$($LFS getstripe -i $test_kdir)
11081         [ $stripe_size -eq $default_size ] ||
11082                 error "stripe size $stripe_size != $default_size"
11083         [ $stripe_count -eq $default_count ] ||
11084                 error "stripe count $stripe_count != $default_count"
11085         [ $stripe_offset -eq $default_offset ] ||
11086                 error "stripe offset $stripe_offset != $default_offset"
11087         rm -rf $DIR/$tfile $test_kdir
11088 }
11089 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11090
11091 test_102l() {
11092         [ -z "$(which getfattr 2>/dev/null)" ] &&
11093                 skip "could not find getfattr"
11094
11095         # LU-532 trusted. xattr is invisible to non-root
11096         local testfile=$DIR/$tfile
11097
11098         touch $testfile
11099
11100         echo "listxattr as user..."
11101         chown $RUNAS_ID $testfile
11102         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11103             grep -q "trusted" &&
11104                 error "$testfile trusted xattrs are user visible"
11105
11106         return 0;
11107 }
11108 run_test 102l "listxattr size test =================================="
11109
11110 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11111         local path=$DIR/$tfile
11112         touch $path
11113
11114         listxattr_size_check $path || error "listattr_size_check $path failed"
11115 }
11116 run_test 102m "Ensure listxattr fails on small bufffer ========"
11117
11118 cleanup_test102
11119
11120 getxattr() { # getxattr path name
11121         # Return the base64 encoding of the value of xattr name on path.
11122         local path=$1
11123         local name=$2
11124
11125         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11126         # file: $path
11127         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11128         #
11129         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11130
11131         getfattr --absolute-names --encoding=base64 --name=$name $path |
11132                 awk -F= -v name=$name '$1 == name {
11133                         print substr($0, index($0, "=") + 1);
11134         }'
11135 }
11136
11137 test_102n() { # LU-4101 mdt: protect internal xattrs
11138         [ -z "$(which setfattr 2>/dev/null)" ] &&
11139                 skip "could not find setfattr"
11140         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11141         then
11142                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11143         fi
11144
11145         local file0=$DIR/$tfile.0
11146         local file1=$DIR/$tfile.1
11147         local xattr0=$TMP/$tfile.0
11148         local xattr1=$TMP/$tfile.1
11149         local namelist="lov lma lmv link fid version som hsm"
11150         local name
11151         local value
11152
11153         rm -rf $file0 $file1 $xattr0 $xattr1
11154         touch $file0 $file1
11155
11156         # Get 'before' xattrs of $file1.
11157         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11158
11159         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11160                 namelist+=" lfsck_namespace"
11161         for name in $namelist; do
11162                 # Try to copy xattr from $file0 to $file1.
11163                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11164
11165                 setfattr --name=trusted.$name --value="$value" $file1 ||
11166                         error "setxattr 'trusted.$name' failed"
11167
11168                 # Try to set a garbage xattr.
11169                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11170
11171                 if [[ x$name == "xlov" ]]; then
11172                         setfattr --name=trusted.lov --value="$value" $file1 &&
11173                         error "setxattr invalid 'trusted.lov' success"
11174                 else
11175                         setfattr --name=trusted.$name --value="$value" $file1 ||
11176                                 error "setxattr invalid 'trusted.$name' failed"
11177                 fi
11178
11179                 # Try to remove the xattr from $file1. We don't care if this
11180                 # appears to succeed or fail, we just don't want there to be
11181                 # any changes or crashes.
11182                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11183         done
11184
11185         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11186         then
11187                 name="lfsck_ns"
11188                 # Try to copy xattr from $file0 to $file1.
11189                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11190
11191                 setfattr --name=trusted.$name --value="$value" $file1 ||
11192                         error "setxattr 'trusted.$name' failed"
11193
11194                 # Try to set a garbage xattr.
11195                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11196
11197                 setfattr --name=trusted.$name --value="$value" $file1 ||
11198                         error "setxattr 'trusted.$name' failed"
11199
11200                 # Try to remove the xattr from $file1. We don't care if this
11201                 # appears to succeed or fail, we just don't want there to be
11202                 # any changes or crashes.
11203                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11204         fi
11205
11206         # Get 'after' xattrs of file1.
11207         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11208
11209         if ! diff $xattr0 $xattr1; then
11210                 error "before and after xattrs of '$file1' differ"
11211         fi
11212
11213         rm -rf $file0 $file1 $xattr0 $xattr1
11214
11215         return 0
11216 }
11217 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11218
11219 test_102p() { # LU-4703 setxattr did not check ownership
11220         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11221                 skip "MDS needs to be at least 2.5.56"
11222
11223         local testfile=$DIR/$tfile
11224
11225         touch $testfile
11226
11227         echo "setfacl as user..."
11228         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11229         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11230
11231         echo "setfattr as user..."
11232         setfacl -m "u:$RUNAS_ID:---" $testfile
11233         $RUNAS setfattr -x system.posix_acl_access $testfile
11234         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11235 }
11236 run_test 102p "check setxattr(2) correctly fails without permission"
11237
11238 test_102q() {
11239         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11240                 skip "MDS needs to be at least 2.6.92"
11241
11242         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11243 }
11244 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11245
11246 test_102r() {
11247         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11248                 skip "MDS needs to be at least 2.6.93"
11249
11250         touch $DIR/$tfile || error "touch"
11251         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11252         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11253         rm $DIR/$tfile || error "rm"
11254
11255         #normal directory
11256         mkdir -p $DIR/$tdir || error "mkdir"
11257         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11258         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11259         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11260                 error "$testfile error deleting user.author1"
11261         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11262                 grep "user.$(basename $tdir)" &&
11263                 error "$tdir did not delete user.$(basename $tdir)"
11264         rmdir $DIR/$tdir || error "rmdir"
11265
11266         #striped directory
11267         test_mkdir $DIR/$tdir
11268         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11269         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11270         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11271                 error "$testfile error deleting user.author1"
11272         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11273                 grep "user.$(basename $tdir)" &&
11274                 error "$tdir did not delete user.$(basename $tdir)"
11275         rmdir $DIR/$tdir || error "rm striped dir"
11276 }
11277 run_test 102r "set EAs with empty values"
11278
11279 test_102s() {
11280         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11281                 skip "MDS needs to be at least 2.11.52"
11282
11283         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11284
11285         save_lustre_params client "llite.*.xattr_cache" > $save
11286
11287         for cache in 0 1; do
11288                 lctl set_param llite.*.xattr_cache=$cache
11289
11290                 rm -f $DIR/$tfile
11291                 touch $DIR/$tfile || error "touch"
11292                 for prefix in lustre security system trusted user; do
11293                         # Note getxattr() may fail with 'Operation not
11294                         # supported' or 'No such attribute' depending
11295                         # on prefix and cache.
11296                         getfattr -n $prefix.n102s $DIR/$tfile &&
11297                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11298                 done
11299         done
11300
11301         restore_lustre_params < $save
11302 }
11303 run_test 102s "getting nonexistent xattrs should fail"
11304
11305 test_102t() {
11306         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11307                 skip "MDS needs to be at least 2.11.52"
11308
11309         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11310
11311         save_lustre_params client "llite.*.xattr_cache" > $save
11312
11313         for cache in 0 1; do
11314                 lctl set_param llite.*.xattr_cache=$cache
11315
11316                 for buf_size in 0 256; do
11317                         rm -f $DIR/$tfile
11318                         touch $DIR/$tfile || error "touch"
11319                         setfattr -n user.multiop $DIR/$tfile
11320                         $MULTIOP $DIR/$tfile oa$buf_size ||
11321                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11322                 done
11323         done
11324
11325         restore_lustre_params < $save
11326 }
11327 run_test 102t "zero length xattr values handled correctly"
11328
11329 run_acl_subtest()
11330 {
11331     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11332     return $?
11333 }
11334
11335 test_103a() {
11336         [ "$UID" != 0 ] && skip "must run as root"
11337         $GSS && skip_env "could not run under gss"
11338         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11339                 skip_env "must have acl enabled"
11340         [ -z "$(which setfacl 2>/dev/null)" ] &&
11341                 skip_env "could not find setfacl"
11342         remote_mds_nodsh && skip "remote MDS with nodsh"
11343
11344         gpasswd -a daemon bin                           # LU-5641
11345         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11346
11347         declare -a identity_old
11348
11349         for num in $(seq $MDSCOUNT); do
11350                 switch_identity $num true || identity_old[$num]=$?
11351         done
11352
11353         SAVE_UMASK=$(umask)
11354         umask 0022
11355         mkdir -p $DIR/$tdir
11356         cd $DIR/$tdir
11357
11358         echo "performing cp ..."
11359         run_acl_subtest cp || error "run_acl_subtest cp failed"
11360         echo "performing getfacl-noacl..."
11361         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11362         echo "performing misc..."
11363         run_acl_subtest misc || error  "misc test failed"
11364         echo "performing permissions..."
11365         run_acl_subtest permissions || error "permissions failed"
11366         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11367         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11368                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11369                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11370         then
11371                 echo "performing permissions xattr..."
11372                 run_acl_subtest permissions_xattr ||
11373                         error "permissions_xattr failed"
11374         fi
11375         echo "performing setfacl..."
11376         run_acl_subtest setfacl || error  "setfacl test failed"
11377
11378         # inheritance test got from HP
11379         echo "performing inheritance..."
11380         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11381         chmod +x make-tree || error "chmod +x failed"
11382         run_acl_subtest inheritance || error "inheritance test failed"
11383         rm -f make-tree
11384
11385         echo "LU-974 ignore umask when acl is enabled..."
11386         run_acl_subtest 974 || error "LU-974 umask test failed"
11387         if [ $MDSCOUNT -ge 2 ]; then
11388                 run_acl_subtest 974_remote ||
11389                         error "LU-974 umask test failed under remote dir"
11390         fi
11391
11392         echo "LU-2561 newly created file is same size as directory..."
11393         if [ "$mds1_FSTYPE" != "zfs" ]; then
11394                 run_acl_subtest 2561 || error "LU-2561 test failed"
11395         else
11396                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11397         fi
11398
11399         run_acl_subtest 4924 || error "LU-4924 test failed"
11400
11401         cd $SAVE_PWD
11402         umask $SAVE_UMASK
11403
11404         for num in $(seq $MDSCOUNT); do
11405                 if [ "${identity_old[$num]}" = 1 ]; then
11406                         switch_identity $num false || identity_old[$num]=$?
11407                 fi
11408         done
11409 }
11410 run_test 103a "acl test"
11411
11412 test_103b() {
11413         declare -a pids
11414         local U
11415
11416         for U in {0..511}; do
11417                 {
11418                 local O=$(printf "%04o" $U)
11419
11420                 umask $(printf "%04o" $((511 ^ $O)))
11421                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11422                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11423
11424                 (( $S == ($O & 0666) )) ||
11425                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11426
11427                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11428                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11429                 (( $S == ($O & 0666) )) ||
11430                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11431
11432                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11433                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11434                 (( $S == ($O & 0666) )) ||
11435                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11436                 rm -f $DIR/$tfile.[smp]$0
11437                 } &
11438                 local pid=$!
11439
11440                 # limit the concurrently running threads to 64. LU-11878
11441                 local idx=$((U % 64))
11442                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11443                 pids[idx]=$pid
11444         done
11445         wait
11446 }
11447 run_test 103b "umask lfs setstripe"
11448
11449 test_103c() {
11450         mkdir -p $DIR/$tdir
11451         cp -rp $DIR/$tdir $DIR/$tdir.bak
11452
11453         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11454                 error "$DIR/$tdir shouldn't contain default ACL"
11455         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11456                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11457         true
11458 }
11459 run_test 103c "'cp -rp' won't set empty acl"
11460
11461 test_103e() {
11462         local numacl
11463         local fileacl
11464         local saved_debug=$($LCTL get_param -n debug)
11465
11466         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
11467                 skip "MDS needs to be at least 2.14.0"
11468
11469         large_xattr_enabled || skip_env "ea_inode feature disabled"
11470
11471         mkdir -p $DIR/$tdir
11472         # add big LOV EA to cause reply buffer overflow earlier
11473         $LFS setstripe -C 1000 $DIR/$tdir
11474         lctl set_param mdc.*-mdc*.stats=clear
11475
11476         $LCTL set_param debug=0
11477         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11478         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11479
11480         # add a large number of default ACLs (expect 8000+ for 2.13+)
11481         for U in {2..7000}; do
11482                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11483                         error "Able to add just $U default ACLs"
11484         done
11485         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11486         echo "$numacl default ACLs created"
11487
11488         stat $DIR/$tdir || error "Cannot stat directory"
11489         # check file creation
11490         touch $DIR/$tdir/$tfile ||
11491                 error "failed to create $tfile with $numacl default ACLs"
11492         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11493         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11494         echo "$fileacl ACLs were inherited"
11495         (( $fileacl == $numacl )) ||
11496                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11497         # check that new ACLs creation adds new ACLs to inherited ACLs
11498         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11499                 error "Cannot set new ACL"
11500         numacl=$((numacl + 1))
11501         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11502         (( $fileacl == $numacl )) ||
11503                 error "failed to add new ACL: $fileacl != $numacl as expected"
11504         # adds more ACLs to a file to reach their maximum at 8000+
11505         numacl=0
11506         for U in {20000..25000}; do
11507                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11508                 numacl=$((numacl + 1))
11509         done
11510         echo "Added $numacl more ACLs to the file"
11511         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11512         echo "Total $fileacl ACLs in file"
11513         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11514         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11515         rmdir $DIR/$tdir || error "Cannot remove directory"
11516 }
11517 run_test 103e "inheritance of big amount of default ACLs"
11518
11519 test_103f() {
11520         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11521                 skip "MDS needs to be at least 2.14.51"
11522
11523         large_xattr_enabled || skip_env "ea_inode feature disabled"
11524
11525         # enable changelog to consume more internal MDD buffers
11526         changelog_register
11527
11528         mkdir -p $DIR/$tdir
11529         # add big LOV EA
11530         $LFS setstripe -C 1000 $DIR/$tdir
11531         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11532         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11533         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11534         rmdir $DIR/$tdir || error "Cannot remove directory"
11535 }
11536 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11537
11538 test_104a() {
11539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11540
11541         touch $DIR/$tfile
11542         lfs df || error "lfs df failed"
11543         lfs df -ih || error "lfs df -ih failed"
11544         lfs df -h $DIR || error "lfs df -h $DIR failed"
11545         lfs df -i $DIR || error "lfs df -i $DIR failed"
11546         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11547         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11548
11549         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11550         lctl --device %$OSC deactivate
11551         lfs df || error "lfs df with deactivated OSC failed"
11552         lctl --device %$OSC activate
11553         # wait the osc back to normal
11554         wait_osc_import_ready client ost
11555
11556         lfs df || error "lfs df with reactivated OSC failed"
11557         rm -f $DIR/$tfile
11558 }
11559 run_test 104a "lfs df [-ih] [path] test ========================="
11560
11561 test_104b() {
11562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11563         [ $RUNAS_ID -eq $UID ] &&
11564                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11565
11566         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11567                         grep "Permission denied" | wc -l)))
11568         if [ $denied_cnt -ne 0 ]; then
11569                 error "lfs check servers test failed"
11570         fi
11571 }
11572 run_test 104b "$RUNAS lfs check servers test ===================="
11573
11574 #
11575 # Verify $1 is within range of $2.
11576 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11577 # $1 is <= 2% of $2. Else Fail.
11578 #
11579 value_in_range() {
11580         # Strip all units (M, G, T)
11581         actual=$(echo $1 | tr -d A-Z)
11582         expect=$(echo $2 | tr -d A-Z)
11583
11584         expect_lo=$(($expect * 98 / 100)) # 2% below
11585         expect_hi=$(($expect * 102 / 100)) # 2% above
11586
11587         # permit 2% drift above and below
11588         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11589 }
11590
11591 test_104c() {
11592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11593         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11594
11595         local ost_param="osd-zfs.$FSNAME-OST0000."
11596         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11597         local ofacets=$(get_facets OST)
11598         local mfacets=$(get_facets MDS)
11599         local saved_ost_blocks=
11600         local saved_mdt_blocks=
11601
11602         echo "Before recordsize change"
11603         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11604         df=($(df -h | grep "/mnt/lustre"$))
11605
11606         # For checking.
11607         echo "lfs output : ${lfs_df[*]}"
11608         echo "df  output : ${df[*]}"
11609
11610         for facet in ${ofacets//,/ }; do
11611                 if [ -z $saved_ost_blocks ]; then
11612                         saved_ost_blocks=$(do_facet $facet \
11613                                 lctl get_param -n $ost_param.blocksize)
11614                         echo "OST Blocksize: $saved_ost_blocks"
11615                 fi
11616                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11617                 do_facet $facet zfs set recordsize=32768 $ost
11618         done
11619
11620         # BS too small. Sufficient for functional testing.
11621         for facet in ${mfacets//,/ }; do
11622                 if [ -z $saved_mdt_blocks ]; then
11623                         saved_mdt_blocks=$(do_facet $facet \
11624                                 lctl get_param -n $mdt_param.blocksize)
11625                         echo "MDT Blocksize: $saved_mdt_blocks"
11626                 fi
11627                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11628                 do_facet $facet zfs set recordsize=32768 $mdt
11629         done
11630
11631         # Give new values chance to reflect change
11632         sleep 2
11633
11634         echo "After recordsize change"
11635         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11636         df_after=($(df -h | grep "/mnt/lustre"$))
11637
11638         # For checking.
11639         echo "lfs output : ${lfs_df_after[*]}"
11640         echo "df  output : ${df_after[*]}"
11641
11642         # Verify lfs df
11643         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11644                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11645         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11646                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11647         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11648                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11649
11650         # Verify df
11651         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11652                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11653         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11654                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11655         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11656                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11657
11658         # Restore MDT recordize back to original
11659         for facet in ${mfacets//,/ }; do
11660                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11661                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11662         done
11663
11664         # Restore OST recordize back to original
11665         for facet in ${ofacets//,/ }; do
11666                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11667                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11668         done
11669
11670         return 0
11671 }
11672 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11673
11674 test_105a() {
11675         # doesn't work on 2.4 kernels
11676         touch $DIR/$tfile
11677         if $(flock_is_enabled); then
11678                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11679         else
11680                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11681         fi
11682         rm -f $DIR/$tfile
11683 }
11684 run_test 105a "flock when mounted without -o flock test ========"
11685
11686 test_105b() {
11687         touch $DIR/$tfile
11688         if $(flock_is_enabled); then
11689                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11690         else
11691                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11692         fi
11693         rm -f $DIR/$tfile
11694 }
11695 run_test 105b "fcntl when mounted without -o flock test ========"
11696
11697 test_105c() {
11698         touch $DIR/$tfile
11699         if $(flock_is_enabled); then
11700                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11701         else
11702                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11703         fi
11704         rm -f $DIR/$tfile
11705 }
11706 run_test 105c "lockf when mounted without -o flock test"
11707
11708 test_105d() { # bug 15924
11709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11710
11711         test_mkdir $DIR/$tdir
11712         flock_is_enabled || skip_env "mount w/o flock enabled"
11713         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11714         $LCTL set_param fail_loc=0x80000315
11715         flocks_test 2 $DIR/$tdir
11716 }
11717 run_test 105d "flock race (should not freeze) ========"
11718
11719 test_105e() { # bug 22660 && 22040
11720         flock_is_enabled || skip_env "mount w/o flock enabled"
11721
11722         touch $DIR/$tfile
11723         flocks_test 3 $DIR/$tfile
11724 }
11725 run_test 105e "Two conflicting flocks from same process"
11726
11727 test_106() { #bug 10921
11728         test_mkdir $DIR/$tdir
11729         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11730         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11731 }
11732 run_test 106 "attempt exec of dir followed by chown of that dir"
11733
11734 test_107() {
11735         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11736
11737         CDIR=`pwd`
11738         local file=core
11739
11740         cd $DIR
11741         rm -f $file
11742
11743         local save_pattern=$(sysctl -n kernel.core_pattern)
11744         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11745         sysctl -w kernel.core_pattern=$file
11746         sysctl -w kernel.core_uses_pid=0
11747
11748         ulimit -c unlimited
11749         sleep 60 &
11750         SLEEPPID=$!
11751
11752         sleep 1
11753
11754         kill -s 11 $SLEEPPID
11755         wait $SLEEPPID
11756         if [ -e $file ]; then
11757                 size=`stat -c%s $file`
11758                 [ $size -eq 0 ] && error "Fail to create core file $file"
11759         else
11760                 error "Fail to create core file $file"
11761         fi
11762         rm -f $file
11763         sysctl -w kernel.core_pattern=$save_pattern
11764         sysctl -w kernel.core_uses_pid=$save_uses_pid
11765         cd $CDIR
11766 }
11767 run_test 107 "Coredump on SIG"
11768
11769 test_110() {
11770         test_mkdir $DIR/$tdir
11771         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11772         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11773                 error "mkdir with 256 char should fail, but did not"
11774         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11775                 error "create with 255 char failed"
11776         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11777                 error "create with 256 char should fail, but did not"
11778
11779         ls -l $DIR/$tdir
11780         rm -rf $DIR/$tdir
11781 }
11782 run_test 110 "filename length checking"
11783
11784 #
11785 # Purpose: To verify dynamic thread (OSS) creation.
11786 #
11787 test_115() {
11788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11789         remote_ost_nodsh && skip "remote OST with nodsh"
11790
11791         # Lustre does not stop service threads once they are started.
11792         # Reset number of running threads to default.
11793         stopall
11794         setupall
11795
11796         local OSTIO_pre
11797         local save_params="$TMP/sanity-$TESTNAME.parameters"
11798
11799         # Get ll_ost_io count before I/O
11800         OSTIO_pre=$(do_facet ost1 \
11801                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11802         # Exit if lustre is not running (ll_ost_io not running).
11803         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11804
11805         echo "Starting with $OSTIO_pre threads"
11806         local thread_max=$((OSTIO_pre * 2))
11807         local rpc_in_flight=$((thread_max * 2))
11808         # Number of I/O Process proposed to be started.
11809         local nfiles
11810         local facets=$(get_facets OST)
11811
11812         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11813         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11814
11815         # Set in_flight to $rpc_in_flight
11816         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11817                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11818         nfiles=${rpc_in_flight}
11819         # Set ost thread_max to $thread_max
11820         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11821
11822         # 5 Minutes should be sufficient for max number of OSS
11823         # threads(thread_max) to be created.
11824         local timeout=300
11825
11826         # Start I/O.
11827         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11828         test_mkdir $DIR/$tdir
11829         for i in $(seq $nfiles); do
11830                 local file=$DIR/$tdir/${tfile}-$i
11831                 $LFS setstripe -c -1 -i 0 $file
11832                 ($WTL $file $timeout)&
11833         done
11834
11835         # I/O Started - Wait for thread_started to reach thread_max or report
11836         # error if thread_started is more than thread_max.
11837         echo "Waiting for thread_started to reach thread_max"
11838         local thread_started=0
11839         local end_time=$((SECONDS + timeout))
11840
11841         while [ $SECONDS -le $end_time ] ; do
11842                 echo -n "."
11843                 # Get ost i/o thread_started count.
11844                 thread_started=$(do_facet ost1 \
11845                         "$LCTL get_param \
11846                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11847                 # Break out if thread_started is equal/greater than thread_max
11848                 if [[ $thread_started -ge $thread_max ]]; then
11849                         echo ll_ost_io thread_started $thread_started, \
11850                                 equal/greater than thread_max $thread_max
11851                         break
11852                 fi
11853                 sleep 1
11854         done
11855
11856         # Cleanup - We have the numbers, Kill i/o jobs if running.
11857         jobcount=($(jobs -p))
11858         for i in $(seq 0 $((${#jobcount[@]}-1)))
11859         do
11860                 kill -9 ${jobcount[$i]}
11861                 if [ $? -ne 0 ] ; then
11862                         echo Warning: \
11863                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11864                 fi
11865         done
11866
11867         # Cleanup files left by WTL binary.
11868         for i in $(seq $nfiles); do
11869                 local file=$DIR/$tdir/${tfile}-$i
11870                 rm -rf $file
11871                 if [ $? -ne 0 ] ; then
11872                         echo "Warning: Failed to delete file $file"
11873                 fi
11874         done
11875
11876         restore_lustre_params <$save_params
11877         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11878
11879         # Error out if no new thread has started or Thread started is greater
11880         # than thread max.
11881         if [[ $thread_started -le $OSTIO_pre ||
11882                         $thread_started -gt $thread_max ]]; then
11883                 error "ll_ost_io: thread_started $thread_started" \
11884                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11885                       "No new thread started or thread started greater " \
11886                       "than thread_max."
11887         fi
11888 }
11889 run_test 115 "verify dynamic thread creation===================="
11890
11891 free_min_max () {
11892         wait_delete_completed
11893         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11894         echo "OST kbytes available: ${AVAIL[@]}"
11895         MAXV=${AVAIL[0]}
11896         MAXI=0
11897         MINV=${AVAIL[0]}
11898         MINI=0
11899         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11900                 #echo OST $i: ${AVAIL[i]}kb
11901                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11902                         MAXV=${AVAIL[i]}
11903                         MAXI=$i
11904                 fi
11905                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11906                         MINV=${AVAIL[i]}
11907                         MINI=$i
11908                 fi
11909         done
11910         echo "Min free space: OST $MINI: $MINV"
11911         echo "Max free space: OST $MAXI: $MAXV"
11912 }
11913
11914 test_116a() { # was previously test_116()
11915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11916         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11917         remote_mds_nodsh && skip "remote MDS with nodsh"
11918
11919         echo -n "Free space priority "
11920         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11921                 head -n1
11922         declare -a AVAIL
11923         free_min_max
11924
11925         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11926         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11927         stack_trap simple_cleanup_common
11928
11929         # Check if we need to generate uneven OSTs
11930         test_mkdir -p $DIR/$tdir/OST${MINI}
11931         local FILL=$((MINV / 4))
11932         local DIFF=$((MAXV - MINV))
11933         local DIFF2=$((DIFF * 100 / MINV))
11934
11935         local threshold=$(do_facet $SINGLEMDS \
11936                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11937         threshold=${threshold%%%}
11938         echo -n "Check for uneven OSTs: "
11939         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11940
11941         if [[ $DIFF2 -gt $threshold ]]; then
11942                 echo "ok"
11943                 echo "Don't need to fill OST$MINI"
11944         else
11945                 # generate uneven OSTs. Write 2% over the QOS threshold value
11946                 echo "no"
11947                 DIFF=$((threshold - DIFF2 + 2))
11948                 DIFF2=$((MINV * DIFF / 100))
11949                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11950                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11951                         error "setstripe failed"
11952                 DIFF=$((DIFF2 / 2048))
11953                 i=0
11954                 while [ $i -lt $DIFF ]; do
11955                         i=$((i + 1))
11956                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11957                                 bs=2M count=1 2>/dev/null
11958                         echo -n .
11959                 done
11960                 echo .
11961                 sync
11962                 sleep_maxage
11963                 free_min_max
11964         fi
11965
11966         DIFF=$((MAXV - MINV))
11967         DIFF2=$((DIFF * 100 / MINV))
11968         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11969         if [ $DIFF2 -gt $threshold ]; then
11970                 echo "ok"
11971         else
11972                 skip "QOS imbalance criteria not met"
11973         fi
11974
11975         MINI1=$MINI
11976         MINV1=$MINV
11977         MAXI1=$MAXI
11978         MAXV1=$MAXV
11979
11980         # now fill using QOS
11981         $LFS setstripe -c 1 $DIR/$tdir
11982         FILL=$((FILL / 200))
11983         if [ $FILL -gt 600 ]; then
11984                 FILL=600
11985         fi
11986         echo "writing $FILL files to QOS-assigned OSTs"
11987         i=0
11988         while [ $i -lt $FILL ]; do
11989                 i=$((i + 1))
11990                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11991                         count=1 2>/dev/null
11992                 echo -n .
11993         done
11994         echo "wrote $i 200k files"
11995         sync
11996         sleep_maxage
11997
11998         echo "Note: free space may not be updated, so measurements might be off"
11999         free_min_max
12000         DIFF2=$((MAXV - MINV))
12001         echo "free space delta: orig $DIFF final $DIFF2"
12002         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12003         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12004         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12005         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12006         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12007         if [[ $DIFF -gt 0 ]]; then
12008                 FILL=$((DIFF2 * 100 / DIFF - 100))
12009                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12010         fi
12011
12012         # Figure out which files were written where
12013         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12014                awk '/'$MINI1': / {print $2; exit}')
12015         echo $UUID
12016         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12017         echo "$MINC files created on smaller OST $MINI1"
12018         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12019                awk '/'$MAXI1': / {print $2; exit}')
12020         echo $UUID
12021         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12022         echo "$MAXC files created on larger OST $MAXI1"
12023         if [[ $MINC -gt 0 ]]; then
12024                 FILL=$((MAXC * 100 / MINC - 100))
12025                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12026         fi
12027         [[ $MAXC -gt $MINC ]] ||
12028                 error_ignore LU-9 "stripe QOS didn't balance free space"
12029 }
12030 run_test 116a "stripe QOS: free space balance ==================="
12031
12032 test_116b() { # LU-2093
12033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12034         remote_mds_nodsh && skip "remote MDS with nodsh"
12035
12036 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12037         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12038                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12039         [ -z "$old_rr" ] && skip "no QOS"
12040         do_facet $SINGLEMDS lctl set_param \
12041                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12042         mkdir -p $DIR/$tdir
12043         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12044         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12045         do_facet $SINGLEMDS lctl set_param fail_loc=0
12046         rm -rf $DIR/$tdir
12047         do_facet $SINGLEMDS lctl set_param \
12048                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12049 }
12050 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12051
12052 test_117() # bug 10891
12053 {
12054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12055
12056         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12057         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12058         lctl set_param fail_loc=0x21e
12059         > $DIR/$tfile || error "truncate failed"
12060         lctl set_param fail_loc=0
12061         echo "Truncate succeeded."
12062         rm -f $DIR/$tfile
12063 }
12064 run_test 117 "verify osd extend =========="
12065
12066 NO_SLOW_RESENDCOUNT=4
12067 export OLD_RESENDCOUNT=""
12068 set_resend_count () {
12069         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12070         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12071         lctl set_param -n $PROC_RESENDCOUNT $1
12072         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12073 }
12074
12075 # for reduce test_118* time (b=14842)
12076 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12077
12078 # Reset async IO behavior after error case
12079 reset_async() {
12080         FILE=$DIR/reset_async
12081
12082         # Ensure all OSCs are cleared
12083         $LFS setstripe -c -1 $FILE
12084         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12085         sync
12086         rm $FILE
12087 }
12088
12089 test_118a() #bug 11710
12090 {
12091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12092
12093         reset_async
12094
12095         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12096         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12097         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12098
12099         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12100                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12101                 return 1;
12102         fi
12103         rm -f $DIR/$tfile
12104 }
12105 run_test 118a "verify O_SYNC works =========="
12106
12107 test_118b()
12108 {
12109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12110         remote_ost_nodsh && skip "remote OST with nodsh"
12111
12112         reset_async
12113
12114         #define OBD_FAIL_SRV_ENOENT 0x217
12115         set_nodes_failloc "$(osts_nodes)" 0x217
12116         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12117         RC=$?
12118         set_nodes_failloc "$(osts_nodes)" 0
12119         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12120         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12121                     grep -c writeback)
12122
12123         if [[ $RC -eq 0 ]]; then
12124                 error "Must return error due to dropped pages, rc=$RC"
12125                 return 1;
12126         fi
12127
12128         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12129                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12130                 return 1;
12131         fi
12132
12133         echo "Dirty pages not leaked on ENOENT"
12134
12135         # Due to the above error the OSC will issue all RPCs syncronously
12136         # until a subsequent RPC completes successfully without error.
12137         $MULTIOP $DIR/$tfile Ow4096yc
12138         rm -f $DIR/$tfile
12139
12140         return 0
12141 }
12142 run_test 118b "Reclaim dirty pages on fatal error =========="
12143
12144 test_118c()
12145 {
12146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12147
12148         # for 118c, restore the original resend count, LU-1940
12149         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12150                                 set_resend_count $OLD_RESENDCOUNT
12151         remote_ost_nodsh && skip "remote OST with nodsh"
12152
12153         reset_async
12154
12155         #define OBD_FAIL_OST_EROFS               0x216
12156         set_nodes_failloc "$(osts_nodes)" 0x216
12157
12158         # multiop should block due to fsync until pages are written
12159         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12160         MULTIPID=$!
12161         sleep 1
12162
12163         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12164                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12165         fi
12166
12167         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12168                     grep -c writeback)
12169         if [[ $WRITEBACK -eq 0 ]]; then
12170                 error "No page in writeback, writeback=$WRITEBACK"
12171         fi
12172
12173         set_nodes_failloc "$(osts_nodes)" 0
12174         wait $MULTIPID
12175         RC=$?
12176         if [[ $RC -ne 0 ]]; then
12177                 error "Multiop fsync failed, rc=$RC"
12178         fi
12179
12180         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12181         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12182                     grep -c writeback)
12183         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12184                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12185         fi
12186
12187         rm -f $DIR/$tfile
12188         echo "Dirty pages flushed via fsync on EROFS"
12189         return 0
12190 }
12191 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12192
12193 # continue to use small resend count to reduce test_118* time (b=14842)
12194 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12195
12196 test_118d()
12197 {
12198         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12199         remote_ost_nodsh && skip "remote OST with nodsh"
12200
12201         reset_async
12202
12203         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12204         set_nodes_failloc "$(osts_nodes)" 0x214
12205         # multiop should block due to fsync until pages are written
12206         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12207         MULTIPID=$!
12208         sleep 1
12209
12210         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12211                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12212         fi
12213
12214         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12215                     grep -c writeback)
12216         if [[ $WRITEBACK -eq 0 ]]; then
12217                 error "No page in writeback, writeback=$WRITEBACK"
12218         fi
12219
12220         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12221         set_nodes_failloc "$(osts_nodes)" 0
12222
12223         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12224         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12225                     grep -c writeback)
12226         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12227                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12228         fi
12229
12230         rm -f $DIR/$tfile
12231         echo "Dirty pages gaurenteed flushed via fsync"
12232         return 0
12233 }
12234 run_test 118d "Fsync validation inject a delay of the bulk =========="
12235
12236 test_118f() {
12237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12238
12239         reset_async
12240
12241         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12242         lctl set_param fail_loc=0x8000040a
12243
12244         # Should simulate EINVAL error which is fatal
12245         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12246         RC=$?
12247         if [[ $RC -eq 0 ]]; then
12248                 error "Must return error due to dropped pages, rc=$RC"
12249         fi
12250
12251         lctl set_param fail_loc=0x0
12252
12253         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12254         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12255         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12256                     grep -c writeback)
12257         if [[ $LOCKED -ne 0 ]]; then
12258                 error "Locked pages remain in cache, locked=$LOCKED"
12259         fi
12260
12261         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12262                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12263         fi
12264
12265         rm -f $DIR/$tfile
12266         echo "No pages locked after fsync"
12267
12268         reset_async
12269         return 0
12270 }
12271 run_test 118f "Simulate unrecoverable OSC side error =========="
12272
12273 test_118g() {
12274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12275
12276         reset_async
12277
12278         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12279         lctl set_param fail_loc=0x406
12280
12281         # simulate local -ENOMEM
12282         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12283         RC=$?
12284
12285         lctl set_param fail_loc=0
12286         if [[ $RC -eq 0 ]]; then
12287                 error "Must return error due to dropped pages, rc=$RC"
12288         fi
12289
12290         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12291         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12292         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12293                         grep -c writeback)
12294         if [[ $LOCKED -ne 0 ]]; then
12295                 error "Locked pages remain in cache, locked=$LOCKED"
12296         fi
12297
12298         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12299                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12300         fi
12301
12302         rm -f $DIR/$tfile
12303         echo "No pages locked after fsync"
12304
12305         reset_async
12306         return 0
12307 }
12308 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12309
12310 test_118h() {
12311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12312         remote_ost_nodsh && skip "remote OST with nodsh"
12313
12314         reset_async
12315
12316         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12317         set_nodes_failloc "$(osts_nodes)" 0x20e
12318         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12319         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12320         RC=$?
12321
12322         set_nodes_failloc "$(osts_nodes)" 0
12323         if [[ $RC -eq 0 ]]; then
12324                 error "Must return error due to dropped pages, rc=$RC"
12325         fi
12326
12327         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12328         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12329         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12330                     grep -c writeback)
12331         if [[ $LOCKED -ne 0 ]]; then
12332                 error "Locked pages remain in cache, locked=$LOCKED"
12333         fi
12334
12335         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12336                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12337         fi
12338
12339         rm -f $DIR/$tfile
12340         echo "No pages locked after fsync"
12341
12342         return 0
12343 }
12344 run_test 118h "Verify timeout in handling recoverables errors  =========="
12345
12346 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12347
12348 test_118i() {
12349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12350         remote_ost_nodsh && skip "remote OST with nodsh"
12351
12352         reset_async
12353
12354         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12355         set_nodes_failloc "$(osts_nodes)" 0x20e
12356
12357         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12358         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12359         PID=$!
12360         sleep 5
12361         set_nodes_failloc "$(osts_nodes)" 0
12362
12363         wait $PID
12364         RC=$?
12365         if [[ $RC -ne 0 ]]; then
12366                 error "got error, but should be not, rc=$RC"
12367         fi
12368
12369         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12370         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12371         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12372         if [[ $LOCKED -ne 0 ]]; then
12373                 error "Locked pages remain in cache, locked=$LOCKED"
12374         fi
12375
12376         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12377                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12378         fi
12379
12380         rm -f $DIR/$tfile
12381         echo "No pages locked after fsync"
12382
12383         return 0
12384 }
12385 run_test 118i "Fix error before timeout in recoverable error  =========="
12386
12387 [ "$SLOW" = "no" ] && set_resend_count 4
12388
12389 test_118j() {
12390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12391         remote_ost_nodsh && skip "remote OST with nodsh"
12392
12393         reset_async
12394
12395         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12396         set_nodes_failloc "$(osts_nodes)" 0x220
12397
12398         # return -EIO from OST
12399         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12400         RC=$?
12401         set_nodes_failloc "$(osts_nodes)" 0x0
12402         if [[ $RC -eq 0 ]]; then
12403                 error "Must return error due to dropped pages, rc=$RC"
12404         fi
12405
12406         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12407         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12408         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12409         if [[ $LOCKED -ne 0 ]]; then
12410                 error "Locked pages remain in cache, locked=$LOCKED"
12411         fi
12412
12413         # in recoverable error on OST we want resend and stay until it finished
12414         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12415                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12416         fi
12417
12418         rm -f $DIR/$tfile
12419         echo "No pages locked after fsync"
12420
12421         return 0
12422 }
12423 run_test 118j "Simulate unrecoverable OST side error =========="
12424
12425 test_118k()
12426 {
12427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12428         remote_ost_nodsh && skip "remote OSTs with nodsh"
12429
12430         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12431         set_nodes_failloc "$(osts_nodes)" 0x20e
12432         test_mkdir $DIR/$tdir
12433
12434         for ((i=0;i<10;i++)); do
12435                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12436                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12437                 SLEEPPID=$!
12438                 sleep 0.500s
12439                 kill $SLEEPPID
12440                 wait $SLEEPPID
12441         done
12442
12443         set_nodes_failloc "$(osts_nodes)" 0
12444         rm -rf $DIR/$tdir
12445 }
12446 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12447
12448 test_118l() # LU-646
12449 {
12450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12451
12452         test_mkdir $DIR/$tdir
12453         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12454         rm -rf $DIR/$tdir
12455 }
12456 run_test 118l "fsync dir"
12457
12458 test_118m() # LU-3066
12459 {
12460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12461
12462         test_mkdir $DIR/$tdir
12463         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12464         rm -rf $DIR/$tdir
12465 }
12466 run_test 118m "fdatasync dir ========="
12467
12468 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12469
12470 test_118n()
12471 {
12472         local begin
12473         local end
12474
12475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12476         remote_ost_nodsh && skip "remote OSTs with nodsh"
12477
12478         # Sleep to avoid a cached response.
12479         #define OBD_STATFS_CACHE_SECONDS 1
12480         sleep 2
12481
12482         # Inject a 10 second delay in the OST_STATFS handler.
12483         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12484         set_nodes_failloc "$(osts_nodes)" 0x242
12485
12486         begin=$SECONDS
12487         stat --file-system $MOUNT > /dev/null
12488         end=$SECONDS
12489
12490         set_nodes_failloc "$(osts_nodes)" 0
12491
12492         if ((end - begin > 20)); then
12493             error "statfs took $((end - begin)) seconds, expected 10"
12494         fi
12495 }
12496 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12497
12498 test_119a() # bug 11737
12499 {
12500         BSIZE=$((512 * 1024))
12501         directio write $DIR/$tfile 0 1 $BSIZE
12502         # We ask to read two blocks, which is more than a file size.
12503         # directio will indicate an error when requested and actual
12504         # sizes aren't equeal (a normal situation in this case) and
12505         # print actual read amount.
12506         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12507         if [ "$NOB" != "$BSIZE" ]; then
12508                 error "read $NOB bytes instead of $BSIZE"
12509         fi
12510         rm -f $DIR/$tfile
12511 }
12512 run_test 119a "Short directIO read must return actual read amount"
12513
12514 test_119b() # bug 11737
12515 {
12516         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12517
12518         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12519         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12520         sync
12521         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12522                 error "direct read failed"
12523         rm -f $DIR/$tfile
12524 }
12525 run_test 119b "Sparse directIO read must return actual read amount"
12526
12527 test_119c() # bug 13099
12528 {
12529         BSIZE=1048576
12530         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12531         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12532         rm -f $DIR/$tfile
12533 }
12534 run_test 119c "Testing for direct read hitting hole"
12535
12536 test_119d() # bug 15950
12537 {
12538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12539
12540         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12541         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12542         BSIZE=1048576
12543         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12544         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12545         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12546         lctl set_param fail_loc=0x40d
12547         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12548         pid_dio=$!
12549         sleep 1
12550         cat $DIR/$tfile > /dev/null &
12551         lctl set_param fail_loc=0
12552         pid_reads=$!
12553         wait $pid_dio
12554         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12555         sleep 2
12556         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12557         error "the read rpcs have not completed in 2s"
12558         rm -f $DIR/$tfile
12559         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12560 }
12561 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12562
12563 test_120a() {
12564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12565         remote_mds_nodsh && skip "remote MDS with nodsh"
12566         test_mkdir -i0 -c1 $DIR/$tdir
12567         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12568                 skip_env "no early lock cancel on server"
12569
12570         lru_resize_disable mdc
12571         lru_resize_disable osc
12572         cancel_lru_locks mdc
12573         # asynchronous object destroy at MDT could cause bl ast to client
12574         cancel_lru_locks osc
12575
12576         stat $DIR/$tdir > /dev/null
12577         can1=$(do_facet mds1 \
12578                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12579                awk '/ldlm_cancel/ {print $2}')
12580         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12581                awk '/ldlm_bl_callback/ {print $2}')
12582         test_mkdir -i0 -c1 $DIR/$tdir/d1
12583         can2=$(do_facet mds1 \
12584                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12585                awk '/ldlm_cancel/ {print $2}')
12586         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12587                awk '/ldlm_bl_callback/ {print $2}')
12588         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12589         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12590         lru_resize_enable mdc
12591         lru_resize_enable osc
12592 }
12593 run_test 120a "Early Lock Cancel: mkdir test"
12594
12595 test_120b() {
12596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12597         remote_mds_nodsh && skip "remote MDS with nodsh"
12598         test_mkdir $DIR/$tdir
12599         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12600                 skip_env "no early lock cancel on server"
12601
12602         lru_resize_disable mdc
12603         lru_resize_disable osc
12604         cancel_lru_locks mdc
12605         stat $DIR/$tdir > /dev/null
12606         can1=$(do_facet $SINGLEMDS \
12607                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12608                awk '/ldlm_cancel/ {print $2}')
12609         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12610                awk '/ldlm_bl_callback/ {print $2}')
12611         touch $DIR/$tdir/f1
12612         can2=$(do_facet $SINGLEMDS \
12613                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12614                awk '/ldlm_cancel/ {print $2}')
12615         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12616                awk '/ldlm_bl_callback/ {print $2}')
12617         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12618         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12619         lru_resize_enable mdc
12620         lru_resize_enable osc
12621 }
12622 run_test 120b "Early Lock Cancel: create test"
12623
12624 test_120c() {
12625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12626         remote_mds_nodsh && skip "remote MDS with nodsh"
12627         test_mkdir -i0 -c1 $DIR/$tdir
12628         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12629                 skip "no early lock cancel on server"
12630
12631         lru_resize_disable mdc
12632         lru_resize_disable osc
12633         test_mkdir -i0 -c1 $DIR/$tdir/d1
12634         test_mkdir -i0 -c1 $DIR/$tdir/d2
12635         touch $DIR/$tdir/d1/f1
12636         cancel_lru_locks mdc
12637         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12638         can1=$(do_facet mds1 \
12639                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12640                awk '/ldlm_cancel/ {print $2}')
12641         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12642                awk '/ldlm_bl_callback/ {print $2}')
12643         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12644         can2=$(do_facet mds1 \
12645                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12646                awk '/ldlm_cancel/ {print $2}')
12647         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12648                awk '/ldlm_bl_callback/ {print $2}')
12649         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12650         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12651         lru_resize_enable mdc
12652         lru_resize_enable osc
12653 }
12654 run_test 120c "Early Lock Cancel: link test"
12655
12656 test_120d() {
12657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12658         remote_mds_nodsh && skip "remote MDS with nodsh"
12659         test_mkdir -i0 -c1 $DIR/$tdir
12660         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12661                 skip_env "no early lock cancel on server"
12662
12663         lru_resize_disable mdc
12664         lru_resize_disable osc
12665         touch $DIR/$tdir
12666         cancel_lru_locks mdc
12667         stat $DIR/$tdir > /dev/null
12668         can1=$(do_facet mds1 \
12669                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12670                awk '/ldlm_cancel/ {print $2}')
12671         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12672                awk '/ldlm_bl_callback/ {print $2}')
12673         chmod a+x $DIR/$tdir
12674         can2=$(do_facet mds1 \
12675                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12676                awk '/ldlm_cancel/ {print $2}')
12677         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12678                awk '/ldlm_bl_callback/ {print $2}')
12679         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12680         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12681         lru_resize_enable mdc
12682         lru_resize_enable osc
12683 }
12684 run_test 120d "Early Lock Cancel: setattr test"
12685
12686 test_120e() {
12687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12688         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12689                 skip_env "no early lock cancel on server"
12690         remote_mds_nodsh && skip "remote MDS with nodsh"
12691
12692         local dlmtrace_set=false
12693
12694         test_mkdir -i0 -c1 $DIR/$tdir
12695         lru_resize_disable mdc
12696         lru_resize_disable osc
12697         ! $LCTL get_param debug | grep -q dlmtrace &&
12698                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12699         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12700         cancel_lru_locks mdc
12701         cancel_lru_locks osc
12702         dd if=$DIR/$tdir/f1 of=/dev/null
12703         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12704         # XXX client can not do early lock cancel of OST lock
12705         # during unlink (LU-4206), so cancel osc lock now.
12706         sleep 2
12707         cancel_lru_locks osc
12708         can1=$(do_facet mds1 \
12709                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12710                awk '/ldlm_cancel/ {print $2}')
12711         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12712                awk '/ldlm_bl_callback/ {print $2}')
12713         unlink $DIR/$tdir/f1
12714         sleep 5
12715         can2=$(do_facet mds1 \
12716                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12717                awk '/ldlm_cancel/ {print $2}')
12718         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12719                awk '/ldlm_bl_callback/ {print $2}')
12720         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12721                 $LCTL dk $TMP/cancel.debug.txt
12722         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12723                 $LCTL dk $TMP/blocking.debug.txt
12724         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12725         lru_resize_enable mdc
12726         lru_resize_enable osc
12727 }
12728 run_test 120e "Early Lock Cancel: unlink test"
12729
12730 test_120f() {
12731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12732         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12733                 skip_env "no early lock cancel on server"
12734         remote_mds_nodsh && skip "remote MDS with nodsh"
12735
12736         test_mkdir -i0 -c1 $DIR/$tdir
12737         lru_resize_disable mdc
12738         lru_resize_disable osc
12739         test_mkdir -i0 -c1 $DIR/$tdir/d1
12740         test_mkdir -i0 -c1 $DIR/$tdir/d2
12741         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12742         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12743         cancel_lru_locks mdc
12744         cancel_lru_locks osc
12745         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12746         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12747         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12748         # XXX client can not do early lock cancel of OST lock
12749         # during rename (LU-4206), so cancel osc lock now.
12750         sleep 2
12751         cancel_lru_locks osc
12752         can1=$(do_facet mds1 \
12753                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12754                awk '/ldlm_cancel/ {print $2}')
12755         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12756                awk '/ldlm_bl_callback/ {print $2}')
12757         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12758         sleep 5
12759         can2=$(do_facet mds1 \
12760                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12761                awk '/ldlm_cancel/ {print $2}')
12762         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12763                awk '/ldlm_bl_callback/ {print $2}')
12764         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12765         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12766         lru_resize_enable mdc
12767         lru_resize_enable osc
12768 }
12769 run_test 120f "Early Lock Cancel: rename test"
12770
12771 test_120g() {
12772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12773         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12774                 skip_env "no early lock cancel on server"
12775         remote_mds_nodsh && skip "remote MDS with nodsh"
12776
12777         lru_resize_disable mdc
12778         lru_resize_disable osc
12779         count=10000
12780         echo create $count files
12781         test_mkdir $DIR/$tdir
12782         cancel_lru_locks mdc
12783         cancel_lru_locks osc
12784         t0=$(date +%s)
12785
12786         can0=$(do_facet $SINGLEMDS \
12787                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12788                awk '/ldlm_cancel/ {print $2}')
12789         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12790                awk '/ldlm_bl_callback/ {print $2}')
12791         createmany -o $DIR/$tdir/f $count
12792         sync
12793         can1=$(do_facet $SINGLEMDS \
12794                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12795                awk '/ldlm_cancel/ {print $2}')
12796         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12797                awk '/ldlm_bl_callback/ {print $2}')
12798         t1=$(date +%s)
12799         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12800         echo rm $count files
12801         rm -r $DIR/$tdir
12802         sync
12803         can2=$(do_facet $SINGLEMDS \
12804                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12805                awk '/ldlm_cancel/ {print $2}')
12806         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12807                awk '/ldlm_bl_callback/ {print $2}')
12808         t2=$(date +%s)
12809         echo total: $count removes in $((t2-t1))
12810         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12811         sleep 2
12812         # wait for commitment of removal
12813         lru_resize_enable mdc
12814         lru_resize_enable osc
12815 }
12816 run_test 120g "Early Lock Cancel: performance test"
12817
12818 test_121() { #bug #10589
12819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12820
12821         rm -rf $DIR/$tfile
12822         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12823 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12824         lctl set_param fail_loc=0x310
12825         cancel_lru_locks osc > /dev/null
12826         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12827         lctl set_param fail_loc=0
12828         [[ $reads -eq $writes ]] ||
12829                 error "read $reads blocks, must be $writes blocks"
12830 }
12831 run_test 121 "read cancel race ========="
12832
12833 test_123a_base() { # was test 123, statahead(bug 11401)
12834         local lsx="$1"
12835
12836         SLOWOK=0
12837         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12838                 log "testing UP system. Performance may be lower than expected."
12839                 SLOWOK=1
12840         fi
12841
12842         rm -rf $DIR/$tdir
12843         test_mkdir $DIR/$tdir
12844         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12845         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12846         MULT=10
12847         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12848                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12849
12850                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12851                 lctl set_param -n llite.*.statahead_max 0
12852                 lctl get_param llite.*.statahead_max
12853                 cancel_lru_locks mdc
12854                 cancel_lru_locks osc
12855                 stime=$(date +%s)
12856                 time $lsx $DIR/$tdir | wc -l
12857                 etime=$(date +%s)
12858                 delta=$((etime - stime))
12859                 log "$lsx $i files without statahead: $delta sec"
12860                 lctl set_param llite.*.statahead_max=$max
12861
12862                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12863                         grep "statahead wrong:" | awk '{print $3}')
12864                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12865                 cancel_lru_locks mdc
12866                 cancel_lru_locks osc
12867                 stime=$(date +%s)
12868                 time $lsx $DIR/$tdir | wc -l
12869                 etime=$(date +%s)
12870                 delta_sa=$((etime - stime))
12871                 log "$lsx $i files with statahead: $delta_sa sec"
12872                 lctl get_param -n llite.*.statahead_stats
12873                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12874                         grep "statahead wrong:" | awk '{print $3}')
12875
12876                 [[ $swrong -lt $ewrong ]] &&
12877                         log "statahead was stopped, maybe too many locks held!"
12878                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12879
12880                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12881                         max=$(lctl get_param -n llite.*.statahead_max |
12882                                 head -n 1)
12883                         lctl set_param -n llite.*.statahead_max 0
12884                         lctl get_param llite.*.statahead_max
12885                         cancel_lru_locks mdc
12886                         cancel_lru_locks osc
12887                         stime=$(date +%s)
12888                         time $lsx $DIR/$tdir | wc -l
12889                         etime=$(date +%s)
12890                         delta=$((etime - stime))
12891                         log "$lsx $i files again without statahead: $delta sec"
12892                         lctl set_param llite.*.statahead_max=$max
12893                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12894                                 if [  $SLOWOK -eq 0 ]; then
12895                                         error "$lsx $i files is slower with statahead!"
12896                                 else
12897                                         log "$lsx $i files is slower with statahead!"
12898                                 fi
12899                                 break
12900                         fi
12901                 fi
12902
12903                 [ $delta -gt 20 ] && break
12904                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12905                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12906         done
12907         log "$lsx done"
12908
12909         stime=$(date +%s)
12910         rm -r $DIR/$tdir
12911         sync
12912         etime=$(date +%s)
12913         delta=$((etime - stime))
12914         log "rm -r $DIR/$tdir/: $delta seconds"
12915         log "rm done"
12916         lctl get_param -n llite.*.statahead_stats
12917 }
12918
12919 test_123aa() {
12920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12921
12922         test_123a_base "ls -l"
12923 }
12924 run_test 123aa "verify statahead work"
12925
12926 test_123ab() {
12927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12928
12929         statx_supported || skip_env "Test must be statx() syscall supported"
12930
12931         test_123a_base "$STATX -l"
12932 }
12933 run_test 123ab "verify statahead work by using statx"
12934
12935 test_123ac() {
12936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12937
12938         statx_supported || skip_env "Test must be statx() syscall supported"
12939
12940         local rpcs_before
12941         local rpcs_after
12942         local agl_before
12943         local agl_after
12944
12945         cancel_lru_locks $OSC
12946         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12947         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12948                 awk '/agl.total:/ {print $3}')
12949         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12950         test_123a_base "$STATX --cached=always -D"
12951         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12952                 awk '/agl.total:/ {print $3}')
12953         [ $agl_before -eq $agl_after ] ||
12954                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12955         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12956         [ $rpcs_after -eq $rpcs_before ] ||
12957                 error "$STATX should not send glimpse RPCs to $OSC"
12958 }
12959 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12960
12961 test_123b () { # statahead(bug 15027)
12962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12963
12964         test_mkdir $DIR/$tdir
12965         createmany -o $DIR/$tdir/$tfile-%d 1000
12966
12967         cancel_lru_locks mdc
12968         cancel_lru_locks osc
12969
12970 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12971         lctl set_param fail_loc=0x80000803
12972         ls -lR $DIR/$tdir > /dev/null
12973         log "ls done"
12974         lctl set_param fail_loc=0x0
12975         lctl get_param -n llite.*.statahead_stats
12976         rm -r $DIR/$tdir
12977         sync
12978
12979 }
12980 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12981
12982 test_123c() {
12983         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12984
12985         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12986         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12987         touch $DIR/$tdir.1/{1..3}
12988         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12989
12990         remount_client $MOUNT
12991
12992         $MULTIOP $DIR/$tdir.0 Q
12993
12994         # let statahead to complete
12995         ls -l $DIR/$tdir.0 > /dev/null
12996
12997         testid=$(echo $TESTNAME | tr '_' ' ')
12998         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12999                 error "statahead warning" || true
13000 }
13001 run_test 123c "Can not initialize inode warning on DNE statahead"
13002
13003 test_124a() {
13004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13005         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13006                 skip_env "no lru resize on server"
13007
13008         local NR=2000
13009
13010         test_mkdir $DIR/$tdir
13011
13012         log "create $NR files at $DIR/$tdir"
13013         createmany -o $DIR/$tdir/f $NR ||
13014                 error "failed to create $NR files in $DIR/$tdir"
13015
13016         cancel_lru_locks mdc
13017         ls -l $DIR/$tdir > /dev/null
13018
13019         local NSDIR=""
13020         local LRU_SIZE=0
13021         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13022                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13023                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13024                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13025                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13026                         log "NSDIR=$NSDIR"
13027                         log "NS=$(basename $NSDIR)"
13028                         break
13029                 fi
13030         done
13031
13032         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13033                 skip "Not enough cached locks created!"
13034         fi
13035         log "LRU=$LRU_SIZE"
13036
13037         local SLEEP=30
13038
13039         # We know that lru resize allows one client to hold $LIMIT locks
13040         # for 10h. After that locks begin to be killed by client.
13041         local MAX_HRS=10
13042         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13043         log "LIMIT=$LIMIT"
13044         if [ $LIMIT -lt $LRU_SIZE ]; then
13045                 skip "Limit is too small $LIMIT"
13046         fi
13047
13048         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13049         # killing locks. Some time was spent for creating locks. This means
13050         # that up to the moment of sleep finish we must have killed some of
13051         # them (10-100 locks). This depends on how fast ther were created.
13052         # Many of them were touched in almost the same moment and thus will
13053         # be killed in groups.
13054         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13055
13056         # Use $LRU_SIZE_B here to take into account real number of locks
13057         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13058         local LRU_SIZE_B=$LRU_SIZE
13059         log "LVF=$LVF"
13060         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13061         log "OLD_LVF=$OLD_LVF"
13062         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13063
13064         # Let's make sure that we really have some margin. Client checks
13065         # cached locks every 10 sec.
13066         SLEEP=$((SLEEP+20))
13067         log "Sleep ${SLEEP} sec"
13068         local SEC=0
13069         while ((SEC<$SLEEP)); do
13070                 echo -n "..."
13071                 sleep 5
13072                 SEC=$((SEC+5))
13073                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13074                 echo -n "$LRU_SIZE"
13075         done
13076         echo ""
13077         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13078         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13079
13080         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13081                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13082                 unlinkmany $DIR/$tdir/f $NR
13083                 return
13084         }
13085
13086         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13087         log "unlink $NR files at $DIR/$tdir"
13088         unlinkmany $DIR/$tdir/f $NR
13089 }
13090 run_test 124a "lru resize ======================================="
13091
13092 get_max_pool_limit()
13093 {
13094         local limit=$($LCTL get_param \
13095                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13096         local max=0
13097         for l in $limit; do
13098                 if [[ $l -gt $max ]]; then
13099                         max=$l
13100                 fi
13101         done
13102         echo $max
13103 }
13104
13105 test_124b() {
13106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13107         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13108                 skip_env "no lru resize on server"
13109
13110         LIMIT=$(get_max_pool_limit)
13111
13112         NR=$(($(default_lru_size)*20))
13113         if [[ $NR -gt $LIMIT ]]; then
13114                 log "Limit lock number by $LIMIT locks"
13115                 NR=$LIMIT
13116         fi
13117
13118         IFree=$(mdsrate_inodes_available)
13119         if [ $IFree -lt $NR ]; then
13120                 log "Limit lock number by $IFree inodes"
13121                 NR=$IFree
13122         fi
13123
13124         lru_resize_disable mdc
13125         test_mkdir -p $DIR/$tdir/disable_lru_resize
13126
13127         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13128         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13129         cancel_lru_locks mdc
13130         stime=`date +%s`
13131         PID=""
13132         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13133         PID="$PID $!"
13134         sleep 2
13135         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13136         PID="$PID $!"
13137         sleep 2
13138         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13139         PID="$PID $!"
13140         wait $PID
13141         etime=`date +%s`
13142         nolruresize_delta=$((etime-stime))
13143         log "ls -la time: $nolruresize_delta seconds"
13144         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13145         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13146
13147         lru_resize_enable mdc
13148         test_mkdir -p $DIR/$tdir/enable_lru_resize
13149
13150         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13151         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13152         cancel_lru_locks mdc
13153         stime=`date +%s`
13154         PID=""
13155         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13156         PID="$PID $!"
13157         sleep 2
13158         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13159         PID="$PID $!"
13160         sleep 2
13161         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13162         PID="$PID $!"
13163         wait $PID
13164         etime=`date +%s`
13165         lruresize_delta=$((etime-stime))
13166         log "ls -la time: $lruresize_delta seconds"
13167         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13168
13169         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13170                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13171         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13172                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13173         else
13174                 log "lru resize performs the same with no lru resize"
13175         fi
13176         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13177 }
13178 run_test 124b "lru resize (performance test) ======================="
13179
13180 test_124c() {
13181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13182         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13183                 skip_env "no lru resize on server"
13184
13185         # cache ununsed locks on client
13186         local nr=100
13187         cancel_lru_locks mdc
13188         test_mkdir $DIR/$tdir
13189         createmany -o $DIR/$tdir/f $nr ||
13190                 error "failed to create $nr files in $DIR/$tdir"
13191         ls -l $DIR/$tdir > /dev/null
13192
13193         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13194         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13195         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13196         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13197         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13198
13199         # set lru_max_age to 1 sec
13200         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13201         echo "sleep $((recalc_p * 2)) seconds..."
13202         sleep $((recalc_p * 2))
13203
13204         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13205         # restore lru_max_age
13206         $LCTL set_param -n $nsdir.lru_max_age $max_age
13207         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13208         unlinkmany $DIR/$tdir/f $nr
13209 }
13210 run_test 124c "LRUR cancel very aged locks"
13211
13212 test_124d() {
13213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13214         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13215                 skip_env "no lru resize on server"
13216
13217         # cache ununsed locks on client
13218         local nr=100
13219
13220         lru_resize_disable mdc
13221         stack_trap "lru_resize_enable mdc" EXIT
13222
13223         cancel_lru_locks mdc
13224
13225         # asynchronous object destroy at MDT could cause bl ast to client
13226         test_mkdir $DIR/$tdir
13227         createmany -o $DIR/$tdir/f $nr ||
13228                 error "failed to create $nr files in $DIR/$tdir"
13229         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13230
13231         ls -l $DIR/$tdir > /dev/null
13232
13233         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13234         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13235         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13236         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13237
13238         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13239
13240         # set lru_max_age to 1 sec
13241         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13242         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13243
13244         echo "sleep $((recalc_p * 2)) seconds..."
13245         sleep $((recalc_p * 2))
13246
13247         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13248
13249         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13250 }
13251 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13252
13253 test_125() { # 13358
13254         $LCTL get_param -n llite.*.client_type | grep -q local ||
13255                 skip "must run as local client"
13256         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13257                 skip_env "must have acl enabled"
13258         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13259
13260         test_mkdir $DIR/$tdir
13261         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13262         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13263         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13264 }
13265 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13266
13267 test_126() { # bug 12829/13455
13268         $GSS && skip_env "must run as gss disabled"
13269         $LCTL get_param -n llite.*.client_type | grep -q local ||
13270                 skip "must run as local client"
13271         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13272
13273         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13274         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13275         rm -f $DIR/$tfile
13276         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13277 }
13278 run_test 126 "check that the fsgid provided by the client is taken into account"
13279
13280 test_127a() { # bug 15521
13281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13282         local name count samp unit min max sum sumsq
13283
13284         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13285         echo "stats before reset"
13286         $LCTL get_param osc.*.stats
13287         $LCTL set_param osc.*.stats=0
13288         local fsize=$((2048 * 1024))
13289
13290         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13291         cancel_lru_locks osc
13292         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13293
13294         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13295         stack_trap "rm -f $TMP/$tfile.tmp"
13296         while read name count samp unit min max sum sumsq; do
13297                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13298                 [ ! $min ] && error "Missing min value for $name proc entry"
13299                 eval $name=$count || error "Wrong proc format"
13300
13301                 case $name in
13302                 read_bytes|write_bytes)
13303                         [[ "$unit" =~ "bytes" ]] ||
13304                                 error "unit is not 'bytes': $unit"
13305                         (( $min >= 4096 )) || error "min is too small: $min"
13306                         (( $min <= $fsize )) || error "min is too big: $min"
13307                         (( $max >= 4096 )) || error "max is too small: $max"
13308                         (( $max <= $fsize )) || error "max is too big: $max"
13309                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13310                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13311                                 error "sumsquare is too small: $sumsq"
13312                         (( $sumsq <= $fsize * $fsize )) ||
13313                                 error "sumsquare is too big: $sumsq"
13314                         ;;
13315                 ost_read|ost_write)
13316                         [[ "$unit" =~ "usec" ]] ||
13317                                 error "unit is not 'usec': $unit"
13318                         ;;
13319                 *)      ;;
13320                 esac
13321         done < $DIR/$tfile.tmp
13322
13323         #check that we actually got some stats
13324         [ "$read_bytes" ] || error "Missing read_bytes stats"
13325         [ "$write_bytes" ] || error "Missing write_bytes stats"
13326         [ "$read_bytes" != 0 ] || error "no read done"
13327         [ "$write_bytes" != 0 ] || error "no write done"
13328 }
13329 run_test 127a "verify the client stats are sane"
13330
13331 test_127b() { # bug LU-333
13332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13333         local name count samp unit min max sum sumsq
13334
13335         echo "stats before reset"
13336         $LCTL get_param llite.*.stats
13337         $LCTL set_param llite.*.stats=0
13338
13339         # perform 2 reads and writes so MAX is different from SUM.
13340         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13341         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13342         cancel_lru_locks osc
13343         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13344         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13345
13346         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13347         stack_trap "rm -f $TMP/$tfile.tmp"
13348         while read name count samp unit min max sum sumsq; do
13349                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13350                 eval $name=$count || error "Wrong proc format"
13351
13352                 case $name in
13353                 read_bytes|write_bytes)
13354                         [[ "$unit" =~ "bytes" ]] ||
13355                                 error "unit is not 'bytes': $unit"
13356                         (( $count == 2 )) || error "count is not 2: $count"
13357                         (( $min == $PAGE_SIZE )) ||
13358                                 error "min is not $PAGE_SIZE: $min"
13359                         (( $max == $PAGE_SIZE )) ||
13360                                 error "max is not $PAGE_SIZE: $max"
13361                         (( $sum == $PAGE_SIZE * 2 )) ||
13362                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13363                         ;;
13364                 read|write)
13365                         [[ "$unit" =~ "usec" ]] ||
13366                                 error "unit is not 'usec': $unit"
13367                         ;;
13368                 *)      ;;
13369                 esac
13370         done < $TMP/$tfile.tmp
13371
13372         #check that we actually got some stats
13373         [ "$read_bytes" ] || error "Missing read_bytes stats"
13374         [ "$write_bytes" ] || error "Missing write_bytes stats"
13375         [ "$read_bytes" != 0 ] || error "no read done"
13376         [ "$write_bytes" != 0 ] || error "no write done"
13377 }
13378 run_test 127b "verify the llite client stats are sane"
13379
13380 test_127c() { # LU-12394
13381         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13382         local size
13383         local bsize
13384         local reads
13385         local writes
13386         local count
13387
13388         $LCTL set_param llite.*.extents_stats=1
13389         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13390
13391         # Use two stripes so there is enough space in default config
13392         $LFS setstripe -c 2 $DIR/$tfile
13393
13394         # Extent stats start at 0-4K and go in power of two buckets
13395         # LL_HIST_START = 12 --> 2^12 = 4K
13396         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13397         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13398         # small configs
13399         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13400                 do
13401                 # Write and read, 2x each, second time at a non-zero offset
13402                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13403                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13404                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13405                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13406                 rm -f $DIR/$tfile
13407         done
13408
13409         $LCTL get_param llite.*.extents_stats
13410
13411         count=2
13412         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13413                 do
13414                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13415                                 grep -m 1 $bsize)
13416                 reads=$(echo $bucket | awk '{print $5}')
13417                 writes=$(echo $bucket | awk '{print $9}')
13418                 [ "$reads" -eq $count ] ||
13419                         error "$reads reads in < $bsize bucket, expect $count"
13420                 [ "$writes" -eq $count ] ||
13421                         error "$writes writes in < $bsize bucket, expect $count"
13422         done
13423
13424         # Test mmap write and read
13425         $LCTL set_param llite.*.extents_stats=c
13426         size=512
13427         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13428         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13429         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13430
13431         $LCTL get_param llite.*.extents_stats
13432
13433         count=$(((size*1024) / PAGE_SIZE))
13434
13435         bsize=$((2 * PAGE_SIZE / 1024))K
13436
13437         bucket=$($LCTL get_param -n llite.*.extents_stats |
13438                         grep -m 1 $bsize)
13439         reads=$(echo $bucket | awk '{print $5}')
13440         writes=$(echo $bucket | awk '{print $9}')
13441         # mmap writes fault in the page first, creating an additonal read
13442         [ "$reads" -eq $((2 * count)) ] ||
13443                 error "$reads reads in < $bsize bucket, expect $count"
13444         [ "$writes" -eq $count ] ||
13445                 error "$writes writes in < $bsize bucket, expect $count"
13446 }
13447 run_test 127c "test llite extent stats with regular & mmap i/o"
13448
13449 test_128() { # bug 15212
13450         touch $DIR/$tfile
13451         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13452                 find $DIR/$tfile
13453                 find $DIR/$tfile
13454         EOF
13455
13456         result=$(grep error $TMP/$tfile.log)
13457         rm -f $DIR/$tfile $TMP/$tfile.log
13458         [ -z "$result" ] ||
13459                 error "consecutive find's under interactive lfs failed"
13460 }
13461 run_test 128 "interactive lfs for 2 consecutive find's"
13462
13463 set_dir_limits () {
13464         local mntdev
13465         local canondev
13466         local node
13467
13468         local ldproc=/proc/fs/ldiskfs
13469         local facets=$(get_facets MDS)
13470
13471         for facet in ${facets//,/ }; do
13472                 canondev=$(ldiskfs_canon \
13473                            *.$(convert_facet2label $facet).mntdev $facet)
13474                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13475                         ldproc=/sys/fs/ldiskfs
13476                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13477                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13478         done
13479 }
13480
13481 check_mds_dmesg() {
13482         local facets=$(get_facets MDS)
13483         for facet in ${facets//,/ }; do
13484                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13485         done
13486         return 1
13487 }
13488
13489 test_129() {
13490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13491         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13492                 skip "Need MDS version with at least 2.5.56"
13493         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13494                 skip_env "ldiskfs only test"
13495         fi
13496         remote_mds_nodsh && skip "remote MDS with nodsh"
13497
13498         local ENOSPC=28
13499         local has_warning=false
13500
13501         rm -rf $DIR/$tdir
13502         mkdir -p $DIR/$tdir
13503
13504         # block size of mds1
13505         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13506         set_dir_limits $maxsize $((maxsize * 6 / 8))
13507         stack_trap "set_dir_limits 0 0"
13508         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13509         local dirsize=$(stat -c%s "$DIR/$tdir")
13510         local nfiles=0
13511         while (( $dirsize <= $maxsize )); do
13512                 $MCREATE $DIR/$tdir/file_base_$nfiles
13513                 rc=$?
13514                 # check two errors:
13515                 # ENOSPC for ext4 max_dir_size, which has been used since
13516                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13517                 if (( rc == ENOSPC )); then
13518                         set_dir_limits 0 0
13519                         echo "rc=$rc returned as expected after $nfiles files"
13520
13521                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13522                                 error "create failed w/o dir size limit"
13523
13524                         # messages may be rate limited if test is run repeatedly
13525                         check_mds_dmesg '"is approaching max"' ||
13526                                 echo "warning message should be output"
13527                         check_mds_dmesg '"has reached max"' ||
13528                                 echo "reached message should be output"
13529
13530                         dirsize=$(stat -c%s "$DIR/$tdir")
13531
13532                         [[ $dirsize -ge $maxsize ]] && return 0
13533                         error "dirsize $dirsize < $maxsize after $nfiles files"
13534                 elif (( rc != 0 )); then
13535                         break
13536                 fi
13537                 nfiles=$((nfiles + 1))
13538                 dirsize=$(stat -c%s "$DIR/$tdir")
13539         done
13540
13541         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13542 }
13543 run_test 129 "test directory size limit ========================"
13544
13545 OLDIFS="$IFS"
13546 cleanup_130() {
13547         trap 0
13548         IFS="$OLDIFS"
13549 }
13550
13551 test_130a() {
13552         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13553         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13554
13555         trap cleanup_130 EXIT RETURN
13556
13557         local fm_file=$DIR/$tfile
13558         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13559         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13560                 error "dd failed for $fm_file"
13561
13562         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13563         filefrag -ves $fm_file
13564         RC=$?
13565         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13566                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13567         [ $RC != 0 ] && error "filefrag $fm_file failed"
13568
13569         filefrag_op=$(filefrag -ve -k $fm_file |
13570                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13571         lun=$($LFS getstripe -i $fm_file)
13572
13573         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13574         IFS=$'\n'
13575         tot_len=0
13576         for line in $filefrag_op
13577         do
13578                 frag_lun=`echo $line | cut -d: -f5`
13579                 ext_len=`echo $line | cut -d: -f4`
13580                 if (( $frag_lun != $lun )); then
13581                         cleanup_130
13582                         error "FIEMAP on 1-stripe file($fm_file) failed"
13583                         return
13584                 fi
13585                 (( tot_len += ext_len ))
13586         done
13587
13588         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13589                 cleanup_130
13590                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13591                 return
13592         fi
13593
13594         cleanup_130
13595
13596         echo "FIEMAP on single striped file succeeded"
13597 }
13598 run_test 130a "FIEMAP (1-stripe file)"
13599
13600 test_130b() {
13601         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13602
13603         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13604         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13605
13606         trap cleanup_130 EXIT RETURN
13607
13608         local fm_file=$DIR/$tfile
13609         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13610                         error "setstripe on $fm_file"
13611         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13612                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13613
13614         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13615                 error "dd failed on $fm_file"
13616
13617         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13618         filefrag_op=$(filefrag -ve -k $fm_file |
13619                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13620
13621         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13622                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13623
13624         IFS=$'\n'
13625         tot_len=0
13626         num_luns=1
13627         for line in $filefrag_op
13628         do
13629                 frag_lun=$(echo $line | cut -d: -f5 |
13630                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13631                 ext_len=$(echo $line | cut -d: -f4)
13632                 if (( $frag_lun != $last_lun )); then
13633                         if (( tot_len != 1024 )); then
13634                                 cleanup_130
13635                                 error "FIEMAP on $fm_file failed; returned " \
13636                                 "len $tot_len for OST $last_lun instead of 1024"
13637                                 return
13638                         else
13639                                 (( num_luns += 1 ))
13640                                 tot_len=0
13641                         fi
13642                 fi
13643                 (( tot_len += ext_len ))
13644                 last_lun=$frag_lun
13645         done
13646         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13647                 cleanup_130
13648                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13649                         "luns or wrong len for OST $last_lun"
13650                 return
13651         fi
13652
13653         cleanup_130
13654
13655         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13656 }
13657 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13658
13659 test_130c() {
13660         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13661
13662         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13663         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13664
13665         trap cleanup_130 EXIT RETURN
13666
13667         local fm_file=$DIR/$tfile
13668         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13669         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13670                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13671
13672         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13673                         error "dd failed on $fm_file"
13674
13675         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13676         filefrag_op=$(filefrag -ve -k $fm_file |
13677                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13678
13679         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13680                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13681
13682         IFS=$'\n'
13683         tot_len=0
13684         num_luns=1
13685         for line in $filefrag_op
13686         do
13687                 frag_lun=$(echo $line | cut -d: -f5 |
13688                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13689                 ext_len=$(echo $line | cut -d: -f4)
13690                 if (( $frag_lun != $last_lun )); then
13691                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13692                         if (( logical != 512 )); then
13693                                 cleanup_130
13694                                 error "FIEMAP on $fm_file failed; returned " \
13695                                 "logical start for lun $logical instead of 512"
13696                                 return
13697                         fi
13698                         if (( tot_len != 512 )); then
13699                                 cleanup_130
13700                                 error "FIEMAP on $fm_file failed; returned " \
13701                                 "len $tot_len for OST $last_lun instead of 1024"
13702                                 return
13703                         else
13704                                 (( num_luns += 1 ))
13705                                 tot_len=0
13706                         fi
13707                 fi
13708                 (( tot_len += ext_len ))
13709                 last_lun=$frag_lun
13710         done
13711         if (( num_luns != 2 || tot_len != 512 )); then
13712                 cleanup_130
13713                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13714                         "luns or wrong len for OST $last_lun"
13715                 return
13716         fi
13717
13718         cleanup_130
13719
13720         echo "FIEMAP on 2-stripe file with hole succeeded"
13721 }
13722 run_test 130c "FIEMAP (2-stripe file with hole)"
13723
13724 test_130d() {
13725         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13726
13727         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13728         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13729
13730         trap cleanup_130 EXIT RETURN
13731
13732         local fm_file=$DIR/$tfile
13733         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13734                         error "setstripe on $fm_file"
13735         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13736                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13737
13738         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13739         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13740                 error "dd failed on $fm_file"
13741
13742         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13743         filefrag_op=$(filefrag -ve -k $fm_file |
13744                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13745
13746         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13747                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13748
13749         IFS=$'\n'
13750         tot_len=0
13751         num_luns=1
13752         for line in $filefrag_op
13753         do
13754                 frag_lun=$(echo $line | cut -d: -f5 |
13755                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13756                 ext_len=$(echo $line | cut -d: -f4)
13757                 if (( $frag_lun != $last_lun )); then
13758                         if (( tot_len != 1024 )); then
13759                                 cleanup_130
13760                                 error "FIEMAP on $fm_file failed; returned " \
13761                                 "len $tot_len for OST $last_lun instead of 1024"
13762                                 return
13763                         else
13764                                 (( num_luns += 1 ))
13765                                 tot_len=0
13766                         fi
13767                 fi
13768                 (( tot_len += ext_len ))
13769                 last_lun=$frag_lun
13770         done
13771         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13772                 cleanup_130
13773                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13774                         "luns or wrong len for OST $last_lun"
13775                 return
13776         fi
13777
13778         cleanup_130
13779
13780         echo "FIEMAP on N-stripe file succeeded"
13781 }
13782 run_test 130d "FIEMAP (N-stripe file)"
13783
13784 test_130e() {
13785         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13786
13787         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13788         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13789
13790         trap cleanup_130 EXIT RETURN
13791
13792         local fm_file=$DIR/$tfile
13793         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13794
13795         NUM_BLKS=512
13796         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13797         for ((i = 0; i < $NUM_BLKS; i++)); do
13798                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13799                         conv=notrunc > /dev/null 2>&1
13800         done
13801
13802         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13803         filefrag_op=$(filefrag -ve -k $fm_file |
13804                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13805
13806         last_lun=$(echo $filefrag_op | cut -d: -f5)
13807
13808         IFS=$'\n'
13809         tot_len=0
13810         num_luns=1
13811         for line in $filefrag_op; do
13812                 frag_lun=$(echo $line | cut -d: -f5)
13813                 ext_len=$(echo $line | cut -d: -f4)
13814                 if [[ "$frag_lun" != "$last_lun" ]]; then
13815                         if (( tot_len != $EXPECTED_LEN )); then
13816                                 cleanup_130
13817                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13818                         else
13819                                 (( num_luns += 1 ))
13820                                 tot_len=0
13821                         fi
13822                 fi
13823                 (( tot_len += ext_len ))
13824                 last_lun=$frag_lun
13825         done
13826         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13827                 cleanup_130
13828                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13829         fi
13830
13831         echo "FIEMAP with continuation calls succeeded"
13832 }
13833 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13834
13835 test_130f() {
13836         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13837         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13838
13839         local fm_file=$DIR/$tfile
13840         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13841                 error "multiop create with lov_delay_create on $fm_file"
13842
13843         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13844         filefrag_extents=$(filefrag -vek $fm_file |
13845                            awk '/extents? found/ { print $2 }')
13846         if [[ "$filefrag_extents" != "0" ]]; then
13847                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13848         fi
13849
13850         rm -f $fm_file
13851 }
13852 run_test 130f "FIEMAP (unstriped file)"
13853
13854 test_130g() {
13855         local file=$DIR/$tfile
13856         local nr=$((OSTCOUNT * 100))
13857
13858         $LFS setstripe -C $nr $file ||
13859                 error "failed to setstripe -C $nr $file"
13860
13861         dd if=/dev/zero of=$file count=$nr bs=1M
13862         sync
13863         nr=$($LFS getstripe -c $file)
13864
13865         local extents=$(filefrag -v $file |
13866                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13867
13868         echo "filefrag list $extents extents in file with stripecount $nr"
13869         if (( extents < nr )); then
13870                 $LFS getstripe $file
13871                 filefrag -v $file
13872                 error "filefrag printed $extents < $nr extents"
13873         fi
13874
13875         rm -f $file
13876 }
13877 run_test 130g "FIEMAP (overstripe file)"
13878
13879 # Test for writev/readv
13880 test_131a() {
13881         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13882                 error "writev test failed"
13883         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13884                 error "readv failed"
13885         rm -f $DIR/$tfile
13886 }
13887 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13888
13889 test_131b() {
13890         local fsize=$((524288 + 1048576 + 1572864))
13891         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13892                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13893                         error "append writev test failed"
13894
13895         ((fsize += 1572864 + 1048576))
13896         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13897                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13898                         error "append writev test failed"
13899         rm -f $DIR/$tfile
13900 }
13901 run_test 131b "test append writev"
13902
13903 test_131c() {
13904         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13905         error "NOT PASS"
13906 }
13907 run_test 131c "test read/write on file w/o objects"
13908
13909 test_131d() {
13910         rwv -f $DIR/$tfile -w -n 1 1572864
13911         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13912         if [ "$NOB" != 1572864 ]; then
13913                 error "Short read filed: read $NOB bytes instead of 1572864"
13914         fi
13915         rm -f $DIR/$tfile
13916 }
13917 run_test 131d "test short read"
13918
13919 test_131e() {
13920         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13921         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13922         error "read hitting hole failed"
13923         rm -f $DIR/$tfile
13924 }
13925 run_test 131e "test read hitting hole"
13926
13927 check_stats() {
13928         local facet=$1
13929         local op=$2
13930         local want=${3:-0}
13931         local res
13932
13933         case $facet in
13934         mds*) res=$(do_facet $facet \
13935                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13936                  ;;
13937         ost*) res=$(do_facet $facet \
13938                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13939                  ;;
13940         *) error "Wrong facet '$facet'" ;;
13941         esac
13942         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13943         # if the argument $3 is zero, it means any stat increment is ok.
13944         if [[ $want -gt 0 ]]; then
13945                 local count=$(echo $res | awk '{ print $2 }')
13946                 [[ $count -ne $want ]] &&
13947                         error "The $op counter on $facet is $count, not $want"
13948         fi
13949 }
13950
13951 test_133a() {
13952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13953         remote_ost_nodsh && skip "remote OST with nodsh"
13954         remote_mds_nodsh && skip "remote MDS with nodsh"
13955         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13956                 skip_env "MDS doesn't support rename stats"
13957
13958         local testdir=$DIR/${tdir}/stats_testdir
13959
13960         mkdir -p $DIR/${tdir}
13961
13962         # clear stats.
13963         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13964         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13965
13966         # verify mdt stats first.
13967         mkdir ${testdir} || error "mkdir failed"
13968         check_stats $SINGLEMDS "mkdir" 1
13969         touch ${testdir}/${tfile} || error "touch failed"
13970         check_stats $SINGLEMDS "open" 1
13971         check_stats $SINGLEMDS "close" 1
13972         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13973                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13974                 check_stats $SINGLEMDS "mknod" 2
13975         }
13976         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13977         check_stats $SINGLEMDS "unlink" 1
13978         rm -f ${testdir}/${tfile} || error "file remove failed"
13979         check_stats $SINGLEMDS "unlink" 2
13980
13981         # remove working dir and check mdt stats again.
13982         rmdir ${testdir} || error "rmdir failed"
13983         check_stats $SINGLEMDS "rmdir" 1
13984
13985         local testdir1=$DIR/${tdir}/stats_testdir1
13986         mkdir -p ${testdir}
13987         mkdir -p ${testdir1}
13988         touch ${testdir1}/test1
13989         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13990         check_stats $SINGLEMDS "crossdir_rename" 1
13991
13992         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13993         check_stats $SINGLEMDS "samedir_rename" 1
13994
13995         rm -rf $DIR/${tdir}
13996 }
13997 run_test 133a "Verifying MDT stats ========================================"
13998
13999 test_133b() {
14000         local res
14001
14002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14003         remote_ost_nodsh && skip "remote OST with nodsh"
14004         remote_mds_nodsh && skip "remote MDS with nodsh"
14005
14006         local testdir=$DIR/${tdir}/stats_testdir
14007
14008         mkdir -p ${testdir} || error "mkdir failed"
14009         touch ${testdir}/${tfile} || error "touch failed"
14010         cancel_lru_locks mdc
14011
14012         # clear stats.
14013         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14014         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14015
14016         # extra mdt stats verification.
14017         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14018         check_stats $SINGLEMDS "setattr" 1
14019         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14020         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14021         then            # LU-1740
14022                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14023                 check_stats $SINGLEMDS "getattr" 1
14024         fi
14025         rm -rf $DIR/${tdir}
14026
14027         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14028         # so the check below is not reliable
14029         [ $MDSCOUNT -eq 1 ] || return 0
14030
14031         # Sleep to avoid a cached response.
14032         #define OBD_STATFS_CACHE_SECONDS 1
14033         sleep 2
14034         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14035         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14036         $LFS df || error "lfs failed"
14037         check_stats $SINGLEMDS "statfs" 1
14038
14039         # check aggregated statfs (LU-10018)
14040         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14041                 return 0
14042         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14043                 return 0
14044         sleep 2
14045         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14046         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14047         df $DIR
14048         check_stats $SINGLEMDS "statfs" 1
14049
14050         # We want to check that the client didn't send OST_STATFS to
14051         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14052         # extra care is needed here.
14053         if remote_mds; then
14054                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14055                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14056
14057                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14058                 [ "$res" ] && error "OST got STATFS"
14059         fi
14060
14061         return 0
14062 }
14063 run_test 133b "Verifying extra MDT stats =================================="
14064
14065 test_133c() {
14066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14067         remote_ost_nodsh && skip "remote OST with nodsh"
14068         remote_mds_nodsh && skip "remote MDS with nodsh"
14069
14070         local testdir=$DIR/$tdir/stats_testdir
14071
14072         test_mkdir -p $testdir
14073
14074         # verify obdfilter stats.
14075         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14076         sync
14077         cancel_lru_locks osc
14078         wait_delete_completed
14079
14080         # clear stats.
14081         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14082         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14083
14084         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14085                 error "dd failed"
14086         sync
14087         cancel_lru_locks osc
14088         check_stats ost1 "write" 1
14089
14090         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14091         check_stats ost1 "read" 1
14092
14093         > $testdir/$tfile || error "truncate failed"
14094         check_stats ost1 "punch" 1
14095
14096         rm -f $testdir/$tfile || error "file remove failed"
14097         wait_delete_completed
14098         check_stats ost1 "destroy" 1
14099
14100         rm -rf $DIR/$tdir
14101 }
14102 run_test 133c "Verifying OST stats ========================================"
14103
14104 order_2() {
14105         local value=$1
14106         local orig=$value
14107         local order=1
14108
14109         while [ $value -ge 2 ]; do
14110                 order=$((order*2))
14111                 value=$((value/2))
14112         done
14113
14114         if [ $orig -gt $order ]; then
14115                 order=$((order*2))
14116         fi
14117         echo $order
14118 }
14119
14120 size_in_KMGT() {
14121     local value=$1
14122     local size=('K' 'M' 'G' 'T');
14123     local i=0
14124     local size_string=$value
14125
14126     while [ $value -ge 1024 ]; do
14127         if [ $i -gt 3 ]; then
14128             #T is the biggest unit we get here, if that is bigger,
14129             #just return XXXT
14130             size_string=${value}T
14131             break
14132         fi
14133         value=$((value >> 10))
14134         if [ $value -lt 1024 ]; then
14135             size_string=${value}${size[$i]}
14136             break
14137         fi
14138         i=$((i + 1))
14139     done
14140
14141     echo $size_string
14142 }
14143
14144 get_rename_size() {
14145         local size=$1
14146         local context=${2:-.}
14147         local sample=$(do_facet $SINGLEMDS $LCTL \
14148                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14149                 grep -A1 $context |
14150                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14151         echo $sample
14152 }
14153
14154 test_133d() {
14155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14156         remote_ost_nodsh && skip "remote OST with nodsh"
14157         remote_mds_nodsh && skip "remote MDS with nodsh"
14158         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14159                 skip_env "MDS doesn't support rename stats"
14160
14161         local testdir1=$DIR/${tdir}/stats_testdir1
14162         local testdir2=$DIR/${tdir}/stats_testdir2
14163         mkdir -p $DIR/${tdir}
14164
14165         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14166
14167         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14168         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14169
14170         createmany -o $testdir1/test 512 || error "createmany failed"
14171
14172         # check samedir rename size
14173         mv ${testdir1}/test0 ${testdir1}/test_0
14174
14175         local testdir1_size=$(ls -l $DIR/${tdir} |
14176                 awk '/stats_testdir1/ {print $5}')
14177         local testdir2_size=$(ls -l $DIR/${tdir} |
14178                 awk '/stats_testdir2/ {print $5}')
14179
14180         testdir1_size=$(order_2 $testdir1_size)
14181         testdir2_size=$(order_2 $testdir2_size)
14182
14183         testdir1_size=$(size_in_KMGT $testdir1_size)
14184         testdir2_size=$(size_in_KMGT $testdir2_size)
14185
14186         echo "source rename dir size: ${testdir1_size}"
14187         echo "target rename dir size: ${testdir2_size}"
14188
14189         local cmd="do_facet $SINGLEMDS $LCTL "
14190         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14191
14192         eval $cmd || error "$cmd failed"
14193         local samedir=$($cmd | grep 'same_dir')
14194         local same_sample=$(get_rename_size $testdir1_size)
14195         [ -z "$samedir" ] && error "samedir_rename_size count error"
14196         [[ $same_sample -eq 1 ]] ||
14197                 error "samedir_rename_size error $same_sample"
14198         echo "Check same dir rename stats success"
14199
14200         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14201
14202         # check crossdir rename size
14203         mv ${testdir1}/test_0 ${testdir2}/test_0
14204
14205         testdir1_size=$(ls -l $DIR/${tdir} |
14206                 awk '/stats_testdir1/ {print $5}')
14207         testdir2_size=$(ls -l $DIR/${tdir} |
14208                 awk '/stats_testdir2/ {print $5}')
14209
14210         testdir1_size=$(order_2 $testdir1_size)
14211         testdir2_size=$(order_2 $testdir2_size)
14212
14213         testdir1_size=$(size_in_KMGT $testdir1_size)
14214         testdir2_size=$(size_in_KMGT $testdir2_size)
14215
14216         echo "source rename dir size: ${testdir1_size}"
14217         echo "target rename dir size: ${testdir2_size}"
14218
14219         eval $cmd || error "$cmd failed"
14220         local crossdir=$($cmd | grep 'crossdir')
14221         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14222         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14223         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14224         [[ $src_sample -eq 1 ]] ||
14225                 error "crossdir_rename_size error $src_sample"
14226         [[ $tgt_sample -eq 1 ]] ||
14227                 error "crossdir_rename_size error $tgt_sample"
14228         echo "Check cross dir rename stats success"
14229         rm -rf $DIR/${tdir}
14230 }
14231 run_test 133d "Verifying rename_stats ========================================"
14232
14233 test_133e() {
14234         remote_mds_nodsh && skip "remote MDS with nodsh"
14235         remote_ost_nodsh && skip "remote OST with nodsh"
14236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14237
14238         local testdir=$DIR/${tdir}/stats_testdir
14239         local ctr f0 f1 bs=32768 count=42 sum
14240
14241         mkdir -p ${testdir} || error "mkdir failed"
14242
14243         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14244
14245         for ctr in {write,read}_bytes; do
14246                 sync
14247                 cancel_lru_locks osc
14248
14249                 do_facet ost1 $LCTL set_param -n \
14250                         "obdfilter.*.exports.clear=clear"
14251
14252                 if [ $ctr = write_bytes ]; then
14253                         f0=/dev/zero
14254                         f1=${testdir}/${tfile}
14255                 else
14256                         f0=${testdir}/${tfile}
14257                         f1=/dev/null
14258                 fi
14259
14260                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14261                         error "dd failed"
14262                 sync
14263                 cancel_lru_locks osc
14264
14265                 sum=$(do_facet ost1 $LCTL get_param \
14266                         "obdfilter.*.exports.*.stats" |
14267                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14268                                 $1 == ctr { sum += $7 }
14269                                 END { printf("%0.0f", sum) }')
14270
14271                 if ((sum != bs * count)); then
14272                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14273                 fi
14274         done
14275
14276         rm -rf $DIR/${tdir}
14277 }
14278 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14279
14280 test_133f() {
14281         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14282                 skip "too old lustre for get_param -R ($facet_ver)"
14283
14284         # verifying readability.
14285         $LCTL get_param -R '*' &> /dev/null
14286
14287         # Verifing writability with badarea_io.
14288         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14289         local skipped_params='force_lbug|changelog_mask|daemon_file'
14290         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14291                 egrep -v "$skipped_params" |
14292                 xargs -n 1 find $proc_dirs -name |
14293                 xargs -n 1 badarea_io ||
14294                 error "client badarea_io failed"
14295
14296         # remount the FS in case writes/reads /proc break the FS
14297         cleanup || error "failed to unmount"
14298         setup || error "failed to setup"
14299 }
14300 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14301
14302 test_133g() {
14303         remote_mds_nodsh && skip "remote MDS with nodsh"
14304         remote_ost_nodsh && skip "remote OST with nodsh"
14305
14306         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14307         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14308         local facet
14309         for facet in mds1 ost1; do
14310                 local facet_ver=$(lustre_version_code $facet)
14311                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14312                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14313                 else
14314                         log "$facet: too old lustre for get_param -R"
14315                 fi
14316                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14317                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14318                                 tr -d = | egrep -v $skipped_params |
14319                                 xargs -n 1 find $proc_dirs -name |
14320                                 xargs -n 1 badarea_io" ||
14321                                         error "$facet badarea_io failed"
14322                 else
14323                         skip_noexit "$facet: too old lustre for get_param -R"
14324                 fi
14325         done
14326
14327         # remount the FS in case writes/reads /proc break the FS
14328         cleanup || error "failed to unmount"
14329         setup || error "failed to setup"
14330 }
14331 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14332
14333 test_133h() {
14334         remote_mds_nodsh && skip "remote MDS with nodsh"
14335         remote_ost_nodsh && skip "remote OST with nodsh"
14336         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14337                 skip "Need MDS version at least 2.9.54"
14338
14339         local facet
14340         for facet in client mds1 ost1; do
14341                 # Get the list of files that are missing the terminating newline
14342                 local plist=$(do_facet $facet
14343                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14344                 local ent
14345                 for ent in $plist; do
14346                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14347                                 awk -v FS='\v' -v RS='\v\v' \
14348                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14349                                         print FILENAME}'" 2>/dev/null)
14350                         [ -z $missing ] || {
14351                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14352                                 error "file does not end with newline: $facet-$ent"
14353                         }
14354                 done
14355         done
14356 }
14357 run_test 133h "Proc files should end with newlines"
14358
14359 test_134a() {
14360         remote_mds_nodsh && skip "remote MDS with nodsh"
14361         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14362                 skip "Need MDS version at least 2.7.54"
14363
14364         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14365         cancel_lru_locks mdc
14366
14367         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14368         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14369         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14370
14371         local nr=1000
14372         createmany -o $DIR/$tdir/f $nr ||
14373                 error "failed to create $nr files in $DIR/$tdir"
14374         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14375
14376         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14377         do_facet mds1 $LCTL set_param fail_loc=0x327
14378         do_facet mds1 $LCTL set_param fail_val=500
14379         touch $DIR/$tdir/m
14380
14381         echo "sleep 10 seconds ..."
14382         sleep 10
14383         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14384
14385         do_facet mds1 $LCTL set_param fail_loc=0
14386         do_facet mds1 $LCTL set_param fail_val=0
14387         [ $lck_cnt -lt $unused ] ||
14388                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14389
14390         rm $DIR/$tdir/m
14391         unlinkmany $DIR/$tdir/f $nr
14392 }
14393 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14394
14395 test_134b() {
14396         remote_mds_nodsh && skip "remote MDS with nodsh"
14397         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14398                 skip "Need MDS version at least 2.7.54"
14399
14400         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14401         cancel_lru_locks mdc
14402
14403         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14404                         ldlm.lock_reclaim_threshold_mb)
14405         # disable reclaim temporarily
14406         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14407
14408         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14409         do_facet mds1 $LCTL set_param fail_loc=0x328
14410         do_facet mds1 $LCTL set_param fail_val=500
14411
14412         $LCTL set_param debug=+trace
14413
14414         local nr=600
14415         createmany -o $DIR/$tdir/f $nr &
14416         local create_pid=$!
14417
14418         echo "Sleep $TIMEOUT seconds ..."
14419         sleep $TIMEOUT
14420         if ! ps -p $create_pid  > /dev/null 2>&1; then
14421                 do_facet mds1 $LCTL set_param fail_loc=0
14422                 do_facet mds1 $LCTL set_param fail_val=0
14423                 do_facet mds1 $LCTL set_param \
14424                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14425                 error "createmany finished incorrectly!"
14426         fi
14427         do_facet mds1 $LCTL set_param fail_loc=0
14428         do_facet mds1 $LCTL set_param fail_val=0
14429         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14430         wait $create_pid || return 1
14431
14432         unlinkmany $DIR/$tdir/f $nr
14433 }
14434 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14435
14436 test_135() {
14437         remote_mds_nodsh && skip "remote MDS with nodsh"
14438         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14439                 skip "Need MDS version at least 2.13.50"
14440         local fname
14441
14442         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14443
14444 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14445         #set only one record at plain llog
14446         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14447
14448         #fill already existed plain llog each 64767
14449         #wrapping whole catalog
14450         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14451
14452         createmany -o $DIR/$tdir/$tfile_ 64700
14453         for (( i = 0; i < 64700; i = i + 2 ))
14454         do
14455                 rm $DIR/$tdir/$tfile_$i &
14456                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14457                 local pid=$!
14458                 wait $pid
14459         done
14460
14461         #waiting osp synchronization
14462         wait_delete_completed
14463 }
14464 run_test 135 "Race catalog processing"
14465
14466 test_136() {
14467         remote_mds_nodsh && skip "remote MDS with nodsh"
14468         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14469                 skip "Need MDS version at least 2.13.50"
14470         local fname
14471
14472         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14473         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14474         #set only one record at plain llog
14475 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14476         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14477
14478         #fill already existed 2 plain llogs each 64767
14479         #wrapping whole catalog
14480         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14481         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14482         wait_delete_completed
14483
14484         createmany -o $DIR/$tdir/$tfile_ 10
14485         sleep 25
14486
14487         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14488         for (( i = 0; i < 10; i = i + 3 ))
14489         do
14490                 rm $DIR/$tdir/$tfile_$i &
14491                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14492                 local pid=$!
14493                 wait $pid
14494                 sleep 7
14495                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14496         done
14497
14498         #waiting osp synchronization
14499         wait_delete_completed
14500 }
14501 run_test 136 "Race catalog processing 2"
14502
14503 test_140() { #bug-17379
14504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14505
14506         test_mkdir $DIR/$tdir
14507         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14508         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14509
14510         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14511         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14512         local i=0
14513         while i=$((i + 1)); do
14514                 test_mkdir $i
14515                 cd $i || error "Changing to $i"
14516                 ln -s ../stat stat || error "Creating stat symlink"
14517                 # Read the symlink until ELOOP present,
14518                 # not LBUGing the system is considered success,
14519                 # we didn't overrun the stack.
14520                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14521                 if [ $ret -ne 0 ]; then
14522                         if [ $ret -eq 40 ]; then
14523                                 break  # -ELOOP
14524                         else
14525                                 error "Open stat symlink"
14526                                         return
14527                         fi
14528                 fi
14529         done
14530         i=$((i - 1))
14531         echo "The symlink depth = $i"
14532         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14533                 error "Invalid symlink depth"
14534
14535         # Test recursive symlink
14536         ln -s symlink_self symlink_self
14537         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14538         echo "open symlink_self returns $ret"
14539         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14540 }
14541 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14542
14543 test_150a() {
14544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14545
14546         local TF="$TMP/$tfile"
14547
14548         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14549         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14550         cp $TF $DIR/$tfile
14551         cancel_lru_locks $OSC
14552         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14553         remount_client $MOUNT
14554         df -P $MOUNT
14555         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14556
14557         $TRUNCATE $TF 6000
14558         $TRUNCATE $DIR/$tfile 6000
14559         cancel_lru_locks $OSC
14560         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14561
14562         echo "12345" >>$TF
14563         echo "12345" >>$DIR/$tfile
14564         cancel_lru_locks $OSC
14565         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14566
14567         echo "12345" >>$TF
14568         echo "12345" >>$DIR/$tfile
14569         cancel_lru_locks $OSC
14570         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14571 }
14572 run_test 150a "truncate/append tests"
14573
14574 test_150b() {
14575         check_set_fallocate_or_skip
14576
14577         touch $DIR/$tfile
14578         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14579         check_fallocate $DIR/$tfile || error "fallocate failed"
14580 }
14581 run_test 150b "Verify fallocate (prealloc) functionality"
14582
14583 test_150bb() {
14584         check_set_fallocate_or_skip
14585
14586         touch $DIR/$tfile
14587         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14588         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14589         > $DIR/$tfile
14590         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14591         # precomputed md5sum for 20MB of zeroes
14592         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14593         local sum=($(md5sum $DIR/$tfile))
14594
14595         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14596
14597         check_set_fallocate 1
14598
14599         > $DIR/$tfile
14600         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14601         sum=($(md5sum $DIR/$tfile))
14602
14603         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14604 }
14605 run_test 150bb "Verify fallocate modes both zero space"
14606
14607 test_150c() {
14608         check_set_fallocate_or_skip
14609         local striping="-c2"
14610
14611         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14612         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14613         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14614         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14615         local want=$((OSTCOUNT * 1048576))
14616
14617         # Must allocate all requested space, not more than 5% extra
14618         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14619                 error "bytes $bytes is not $want"
14620
14621         rm -f $DIR/$tfile
14622
14623         echo "verify fallocate on PFL file"
14624
14625         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14626
14627         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14628                 error "Create $DIR/$tfile failed"
14629         fallocate -l $((1048576 * 512)) $DIR/$tfile ||
14630                         error "fallocate failed"
14631         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14632         want=$((512 * 1048576))
14633
14634         # Must allocate all requested space, not more than 5% extra
14635         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14636                 error "bytes $bytes is not $want"
14637 }
14638 run_test 150c "Verify fallocate Size and Blocks"
14639
14640 test_150d() {
14641         check_set_fallocate_or_skip
14642         local striping="-c2"
14643
14644         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14645
14646         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14647         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14648                 error "setstripe failed"
14649         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14650         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14651         local want=$((OSTCOUNT * 1048576))
14652
14653         # Must allocate all requested space, not more than 5% extra
14654         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14655                 error "bytes $bytes is not $want"
14656 }
14657 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14658
14659 test_150e() {
14660         check_set_fallocate_or_skip
14661
14662         echo "df before:"
14663         $LFS df
14664         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14665         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14666                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14667
14668         # Find OST with Minimum Size
14669         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14670                        sort -un | head -1)
14671
14672         # Get 100MB per OST of the available space to reduce run time
14673         # else 60% of the available space if we are running SLOW tests
14674         if [ $SLOW == "no" ]; then
14675                 local space=$((1024 * 100 * OSTCOUNT))
14676         else
14677                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14678         fi
14679
14680         fallocate -l${space}k $DIR/$tfile ||
14681                 error "fallocate ${space}k $DIR/$tfile failed"
14682         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14683
14684         # get size immediately after fallocate. This should be correctly
14685         # updated
14686         local size=$(stat -c '%s' $DIR/$tfile)
14687         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14688
14689         # Sleep for a while for statfs to get updated. And not pull from cache.
14690         sleep 2
14691
14692         echo "df after fallocate:"
14693         $LFS df
14694
14695         (( size / 1024 == space )) || error "size $size != requested $space"
14696         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14697                 error "used $used < space $space"
14698
14699         rm $DIR/$tfile || error "rm failed"
14700         sync
14701         wait_delete_completed
14702
14703         echo "df after unlink:"
14704         $LFS df
14705 }
14706 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14707
14708 test_150f() {
14709         local size
14710         local blocks
14711         local want_size_before=20480 # in bytes
14712         local want_blocks_before=40 # 512 sized blocks
14713         local want_blocks_after=24  # 512 sized blocks
14714         local length=$(((want_blocks_before - want_blocks_after) * 512))
14715
14716         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14717                 skip "need at least 2.14.0 for fallocate punch"
14718
14719         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14720                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14721         fi
14722
14723         check_set_fallocate_or_skip
14724         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14725
14726         [[ "x$DOM" == "xyes" ]] &&
14727                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14728
14729         echo "Verify fallocate punch: Range within the file range"
14730         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14731                 error "dd failed for bs 4096 and count 5"
14732
14733         # Call fallocate with punch range which is within the file range
14734         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
14735                 error "fallocate failed: offset 4096 and length $length"
14736         # client must see changes immediately after fallocate
14737         size=$(stat -c '%s' $DIR/$tfile)
14738         blocks=$(stat -c '%b' $DIR/$tfile)
14739
14740         # Verify punch worked.
14741         (( blocks == want_blocks_after )) ||
14742                 error "punch failed: blocks $blocks != $want_blocks_after"
14743
14744         (( size == want_size_before )) ||
14745                 error "punch failed: size $size != $want_size_before"
14746
14747         # Verify there is hole in file
14748         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14749         # precomputed md5sum
14750         local expect="4a9a834a2db02452929c0a348273b4aa"
14751
14752         cksum=($(md5sum $DIR/$tfile))
14753         [[ "${cksum[0]}" == "$expect" ]] ||
14754                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14755
14756         # Start second sub-case for fallocate punch.
14757         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14758         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14759                 error "dd failed for bs 4096 and count 5"
14760
14761         # Punch range less than block size will have no change in block count
14762         want_blocks_after=40  # 512 sized blocks
14763
14764         # Punch overlaps two blocks and less than blocksize
14765         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
14766                 error "fallocate failed: offset 4000 length 3000"
14767         size=$(stat -c '%s' $DIR/$tfile)
14768         blocks=$(stat -c '%b' $DIR/$tfile)
14769
14770         # Verify punch worked.
14771         (( blocks == want_blocks_after )) ||
14772                 error "punch failed: blocks $blocks != $want_blocks_after"
14773
14774         (( size == want_size_before )) ||
14775                 error "punch failed: size $size != $want_size_before"
14776
14777         # Verify if range is really zero'ed out. We expect Zeros.
14778         # precomputed md5sum
14779         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14780         cksum=($(md5sum $DIR/$tfile))
14781         [[ "${cksum[0]}" == "$expect" ]] ||
14782                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14783 }
14784 run_test 150f "Verify fallocate punch functionality"
14785
14786 test_150g() {
14787         local space
14788         local size
14789         local blocks
14790         local blocks_after
14791         local size_after
14792         local BS=4096 # Block size in bytes
14793
14794         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14795                 skip "need at least 2.14.0 for fallocate punch"
14796
14797         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14798                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14799         fi
14800
14801         check_set_fallocate_or_skip
14802         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14803
14804         if [[ "x$DOM" == "xyes" ]]; then
14805                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
14806                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
14807         else
14808                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14809                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14810         fi
14811
14812         # Get 100MB per OST of the available space to reduce run time
14813         # else 60% of the available space if we are running SLOW tests
14814         if [ $SLOW == "no" ]; then
14815                 space=$((1024 * 100 * OSTCOUNT))
14816         else
14817                 # Find OST with Minimum Size
14818                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14819                         sort -un | head -1)
14820                 echo "min size OST: $space"
14821                 space=$(((space * 60)/100 * OSTCOUNT))
14822         fi
14823         # space in 1k units, round to 4k blocks
14824         local blkcount=$((space * 1024 / $BS))
14825
14826         echo "Verify fallocate punch: Very large Range"
14827         fallocate -l${space}k $DIR/$tfile ||
14828                 error "fallocate ${space}k $DIR/$tfile failed"
14829         # write 1M at the end, start and in the middle
14830         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14831                 error "dd failed: bs $BS count 256"
14832         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14833                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14834         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14835                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14836
14837         # Gather stats.
14838         size=$(stat -c '%s' $DIR/$tfile)
14839
14840         # gather punch length.
14841         local punch_size=$((size - (BS * 2)))
14842
14843         echo "punch_size = $punch_size"
14844         echo "size - punch_size: $((size - punch_size))"
14845         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14846
14847         # Call fallocate to punch all except 2 blocks. We leave the
14848         # first and the last block
14849         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14850         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14851                 error "fallocate failed: offset $BS length $punch_size"
14852
14853         size_after=$(stat -c '%s' $DIR/$tfile)
14854         blocks_after=$(stat -c '%b' $DIR/$tfile)
14855
14856         # Verify punch worked.
14857         # Size should be kept
14858         (( size == size_after )) ||
14859                 error "punch failed: size $size != $size_after"
14860
14861         # two 4k data blocks to remain plus possible 1 extra extent block
14862         (( blocks_after <= ((BS / 512) * 3) )) ||
14863                 error "too many blocks remains: $blocks_after"
14864
14865         # Verify that file has hole between the first and the last blocks
14866         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14867         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14868
14869         echo "Hole at [$hole_start, $hole_end)"
14870         (( hole_start == BS )) ||
14871                 error "no hole at offset $BS after punch"
14872
14873         (( hole_end == BS + punch_size )) ||
14874                 error "data at offset $hole_end < $((BS + punch_size))"
14875 }
14876 run_test 150g "Verify fallocate punch on large range"
14877
14878 #LU-2902 roc_hit was not able to read all values from lproc
14879 function roc_hit_init() {
14880         local list=$(comma_list $(osts_nodes))
14881         local dir=$DIR/$tdir-check
14882         local file=$dir/$tfile
14883         local BEFORE
14884         local AFTER
14885         local idx
14886
14887         test_mkdir $dir
14888         #use setstripe to do a write to every ost
14889         for i in $(seq 0 $((OSTCOUNT-1))); do
14890                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14891                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14892                 idx=$(printf %04x $i)
14893                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14894                         awk '$1 == "cache_access" {sum += $7}
14895                                 END { printf("%0.0f", sum) }')
14896
14897                 cancel_lru_locks osc
14898                 cat $file >/dev/null
14899
14900                 AFTER=$(get_osd_param $list *OST*$idx stats |
14901                         awk '$1 == "cache_access" {sum += $7}
14902                                 END { printf("%0.0f", sum) }')
14903
14904                 echo BEFORE:$BEFORE AFTER:$AFTER
14905                 if ! let "AFTER - BEFORE == 4"; then
14906                         rm -rf $dir
14907                         error "roc_hit is not safe to use"
14908                 fi
14909                 rm $file
14910         done
14911
14912         rm -rf $dir
14913 }
14914
14915 function roc_hit() {
14916         local list=$(comma_list $(osts_nodes))
14917         echo $(get_osd_param $list '' stats |
14918                 awk '$1 == "cache_hit" {sum += $7}
14919                         END { printf("%0.0f", sum) }')
14920 }
14921
14922 function set_cache() {
14923         local on=1
14924
14925         if [ "$2" == "off" ]; then
14926                 on=0;
14927         fi
14928         local list=$(comma_list $(osts_nodes))
14929         set_osd_param $list '' $1_cache_enable $on
14930
14931         cancel_lru_locks osc
14932 }
14933
14934 test_151() {
14935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14936         remote_ost_nodsh && skip "remote OST with nodsh"
14937
14938         local CPAGES=3
14939         local list=$(comma_list $(osts_nodes))
14940
14941         # check whether obdfilter is cache capable at all
14942         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14943                 skip "not cache-capable obdfilter"
14944         fi
14945
14946         # check cache is enabled on all obdfilters
14947         if get_osd_param $list '' read_cache_enable | grep 0; then
14948                 skip "oss cache is disabled"
14949         fi
14950
14951         set_osd_param $list '' writethrough_cache_enable 1
14952
14953         # check write cache is enabled on all obdfilters
14954         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14955                 skip "oss write cache is NOT enabled"
14956         fi
14957
14958         roc_hit_init
14959
14960         #define OBD_FAIL_OBD_NO_LRU  0x609
14961         do_nodes $list $LCTL set_param fail_loc=0x609
14962
14963         # pages should be in the case right after write
14964         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14965                 error "dd failed"
14966
14967         local BEFORE=$(roc_hit)
14968         cancel_lru_locks osc
14969         cat $DIR/$tfile >/dev/null
14970         local AFTER=$(roc_hit)
14971
14972         do_nodes $list $LCTL set_param fail_loc=0
14973
14974         if ! let "AFTER - BEFORE == CPAGES"; then
14975                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
14976         fi
14977
14978         cancel_lru_locks osc
14979         # invalidates OST cache
14980         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
14981         set_osd_param $list '' read_cache_enable 0
14982         cat $DIR/$tfile >/dev/null
14983
14984         # now data shouldn't be found in the cache
14985         BEFORE=$(roc_hit)
14986         cancel_lru_locks osc
14987         cat $DIR/$tfile >/dev/null
14988         AFTER=$(roc_hit)
14989         if let "AFTER - BEFORE != 0"; then
14990                 error "IN CACHE: before: $BEFORE, after: $AFTER"
14991         fi
14992
14993         set_osd_param $list '' read_cache_enable 1
14994         rm -f $DIR/$tfile
14995 }
14996 run_test 151 "test cache on oss and controls ==============================="
14997
14998 test_152() {
14999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15000
15001         local TF="$TMP/$tfile"
15002
15003         # simulate ENOMEM during write
15004 #define OBD_FAIL_OST_NOMEM      0x226
15005         lctl set_param fail_loc=0x80000226
15006         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15007         cp $TF $DIR/$tfile
15008         sync || error "sync failed"
15009         lctl set_param fail_loc=0
15010
15011         # discard client's cache
15012         cancel_lru_locks osc
15013
15014         # simulate ENOMEM during read
15015         lctl set_param fail_loc=0x80000226
15016         cmp $TF $DIR/$tfile || error "cmp failed"
15017         lctl set_param fail_loc=0
15018
15019         rm -f $TF
15020 }
15021 run_test 152 "test read/write with enomem ============================"
15022
15023 test_153() {
15024         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15025 }
15026 run_test 153 "test if fdatasync does not crash ======================="
15027
15028 dot_lustre_fid_permission_check() {
15029         local fid=$1
15030         local ffid=$MOUNT/.lustre/fid/$fid
15031         local test_dir=$2
15032
15033         echo "stat fid $fid"
15034         stat $ffid > /dev/null || error "stat $ffid failed."
15035         echo "touch fid $fid"
15036         touch $ffid || error "touch $ffid failed."
15037         echo "write to fid $fid"
15038         cat /etc/hosts > $ffid || error "write $ffid failed."
15039         echo "read fid $fid"
15040         diff /etc/hosts $ffid || error "read $ffid failed."
15041         echo "append write to fid $fid"
15042         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15043         echo "rename fid $fid"
15044         mv $ffid $test_dir/$tfile.1 &&
15045                 error "rename $ffid to $tfile.1 should fail."
15046         touch $test_dir/$tfile.1
15047         mv $test_dir/$tfile.1 $ffid &&
15048                 error "rename $tfile.1 to $ffid should fail."
15049         rm -f $test_dir/$tfile.1
15050         echo "truncate fid $fid"
15051         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15052         echo "link fid $fid"
15053         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15054         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15055                 echo "setfacl fid $fid"
15056                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
15057                 echo "getfacl fid $fid"
15058                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
15059         fi
15060         echo "unlink fid $fid"
15061         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15062         echo "mknod fid $fid"
15063         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15064
15065         fid=[0xf00000400:0x1:0x0]
15066         ffid=$MOUNT/.lustre/fid/$fid
15067
15068         echo "stat non-exist fid $fid"
15069         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15070         echo "write to non-exist fid $fid"
15071         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15072         echo "link new fid $fid"
15073         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15074
15075         mkdir -p $test_dir/$tdir
15076         touch $test_dir/$tdir/$tfile
15077         fid=$($LFS path2fid $test_dir/$tdir)
15078         rc=$?
15079         [ $rc -ne 0 ] &&
15080                 error "error: could not get fid for $test_dir/$dir/$tfile."
15081
15082         ffid=$MOUNT/.lustre/fid/$fid
15083
15084         echo "ls $fid"
15085         ls $ffid > /dev/null || error "ls $ffid failed."
15086         echo "touch $fid/$tfile.1"
15087         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15088
15089         echo "touch $MOUNT/.lustre/fid/$tfile"
15090         touch $MOUNT/.lustre/fid/$tfile && \
15091                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15092
15093         echo "setxattr to $MOUNT/.lustre/fid"
15094         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15095
15096         echo "listxattr for $MOUNT/.lustre/fid"
15097         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15098
15099         echo "delxattr from $MOUNT/.lustre/fid"
15100         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15101
15102         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15103         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15104                 error "touch invalid fid should fail."
15105
15106         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15107         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15108                 error "touch non-normal fid should fail."
15109
15110         echo "rename $tdir to $MOUNT/.lustre/fid"
15111         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15112                 error "rename to $MOUNT/.lustre/fid should fail."
15113
15114         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15115         then            # LU-3547
15116                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15117                 local new_obf_mode=777
15118
15119                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15120                 chmod $new_obf_mode $DIR/.lustre/fid ||
15121                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15122
15123                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15124                 [ $obf_mode -eq $new_obf_mode ] ||
15125                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15126
15127                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15128                 chmod $old_obf_mode $DIR/.lustre/fid ||
15129                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15130         fi
15131
15132         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15133         fid=$($LFS path2fid $test_dir/$tfile-2)
15134
15135         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15136         then # LU-5424
15137                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15138                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15139                         error "create lov data thru .lustre failed"
15140         fi
15141         echo "cp /etc/passwd $test_dir/$tfile-2"
15142         cp /etc/passwd $test_dir/$tfile-2 ||
15143                 error "copy to $test_dir/$tfile-2 failed."
15144         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15145         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15146                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15147
15148         rm -rf $test_dir/tfile.lnk
15149         rm -rf $test_dir/$tfile-2
15150 }
15151
15152 test_154A() {
15153         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15154                 skip "Need MDS version at least 2.4.1"
15155
15156         local tf=$DIR/$tfile
15157         touch $tf
15158
15159         local fid=$($LFS path2fid $tf)
15160         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15161
15162         # check that we get the same pathname back
15163         local rootpath
15164         local found
15165         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15166                 echo "$rootpath $fid"
15167                 found=$($LFS fid2path $rootpath "$fid")
15168                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15169                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15170         done
15171
15172         # check wrong root path format
15173         rootpath=$MOUNT"_wrong"
15174         found=$($LFS fid2path $rootpath "$fid")
15175         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15176 }
15177 run_test 154A "lfs path2fid and fid2path basic checks"
15178
15179 test_154B() {
15180         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15181                 skip "Need MDS version at least 2.4.1"
15182
15183         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15184         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15185         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15186         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15187
15188         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15189         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15190
15191         # check that we get the same pathname
15192         echo "PFID: $PFID, name: $name"
15193         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15194         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15195         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15196                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15197
15198         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15199 }
15200 run_test 154B "verify the ll_decode_linkea tool"
15201
15202 test_154a() {
15203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15204         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15205         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15206                 skip "Need MDS version at least 2.2.51"
15207         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15208
15209         cp /etc/hosts $DIR/$tfile
15210
15211         fid=$($LFS path2fid $DIR/$tfile)
15212         rc=$?
15213         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15214
15215         dot_lustre_fid_permission_check "$fid" $DIR ||
15216                 error "dot lustre permission check $fid failed"
15217
15218         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15219
15220         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15221
15222         touch $MOUNT/.lustre/file &&
15223                 error "creation is not allowed under .lustre"
15224
15225         mkdir $MOUNT/.lustre/dir &&
15226                 error "mkdir is not allowed under .lustre"
15227
15228         rm -rf $DIR/$tfile
15229 }
15230 run_test 154a "Open-by-FID"
15231
15232 test_154b() {
15233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15234         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15235         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15236         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15237                 skip "Need MDS version at least 2.2.51"
15238
15239         local remote_dir=$DIR/$tdir/remote_dir
15240         local MDTIDX=1
15241         local rc=0
15242
15243         mkdir -p $DIR/$tdir
15244         $LFS mkdir -i $MDTIDX $remote_dir ||
15245                 error "create remote directory failed"
15246
15247         cp /etc/hosts $remote_dir/$tfile
15248
15249         fid=$($LFS path2fid $remote_dir/$tfile)
15250         rc=$?
15251         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15252
15253         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15254                 error "dot lustre permission check $fid failed"
15255         rm -rf $DIR/$tdir
15256 }
15257 run_test 154b "Open-by-FID for remote directory"
15258
15259 test_154c() {
15260         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15261                 skip "Need MDS version at least 2.4.1"
15262
15263         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15264         local FID1=$($LFS path2fid $DIR/$tfile.1)
15265         local FID2=$($LFS path2fid $DIR/$tfile.2)
15266         local FID3=$($LFS path2fid $DIR/$tfile.3)
15267
15268         local N=1
15269         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15270                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15271                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15272                 local want=FID$N
15273                 [ "$FID" = "${!want}" ] ||
15274                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15275                 N=$((N + 1))
15276         done
15277
15278         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15279         do
15280                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15281                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15282                 N=$((N + 1))
15283         done
15284 }
15285 run_test 154c "lfs path2fid and fid2path multiple arguments"
15286
15287 test_154d() {
15288         remote_mds_nodsh && skip "remote MDS with nodsh"
15289         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15290                 skip "Need MDS version at least 2.5.53"
15291
15292         if remote_mds; then
15293                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15294         else
15295                 nid="0@lo"
15296         fi
15297         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15298         local fd
15299         local cmd
15300
15301         rm -f $DIR/$tfile
15302         touch $DIR/$tfile
15303
15304         local fid=$($LFS path2fid $DIR/$tfile)
15305         # Open the file
15306         fd=$(free_fd)
15307         cmd="exec $fd<$DIR/$tfile"
15308         eval $cmd
15309         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15310         echo "$fid_list" | grep "$fid"
15311         rc=$?
15312
15313         cmd="exec $fd>/dev/null"
15314         eval $cmd
15315         if [ $rc -ne 0 ]; then
15316                 error "FID $fid not found in open files list $fid_list"
15317         fi
15318 }
15319 run_test 154d "Verify open file fid"
15320
15321 test_154e()
15322 {
15323         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15324                 skip "Need MDS version at least 2.6.50"
15325
15326         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15327                 error ".lustre returned by readdir"
15328         fi
15329 }
15330 run_test 154e ".lustre is not returned by readdir"
15331
15332 test_154f() {
15333         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15334
15335         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15336         mkdir_on_mdt0 $DIR/$tdir
15337         # test dirs inherit from its stripe
15338         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15339         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15340         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15341         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15342         touch $DIR/f
15343
15344         # get fid of parents
15345         local FID0=$($LFS path2fid $DIR/$tdir)
15346         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15347         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15348         local FID3=$($LFS path2fid $DIR)
15349
15350         # check that path2fid --parents returns expected <parent_fid>/name
15351         # 1) test for a directory (single parent)
15352         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15353         [ "$parent" == "$FID0/foo1" ] ||
15354                 error "expected parent: $FID0/foo1, got: $parent"
15355
15356         # 2) test for a file with nlink > 1 (multiple parents)
15357         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15358         echo "$parent" | grep -F "$FID1/$tfile" ||
15359                 error "$FID1/$tfile not returned in parent list"
15360         echo "$parent" | grep -F "$FID2/link" ||
15361                 error "$FID2/link not returned in parent list"
15362
15363         # 3) get parent by fid
15364         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15365         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15366         echo "$parent" | grep -F "$FID1/$tfile" ||
15367                 error "$FID1/$tfile not returned in parent list (by fid)"
15368         echo "$parent" | grep -F "$FID2/link" ||
15369                 error "$FID2/link not returned in parent list (by fid)"
15370
15371         # 4) test for entry in root directory
15372         parent=$($LFS path2fid --parents $DIR/f)
15373         echo "$parent" | grep -F "$FID3/f" ||
15374                 error "$FID3/f not returned in parent list"
15375
15376         # 5) test it on root directory
15377         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15378                 error "$MOUNT should not have parents"
15379
15380         # enable xattr caching and check that linkea is correctly updated
15381         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15382         save_lustre_params client "llite.*.xattr_cache" > $save
15383         lctl set_param llite.*.xattr_cache 1
15384
15385         # 6.1) linkea update on rename
15386         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15387
15388         # get parents by fid
15389         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15390         # foo1 should no longer be returned in parent list
15391         echo "$parent" | grep -F "$FID1" &&
15392                 error "$FID1 should no longer be in parent list"
15393         # the new path should appear
15394         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15395                 error "$FID2/$tfile.moved is not in parent list"
15396
15397         # 6.2) linkea update on unlink
15398         rm -f $DIR/$tdir/foo2/link
15399         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15400         # foo2/link should no longer be returned in parent list
15401         echo "$parent" | grep -F "$FID2/link" &&
15402                 error "$FID2/link should no longer be in parent list"
15403         true
15404
15405         rm -f $DIR/f
15406         restore_lustre_params < $save
15407         rm -f $save
15408 }
15409 run_test 154f "get parent fids by reading link ea"
15410
15411 test_154g()
15412 {
15413         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15414         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15415            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15416                 skip "Need MDS version at least 2.6.92"
15417
15418         mkdir_on_mdt0 $DIR/$tdir
15419         llapi_fid_test -d $DIR/$tdir
15420 }
15421 run_test 154g "various llapi FID tests"
15422
15423 test_155_small_load() {
15424     local temp=$TMP/$tfile
15425     local file=$DIR/$tfile
15426
15427     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15428         error "dd of=$temp bs=6096 count=1 failed"
15429     cp $temp $file
15430     cancel_lru_locks $OSC
15431     cmp $temp $file || error "$temp $file differ"
15432
15433     $TRUNCATE $temp 6000
15434     $TRUNCATE $file 6000
15435     cmp $temp $file || error "$temp $file differ (truncate1)"
15436
15437     echo "12345" >>$temp
15438     echo "12345" >>$file
15439     cmp $temp $file || error "$temp $file differ (append1)"
15440
15441     echo "12345" >>$temp
15442     echo "12345" >>$file
15443     cmp $temp $file || error "$temp $file differ (append2)"
15444
15445     rm -f $temp $file
15446     true
15447 }
15448
15449 test_155_big_load() {
15450         remote_ost_nodsh && skip "remote OST with nodsh"
15451
15452         local temp=$TMP/$tfile
15453         local file=$DIR/$tfile
15454
15455         free_min_max
15456         local cache_size=$(do_facet ost$((MAXI+1)) \
15457                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15458         local large_file_size=$((cache_size * 2))
15459
15460         echo "OSS cache size: $cache_size KB"
15461         echo "Large file size: $large_file_size KB"
15462
15463         [ $MAXV -le $large_file_size ] &&
15464                 skip_env "max available OST size needs > $large_file_size KB"
15465
15466         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15467
15468         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15469                 error "dd of=$temp bs=$large_file_size count=1k failed"
15470         cp $temp $file
15471         ls -lh $temp $file
15472         cancel_lru_locks osc
15473         cmp $temp $file || error "$temp $file differ"
15474
15475         rm -f $temp $file
15476         true
15477 }
15478
15479 save_writethrough() {
15480         local facets=$(get_facets OST)
15481
15482         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15483 }
15484
15485 test_155a() {
15486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15487
15488         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15489
15490         save_writethrough $p
15491
15492         set_cache read on
15493         set_cache writethrough on
15494         test_155_small_load
15495         restore_lustre_params < $p
15496         rm -f $p
15497 }
15498 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15499
15500 test_155b() {
15501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15502
15503         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15504
15505         save_writethrough $p
15506
15507         set_cache read on
15508         set_cache writethrough off
15509         test_155_small_load
15510         restore_lustre_params < $p
15511         rm -f $p
15512 }
15513 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15514
15515 test_155c() {
15516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15517
15518         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15519
15520         save_writethrough $p
15521
15522         set_cache read off
15523         set_cache writethrough on
15524         test_155_small_load
15525         restore_lustre_params < $p
15526         rm -f $p
15527 }
15528 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15529
15530 test_155d() {
15531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15532
15533         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15534
15535         save_writethrough $p
15536
15537         set_cache read off
15538         set_cache writethrough off
15539         test_155_small_load
15540         restore_lustre_params < $p
15541         rm -f $p
15542 }
15543 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15544
15545 test_155e() {
15546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15547
15548         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15549
15550         save_writethrough $p
15551
15552         set_cache read on
15553         set_cache writethrough on
15554         test_155_big_load
15555         restore_lustre_params < $p
15556         rm -f $p
15557 }
15558 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15559
15560 test_155f() {
15561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15562
15563         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15564
15565         save_writethrough $p
15566
15567         set_cache read on
15568         set_cache writethrough off
15569         test_155_big_load
15570         restore_lustre_params < $p
15571         rm -f $p
15572 }
15573 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15574
15575 test_155g() {
15576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15577
15578         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15579
15580         save_writethrough $p
15581
15582         set_cache read off
15583         set_cache writethrough on
15584         test_155_big_load
15585         restore_lustre_params < $p
15586         rm -f $p
15587 }
15588 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15589
15590 test_155h() {
15591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15592
15593         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15594
15595         save_writethrough $p
15596
15597         set_cache read off
15598         set_cache writethrough off
15599         test_155_big_load
15600         restore_lustre_params < $p
15601         rm -f $p
15602 }
15603 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15604
15605 test_156() {
15606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15607         remote_ost_nodsh && skip "remote OST with nodsh"
15608         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15609                 skip "stats not implemented on old servers"
15610         [ "$ost1_FSTYPE" = "zfs" ] &&
15611                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15612
15613         local CPAGES=3
15614         local BEFORE
15615         local AFTER
15616         local file="$DIR/$tfile"
15617         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15618
15619         save_writethrough $p
15620         roc_hit_init
15621
15622         log "Turn on read and write cache"
15623         set_cache read on
15624         set_cache writethrough on
15625
15626         log "Write data and read it back."
15627         log "Read should be satisfied from the cache."
15628         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15629         BEFORE=$(roc_hit)
15630         cancel_lru_locks osc
15631         cat $file >/dev/null
15632         AFTER=$(roc_hit)
15633         if ! let "AFTER - BEFORE == CPAGES"; then
15634                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15635         else
15636                 log "cache hits: before: $BEFORE, after: $AFTER"
15637         fi
15638
15639         log "Read again; it should be satisfied from the cache."
15640         BEFORE=$AFTER
15641         cancel_lru_locks osc
15642         cat $file >/dev/null
15643         AFTER=$(roc_hit)
15644         if ! let "AFTER - BEFORE == CPAGES"; then
15645                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15646         else
15647                 log "cache hits:: before: $BEFORE, after: $AFTER"
15648         fi
15649
15650         log "Turn off the read cache and turn on the write cache"
15651         set_cache read off
15652         set_cache writethrough on
15653
15654         log "Read again; it should be satisfied from the cache."
15655         BEFORE=$(roc_hit)
15656         cancel_lru_locks osc
15657         cat $file >/dev/null
15658         AFTER=$(roc_hit)
15659         if ! let "AFTER - BEFORE == CPAGES"; then
15660                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15661         else
15662                 log "cache hits:: before: $BEFORE, after: $AFTER"
15663         fi
15664
15665         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15666                 # > 2.12.56 uses pagecache if cached
15667                 log "Read again; it should not be satisfied from the cache."
15668                 BEFORE=$AFTER
15669                 cancel_lru_locks osc
15670                 cat $file >/dev/null
15671                 AFTER=$(roc_hit)
15672                 if ! let "AFTER - BEFORE == 0"; then
15673                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15674                 else
15675                         log "cache hits:: before: $BEFORE, after: $AFTER"
15676                 fi
15677         fi
15678
15679         log "Write data and read it back."
15680         log "Read should be satisfied from the cache."
15681         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15682         BEFORE=$(roc_hit)
15683         cancel_lru_locks osc
15684         cat $file >/dev/null
15685         AFTER=$(roc_hit)
15686         if ! let "AFTER - BEFORE == CPAGES"; then
15687                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15688         else
15689                 log "cache hits:: before: $BEFORE, after: $AFTER"
15690         fi
15691
15692         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15693                 # > 2.12.56 uses pagecache if cached
15694                 log "Read again; it should not be satisfied from the cache."
15695                 BEFORE=$AFTER
15696                 cancel_lru_locks osc
15697                 cat $file >/dev/null
15698                 AFTER=$(roc_hit)
15699                 if ! let "AFTER - BEFORE == 0"; then
15700                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15701                 else
15702                         log "cache hits:: before: $BEFORE, after: $AFTER"
15703                 fi
15704         fi
15705
15706         log "Turn off read and write cache"
15707         set_cache read off
15708         set_cache writethrough off
15709
15710         log "Write data and read it back"
15711         log "It should not be satisfied from the cache."
15712         rm -f $file
15713         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15714         cancel_lru_locks osc
15715         BEFORE=$(roc_hit)
15716         cat $file >/dev/null
15717         AFTER=$(roc_hit)
15718         if ! let "AFTER - BEFORE == 0"; then
15719                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15720         else
15721                 log "cache hits:: before: $BEFORE, after: $AFTER"
15722         fi
15723
15724         log "Turn on the read cache and turn off the write cache"
15725         set_cache read on
15726         set_cache writethrough off
15727
15728         log "Write data and read it back"
15729         log "It should not be satisfied from the cache."
15730         rm -f $file
15731         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15732         BEFORE=$(roc_hit)
15733         cancel_lru_locks osc
15734         cat $file >/dev/null
15735         AFTER=$(roc_hit)
15736         if ! let "AFTER - BEFORE == 0"; then
15737                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15738         else
15739                 log "cache hits:: before: $BEFORE, after: $AFTER"
15740         fi
15741
15742         log "Read again; it should be satisfied from the cache."
15743         BEFORE=$(roc_hit)
15744         cancel_lru_locks osc
15745         cat $file >/dev/null
15746         AFTER=$(roc_hit)
15747         if ! let "AFTER - BEFORE == CPAGES"; then
15748                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15749         else
15750                 log "cache hits:: before: $BEFORE, after: $AFTER"
15751         fi
15752
15753         restore_lustre_params < $p
15754         rm -f $p $file
15755 }
15756 run_test 156 "Verification of tunables"
15757
15758 test_160a() {
15759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15760         remote_mds_nodsh && skip "remote MDS with nodsh"
15761         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15762                 skip "Need MDS version at least 2.2.0"
15763
15764         changelog_register || error "changelog_register failed"
15765         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15766         changelog_users $SINGLEMDS | grep -q $cl_user ||
15767                 error "User $cl_user not found in changelog_users"
15768
15769         mkdir_on_mdt0 $DIR/$tdir
15770
15771         # change something
15772         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15773         changelog_clear 0 || error "changelog_clear failed"
15774         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15775         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15776         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15777         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15778         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15779         rm $DIR/$tdir/pics/desktop.jpg
15780
15781         echo "verifying changelog mask"
15782         changelog_chmask "-MKDIR"
15783         changelog_chmask "-CLOSE"
15784
15785         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15786         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15787
15788         changelog_chmask "+MKDIR"
15789         changelog_chmask "+CLOSE"
15790
15791         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15792         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15793
15794         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15795         CLOSES=$(changelog_dump | grep -c "CLOSE")
15796         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15797         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15798
15799         # verify contents
15800         echo "verifying target fid"
15801         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15802         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15803         [ "$fidc" == "$fidf" ] ||
15804                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15805         echo "verifying parent fid"
15806         # The FID returned from the Changelog may be the directory shard on
15807         # a different MDT, and not the FID returned by path2fid on the parent.
15808         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15809         # since this is what will matter when recreating this file in the tree.
15810         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15811         local pathp=$($LFS fid2path $MOUNT "$fidp")
15812         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15813                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15814
15815         echo "getting records for $cl_user"
15816         changelog_users $SINGLEMDS
15817         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15818         local nclr=3
15819         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15820                 error "changelog_clear failed"
15821         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15822         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15823         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15824                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15825
15826         local min0_rec=$(changelog_users $SINGLEMDS |
15827                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15828         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15829                           awk '{ print $1; exit; }')
15830
15831         changelog_dump | tail -n 5
15832         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15833         [ $first_rec == $((min0_rec + 1)) ] ||
15834                 error "first index should be $min0_rec + 1 not $first_rec"
15835
15836         # LU-3446 changelog index reset on MDT restart
15837         local cur_rec1=$(changelog_users $SINGLEMDS |
15838                          awk '/^current.index:/ { print $NF }')
15839         changelog_clear 0 ||
15840                 error "clear all changelog records for $cl_user failed"
15841         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15842         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15843                 error "Fail to start $SINGLEMDS"
15844         local cur_rec2=$(changelog_users $SINGLEMDS |
15845                          awk '/^current.index:/ { print $NF }')
15846         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15847         [ $cur_rec1 == $cur_rec2 ] ||
15848                 error "current index should be $cur_rec1 not $cur_rec2"
15849
15850         echo "verifying users from this test are deregistered"
15851         changelog_deregister || error "changelog_deregister failed"
15852         changelog_users $SINGLEMDS | grep -q $cl_user &&
15853                 error "User '$cl_user' still in changelog_users"
15854
15855         # lctl get_param -n mdd.*.changelog_users
15856         # current_index: 144
15857         # ID    index (idle seconds)
15858         # cl3   144   (2) mask=<list>
15859         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15860                 # this is the normal case where all users were deregistered
15861                 # make sure no new records are added when no users are present
15862                 local last_rec1=$(changelog_users $SINGLEMDS |
15863                                   awk '/^current.index:/ { print $NF }')
15864                 touch $DIR/$tdir/chloe
15865                 local last_rec2=$(changelog_users $SINGLEMDS |
15866                                   awk '/^current.index:/ { print $NF }')
15867                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15868                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15869         else
15870                 # any changelog users must be leftovers from a previous test
15871                 changelog_users $SINGLEMDS
15872                 echo "other changelog users; can't verify off"
15873         fi
15874 }
15875 run_test 160a "changelog sanity"
15876
15877 test_160b() { # LU-3587
15878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15879         remote_mds_nodsh && skip "remote MDS with nodsh"
15880         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15881                 skip "Need MDS version at least 2.2.0"
15882
15883         changelog_register || error "changelog_register failed"
15884         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15885         changelog_users $SINGLEMDS | grep -q $cl_user ||
15886                 error "User '$cl_user' not found in changelog_users"
15887
15888         local longname1=$(str_repeat a 255)
15889         local longname2=$(str_repeat b 255)
15890
15891         cd $DIR
15892         echo "creating very long named file"
15893         touch $longname1 || error "create of '$longname1' failed"
15894         echo "renaming very long named file"
15895         mv $longname1 $longname2
15896
15897         changelog_dump | grep RENME | tail -n 5
15898         rm -f $longname2
15899 }
15900 run_test 160b "Verify that very long rename doesn't crash in changelog"
15901
15902 test_160c() {
15903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15904         remote_mds_nodsh && skip "remote MDS with nodsh"
15905
15906         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15907                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15908                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15909                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15910
15911         local rc=0
15912
15913         # Registration step
15914         changelog_register || error "changelog_register failed"
15915
15916         rm -rf $DIR/$tdir
15917         mkdir -p $DIR/$tdir
15918         $MCREATE $DIR/$tdir/foo_160c
15919         changelog_chmask "-TRUNC"
15920         $TRUNCATE $DIR/$tdir/foo_160c 200
15921         changelog_chmask "+TRUNC"
15922         $TRUNCATE $DIR/$tdir/foo_160c 199
15923         changelog_dump | tail -n 5
15924         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15925         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15926 }
15927 run_test 160c "verify that changelog log catch the truncate event"
15928
15929 test_160d() {
15930         remote_mds_nodsh && skip "remote MDS with nodsh"
15931         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15933         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15934                 skip "Need MDS version at least 2.7.60"
15935
15936         # Registration step
15937         changelog_register || error "changelog_register failed"
15938
15939         mkdir -p $DIR/$tdir/migrate_dir
15940         changelog_clear 0 || error "changelog_clear failed"
15941
15942         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15943         changelog_dump | tail -n 5
15944         local migrates=$(changelog_dump | grep -c "MIGRT")
15945         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15946 }
15947 run_test 160d "verify that changelog log catch the migrate event"
15948
15949 test_160e() {
15950         remote_mds_nodsh && skip "remote MDS with nodsh"
15951
15952         # Create a user
15953         changelog_register || error "changelog_register failed"
15954
15955         local MDT0=$(facet_svc $SINGLEMDS)
15956         local rc
15957
15958         # No user (expect fail)
15959         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
15960         rc=$?
15961         if [ $rc -eq 0 ]; then
15962                 error "Should fail without user"
15963         elif [ $rc -ne 4 ]; then
15964                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
15965         fi
15966
15967         # Delete a future user (expect fail)
15968         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
15969         rc=$?
15970         if [ $rc -eq 0 ]; then
15971                 error "Deleted non-existant user cl77"
15972         elif [ $rc -ne 2 ]; then
15973                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
15974         fi
15975
15976         # Clear to a bad index (1 billion should be safe)
15977         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
15978         rc=$?
15979
15980         if [ $rc -eq 0 ]; then
15981                 error "Successfully cleared to invalid CL index"
15982         elif [ $rc -ne 22 ]; then
15983                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
15984         fi
15985 }
15986 run_test 160e "changelog negative testing (should return errors)"
15987
15988 test_160f() {
15989         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15990         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15991                 skip "Need MDS version at least 2.10.56"
15992
15993         local mdts=$(comma_list $(mdts_nodes))
15994
15995         # Create a user
15996         changelog_register || error "first changelog_register failed"
15997         changelog_register || error "second changelog_register failed"
15998         local cl_users
15999         declare -A cl_user1
16000         declare -A cl_user2
16001         local user_rec1
16002         local user_rec2
16003         local i
16004
16005         # generate some changelog records to accumulate on each MDT
16006         # use all_char because created files should be evenly distributed
16007         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16008                 error "test_mkdir $tdir failed"
16009         log "$(date +%s): creating first files"
16010         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16011                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16012                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16013         done
16014
16015         # check changelogs have been generated
16016         local start=$SECONDS
16017         local idle_time=$((MDSCOUNT * 5 + 5))
16018         local nbcl=$(changelog_dump | wc -l)
16019         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16020
16021         for param in "changelog_max_idle_time=$idle_time" \
16022                      "changelog_gc=1" \
16023                      "changelog_min_gc_interval=2" \
16024                      "changelog_min_free_cat_entries=3"; do
16025                 local MDT0=$(facet_svc $SINGLEMDS)
16026                 local var="${param%=*}"
16027                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16028
16029                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16030                 do_nodes $mdts $LCTL set_param mdd.*.$param
16031         done
16032
16033         # force cl_user2 to be idle (1st part), but also cancel the
16034         # cl_user1 records so that it is not evicted later in the test.
16035         local sleep1=$((idle_time / 2))
16036         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16037         sleep $sleep1
16038
16039         # simulate changelog catalog almost full
16040         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16041         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16042
16043         for i in $(seq $MDSCOUNT); do
16044                 cl_users=(${CL_USERS[mds$i]})
16045                 cl_user1[mds$i]="${cl_users[0]}"
16046                 cl_user2[mds$i]="${cl_users[1]}"
16047
16048                 [ -n "${cl_user1[mds$i]}" ] ||
16049                         error "mds$i: no user registered"
16050                 [ -n "${cl_user2[mds$i]}" ] ||
16051                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16052
16053                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16054                 [ -n "$user_rec1" ] ||
16055                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16056                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16057                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16058                 [ -n "$user_rec2" ] ||
16059                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16060                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16061                      "$user_rec1 + 2 == $user_rec2"
16062                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16063                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16064                               "$user_rec1 + 2, but is $user_rec2"
16065                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16066                 [ -n "$user_rec2" ] ||
16067                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16068                 [ $user_rec1 == $user_rec2 ] ||
16069                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16070                               "$user_rec1, but is $user_rec2"
16071         done
16072
16073         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16074         local sleep2=$((idle_time - (SECONDS - start) + 1))
16075         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16076         sleep $sleep2
16077
16078         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16079         # cl_user1 should be OK because it recently processed records.
16080         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16081         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16082                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16083                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16084         done
16085
16086         # ensure gc thread is done
16087         for i in $(mdts_nodes); do
16088                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16089                         error "$i: GC-thread not done"
16090         done
16091
16092         local first_rec
16093         for (( i = 1; i <= MDSCOUNT; i++ )); do
16094                 # check cl_user1 still registered
16095                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16096                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16097                 # check cl_user2 unregistered
16098                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16099                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16100
16101                 # check changelogs are present and starting at $user_rec1 + 1
16102                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16103                 [ -n "$user_rec1" ] ||
16104                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16105                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16106                             awk '{ print $1; exit; }')
16107
16108                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16109                 [ $((user_rec1 + 1)) == $first_rec ] ||
16110                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16111         done
16112 }
16113 run_test 160f "changelog garbage collect (timestamped users)"
16114
16115 test_160g() {
16116         remote_mds_nodsh && skip "remote MDS with nodsh"
16117         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16118                 skip "Need MDS version at least 2.14.55"
16119
16120         local mdts=$(comma_list $(mdts_nodes))
16121
16122         # Create a user
16123         changelog_register || error "first changelog_register failed"
16124         changelog_register || error "second changelog_register failed"
16125         local cl_users
16126         declare -A cl_user1
16127         declare -A cl_user2
16128         local user_rec1
16129         local user_rec2
16130         local i
16131
16132         # generate some changelog records to accumulate on each MDT
16133         # use all_char because created files should be evenly distributed
16134         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16135                 error "test_mkdir $tdir failed"
16136         for ((i = 0; i < MDSCOUNT; i++)); do
16137                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16138                         error "create $DIR/$tdir/d$i.1 failed"
16139         done
16140
16141         # check changelogs have been generated
16142         local nbcl=$(changelog_dump | wc -l)
16143         (( $nbcl > 0 )) || error "no changelogs found"
16144
16145         # reduce the max_idle_indexes value to make sure we exceed it
16146         for param in "changelog_max_idle_indexes=2" \
16147                      "changelog_gc=1" \
16148                      "changelog_min_gc_interval=2"; do
16149                 local MDT0=$(facet_svc $SINGLEMDS)
16150                 local var="${param%=*}"
16151                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16152
16153                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16154                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16155                         error "unable to set mdd.*.$param"
16156         done
16157
16158         local start=$SECONDS
16159         for i in $(seq $MDSCOUNT); do
16160                 cl_users=(${CL_USERS[mds$i]})
16161                 cl_user1[mds$i]="${cl_users[0]}"
16162                 cl_user2[mds$i]="${cl_users[1]}"
16163
16164                 [ -n "${cl_user1[mds$i]}" ] ||
16165                         error "mds$i: user1 is not registered"
16166                 [ -n "${cl_user2[mds$i]}" ] ||
16167                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16168
16169                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16170                 [ -n "$user_rec1" ] ||
16171                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16172                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16173                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16174                 [ -n "$user_rec2" ] ||
16175                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16176                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16177                      "$user_rec1 + 2 == $user_rec2"
16178                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16179                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16180                               "expected $user_rec1 + 2, but is $user_rec2"
16181                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16182                 [ -n "$user_rec2" ] ||
16183                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16184                 [ $user_rec1 == $user_rec2 ] ||
16185                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16186                               "expected $user_rec1, but is $user_rec2"
16187         done
16188
16189         # ensure we are past the previous changelog_min_gc_interval set above
16190         local sleep2=$((start + 2 - SECONDS))
16191         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16192         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16193         # cl_user1 should be OK because it recently processed records.
16194         for ((i = 0; i < MDSCOUNT; i++)); do
16195                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16196                         error "create $DIR/$tdir/d$i.3 failed"
16197         done
16198
16199         # ensure gc thread is done
16200         for i in $(mdts_nodes); do
16201                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16202                         error "$i: GC-thread not done"
16203         done
16204
16205         local first_rec
16206         for (( i = 1; i <= MDSCOUNT; i++ )); do
16207                 # check cl_user1 still registered
16208                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16209                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16210                 # check cl_user2 unregistered
16211                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16212                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16213
16214                 # check changelogs are present and starting at $user_rec1 + 1
16215                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16216                 [ -n "$user_rec1" ] ||
16217                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16218                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16219                             awk '{ print $1; exit; }')
16220
16221                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16222                 [ $((user_rec1 + 1)) == $first_rec ] ||
16223                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16224         done
16225 }
16226 run_test 160g "changelog garbage collect on idle records"
16227
16228 test_160h() {
16229         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16230         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16231                 skip "Need MDS version at least 2.10.56"
16232
16233         local mdts=$(comma_list $(mdts_nodes))
16234
16235         # Create a user
16236         changelog_register || error "first changelog_register failed"
16237         changelog_register || error "second changelog_register failed"
16238         local cl_users
16239         declare -A cl_user1
16240         declare -A cl_user2
16241         local user_rec1
16242         local user_rec2
16243         local i
16244
16245         # generate some changelog records to accumulate on each MDT
16246         # use all_char because created files should be evenly distributed
16247         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16248                 error "test_mkdir $tdir failed"
16249         for ((i = 0; i < MDSCOUNT; i++)); do
16250                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16251                         error "create $DIR/$tdir/d$i.1 failed"
16252         done
16253
16254         # check changelogs have been generated
16255         local nbcl=$(changelog_dump | wc -l)
16256         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16257
16258         for param in "changelog_max_idle_time=10" \
16259                      "changelog_gc=1" \
16260                      "changelog_min_gc_interval=2"; do
16261                 local MDT0=$(facet_svc $SINGLEMDS)
16262                 local var="${param%=*}"
16263                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16264
16265                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16266                 do_nodes $mdts $LCTL set_param mdd.*.$param
16267         done
16268
16269         # force cl_user2 to be idle (1st part)
16270         sleep 9
16271
16272         for i in $(seq $MDSCOUNT); do
16273                 cl_users=(${CL_USERS[mds$i]})
16274                 cl_user1[mds$i]="${cl_users[0]}"
16275                 cl_user2[mds$i]="${cl_users[1]}"
16276
16277                 [ -n "${cl_user1[mds$i]}" ] ||
16278                         error "mds$i: no user registered"
16279                 [ -n "${cl_user2[mds$i]}" ] ||
16280                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16281
16282                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16283                 [ -n "$user_rec1" ] ||
16284                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16285                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16286                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16287                 [ -n "$user_rec2" ] ||
16288                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16289                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16290                      "$user_rec1 + 2 == $user_rec2"
16291                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16292                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16293                               "$user_rec1 + 2, but is $user_rec2"
16294                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16295                 [ -n "$user_rec2" ] ||
16296                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16297                 [ $user_rec1 == $user_rec2 ] ||
16298                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16299                               "$user_rec1, but is $user_rec2"
16300         done
16301
16302         # force cl_user2 to be idle (2nd part) and to reach
16303         # changelog_max_idle_time
16304         sleep 2
16305
16306         # force each GC-thread start and block then
16307         # one per MDT/MDD, set fail_val accordingly
16308         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16309         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16310
16311         # generate more changelogs to trigger fail_loc
16312         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16313                 error "create $DIR/$tdir/${tfile}bis failed"
16314
16315         # stop MDT to stop GC-thread, should be done in back-ground as it will
16316         # block waiting for the thread to be released and exit
16317         declare -A stop_pids
16318         for i in $(seq $MDSCOUNT); do
16319                 stop mds$i &
16320                 stop_pids[mds$i]=$!
16321         done
16322
16323         for i in $(mdts_nodes); do
16324                 local facet
16325                 local nb=0
16326                 local facets=$(facets_up_on_host $i)
16327
16328                 for facet in ${facets//,/ }; do
16329                         if [[ $facet == mds* ]]; then
16330                                 nb=$((nb + 1))
16331                         fi
16332                 done
16333                 # ensure each MDS's gc threads are still present and all in "R"
16334                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16335                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16336                         error "$i: expected $nb GC-thread"
16337                 wait_update $i \
16338                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16339                         "R" 20 ||
16340                         error "$i: GC-thread not found in R-state"
16341                 # check umounts of each MDT on MDS have reached kthread_stop()
16342                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16343                         error "$i: expected $nb umount"
16344                 wait_update $i \
16345                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16346                         error "$i: umount not found in D-state"
16347         done
16348
16349         # release all GC-threads
16350         do_nodes $mdts $LCTL set_param fail_loc=0
16351
16352         # wait for MDT stop to complete
16353         for i in $(seq $MDSCOUNT); do
16354                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16355         done
16356
16357         # XXX
16358         # may try to check if any orphan changelog records are present
16359         # via ldiskfs/zfs and llog_reader...
16360
16361         # re-start/mount MDTs
16362         for i in $(seq $MDSCOUNT); do
16363                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16364                         error "Fail to start mds$i"
16365         done
16366
16367         local first_rec
16368         for i in $(seq $MDSCOUNT); do
16369                 # check cl_user1 still registered
16370                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16371                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16372                 # check cl_user2 unregistered
16373                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16374                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16375
16376                 # check changelogs are present and starting at $user_rec1 + 1
16377                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16378                 [ -n "$user_rec1" ] ||
16379                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16380                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16381                             awk '{ print $1; exit; }')
16382
16383                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16384                 [ $((user_rec1 + 1)) == $first_rec ] ||
16385                         error "mds$i: first index should be $user_rec1 + 1, " \
16386                               "but is $first_rec"
16387         done
16388 }
16389 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16390               "during mount"
16391
16392 test_160i() {
16393
16394         local mdts=$(comma_list $(mdts_nodes))
16395
16396         changelog_register || error "first changelog_register failed"
16397
16398         # generate some changelog records to accumulate on each MDT
16399         # use all_char because created files should be evenly distributed
16400         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16401                 error "test_mkdir $tdir failed"
16402         for ((i = 0; i < MDSCOUNT; i++)); do
16403                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16404                         error "create $DIR/$tdir/d$i.1 failed"
16405         done
16406
16407         # check changelogs have been generated
16408         local nbcl=$(changelog_dump | wc -l)
16409         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16410
16411         # simulate race between register and unregister
16412         # XXX as fail_loc is set per-MDS, with DNE configs the race
16413         # simulation will only occur for one MDT per MDS and for the
16414         # others the normal race scenario will take place
16415         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16416         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16417         do_nodes $mdts $LCTL set_param fail_val=1
16418
16419         # unregister 1st user
16420         changelog_deregister &
16421         local pid1=$!
16422         # wait some time for deregister work to reach race rdv
16423         sleep 2
16424         # register 2nd user
16425         changelog_register || error "2nd user register failed"
16426
16427         wait $pid1 || error "1st user deregister failed"
16428
16429         local i
16430         local last_rec
16431         declare -A LAST_REC
16432         for i in $(seq $MDSCOUNT); do
16433                 if changelog_users mds$i | grep "^cl"; then
16434                         # make sure new records are added with one user present
16435                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16436                                           awk '/^current.index:/ { print $NF }')
16437                 else
16438                         error "mds$i has no user registered"
16439                 fi
16440         done
16441
16442         # generate more changelog records to accumulate on each MDT
16443         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16444                 error "create $DIR/$tdir/${tfile}bis failed"
16445
16446         for i in $(seq $MDSCOUNT); do
16447                 last_rec=$(changelog_users $SINGLEMDS |
16448                            awk '/^current.index:/ { print $NF }')
16449                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16450                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16451                         error "changelogs are off on mds$i"
16452         done
16453 }
16454 run_test 160i "changelog user register/unregister race"
16455
16456 test_160j() {
16457         remote_mds_nodsh && skip "remote MDS with nodsh"
16458         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16459                 skip "Need MDS version at least 2.12.56"
16460
16461         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16462         stack_trap "umount $MOUNT2" EXIT
16463
16464         changelog_register || error "first changelog_register failed"
16465         stack_trap "changelog_deregister" EXIT
16466
16467         # generate some changelog
16468         # use all_char because created files should be evenly distributed
16469         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16470                 error "mkdir $tdir failed"
16471         for ((i = 0; i < MDSCOUNT; i++)); do
16472                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16473                         error "create $DIR/$tdir/d$i.1 failed"
16474         done
16475
16476         # open the changelog device
16477         exec 3>/dev/changelog-$FSNAME-MDT0000
16478         stack_trap "exec 3>&-" EXIT
16479         exec 4</dev/changelog-$FSNAME-MDT0000
16480         stack_trap "exec 4<&-" EXIT
16481
16482         # umount the first lustre mount
16483         umount $MOUNT
16484         stack_trap "mount_client $MOUNT" EXIT
16485
16486         # read changelog, which may or may not fail, but should not crash
16487         cat <&4 >/dev/null
16488
16489         # clear changelog
16490         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16491         changelog_users $SINGLEMDS | grep -q $cl_user ||
16492                 error "User $cl_user not found in changelog_users"
16493
16494         printf 'clear:'$cl_user':0' >&3
16495 }
16496 run_test 160j "client can be umounted while its chanangelog is being used"
16497
16498 test_160k() {
16499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16500         remote_mds_nodsh && skip "remote MDS with nodsh"
16501
16502         mkdir -p $DIR/$tdir/1/1
16503
16504         changelog_register || error "changelog_register failed"
16505         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16506
16507         changelog_users $SINGLEMDS | grep -q $cl_user ||
16508                 error "User '$cl_user' not found in changelog_users"
16509 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16510         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16511         rmdir $DIR/$tdir/1/1 & sleep 1
16512         mkdir $DIR/$tdir/2
16513         touch $DIR/$tdir/2/2
16514         rm -rf $DIR/$tdir/2
16515
16516         wait
16517         sleep 4
16518
16519         changelog_dump | grep rmdir || error "rmdir not recorded"
16520 }
16521 run_test 160k "Verify that changelog records are not lost"
16522
16523 # Verifies that a file passed as a parameter has recently had an operation
16524 # performed on it that has generated an MTIME changelog which contains the
16525 # correct parent FID. As files might reside on a different MDT from the
16526 # parent directory in DNE configurations, the FIDs are translated to paths
16527 # before being compared, which should be identical
16528 compare_mtime_changelog() {
16529         local file="${1}"
16530         local mdtidx
16531         local mtime
16532         local cl_fid
16533         local pdir
16534         local dir
16535
16536         mdtidx=$($LFS getstripe --mdt-index $file)
16537         mdtidx=$(printf "%04x" $mdtidx)
16538
16539         # Obtain the parent FID from the MTIME changelog
16540         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16541         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16542
16543         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16544         [ -z "$cl_fid" ] && error "parent FID not present"
16545
16546         # Verify that the path for the parent FID is the same as the path for
16547         # the test directory
16548         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16549
16550         dir=$(dirname $1)
16551
16552         [[ "${pdir%/}" == "$dir" ]] ||
16553                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16554 }
16555
16556 test_160l() {
16557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16558
16559         remote_mds_nodsh && skip "remote MDS with nodsh"
16560         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16561                 skip "Need MDS version at least 2.13.55"
16562
16563         local cl_user
16564
16565         changelog_register || error "changelog_register failed"
16566         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16567
16568         changelog_users $SINGLEMDS | grep -q $cl_user ||
16569                 error "User '$cl_user' not found in changelog_users"
16570
16571         # Clear some types so that MTIME changelogs are generated
16572         changelog_chmask "-CREAT"
16573         changelog_chmask "-CLOSE"
16574
16575         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16576
16577         # Test CL_MTIME during setattr
16578         touch $DIR/$tdir/$tfile
16579         compare_mtime_changelog $DIR/$tdir/$tfile
16580
16581         # Test CL_MTIME during close
16582         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16583         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16584 }
16585 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16586
16587 test_160m() {
16588         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16589         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16590                 skip "Need MDS version at least 2.14.51"
16591         local cl_users
16592         local cl_user1
16593         local cl_user2
16594         local pid1
16595
16596         # Create a user
16597         changelog_register || error "first changelog_register failed"
16598         changelog_register || error "second changelog_register failed"
16599
16600         cl_users=(${CL_USERS[mds1]})
16601         cl_user1="${cl_users[0]}"
16602         cl_user2="${cl_users[1]}"
16603         # generate some changelog records to accumulate on MDT0
16604         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16605         createmany -m $DIR/$tdir/$tfile 50 ||
16606                 error "create $DIR/$tdir/$tfile failed"
16607         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16608         rm -f $DIR/$tdir
16609
16610         # check changelogs have been generated
16611         local nbcl=$(changelog_dump | wc -l)
16612         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16613
16614 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16615         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16616
16617         __changelog_clear mds1 $cl_user1 +10
16618         __changelog_clear mds1 $cl_user2 0 &
16619         pid1=$!
16620         sleep 2
16621         __changelog_clear mds1 $cl_user1 0 ||
16622                 error "fail to cancel record for $cl_user1"
16623         wait $pid1
16624         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16625 }
16626 run_test 160m "Changelog clear race"
16627
16628 test_160n() {
16629         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16630         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16631                 skip "Need MDS version at least 2.14.51"
16632         local cl_users
16633         local cl_user1
16634         local cl_user2
16635         local pid1
16636         local first_rec
16637         local last_rec=0
16638
16639         # Create a user
16640         changelog_register || error "first changelog_register failed"
16641
16642         cl_users=(${CL_USERS[mds1]})
16643         cl_user1="${cl_users[0]}"
16644
16645         # generate some changelog records to accumulate on MDT0
16646         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16647         first_rec=$(changelog_users $SINGLEMDS |
16648                         awk '/^current.index:/ { print $NF }')
16649         while (( last_rec < (( first_rec + 65000)) )); do
16650                 createmany -m $DIR/$tdir/$tfile 10000 ||
16651                         error "create $DIR/$tdir/$tfile failed"
16652
16653                 for i in $(seq 0 10000); do
16654                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16655                                 > /dev/null
16656                 done
16657
16658                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16659                         error "unlinkmany failed unlink"
16660                 last_rec=$(changelog_users $SINGLEMDS |
16661                         awk '/^current.index:/ { print $NF }')
16662                 echo last record $last_rec
16663                 (( last_rec == 0 )) && error "no changelog found"
16664         done
16665
16666 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16667         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16668
16669         __changelog_clear mds1 $cl_user1 0 &
16670         pid1=$!
16671         sleep 2
16672         __changelog_clear mds1 $cl_user1 0 ||
16673                 error "fail to cancel record for $cl_user1"
16674         wait $pid1
16675         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16676 }
16677 run_test 160n "Changelog destroy race"
16678
16679 test_160o() {
16680         local mdt="$(facet_svc $SINGLEMDS)"
16681
16682         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16683         remote_mds_nodsh && skip "remote MDS with nodsh"
16684         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16685                 skip "Need MDS version at least 2.14.52"
16686
16687         changelog_register --user test_160o -m unlnk+close+open ||
16688                 error "changelog_register failed"
16689
16690         do_facet $SINGLEMDS $LCTL --device $mdt \
16691                                 changelog_register -u "Tt3_-#" &&
16692                 error "bad symbols in name should fail"
16693
16694         do_facet $SINGLEMDS $LCTL --device $mdt \
16695                                 changelog_register -u test_160o &&
16696                 error "the same name registration should fail"
16697
16698         do_facet $SINGLEMDS $LCTL --device $mdt \
16699                         changelog_register -u test_160toolongname &&
16700                 error "too long name registration should fail"
16701
16702         changelog_chmask "MARK+HSM"
16703         lctl get_param mdd.*.changelog*mask
16704         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16705         changelog_users $SINGLEMDS | grep -q $cl_user ||
16706                 error "User $cl_user not found in changelog_users"
16707         #verify username
16708         echo $cl_user | grep -q test_160o ||
16709                 error "User $cl_user has no specific name 'test160o'"
16710
16711         # change something
16712         changelog_clear 0 || error "changelog_clear failed"
16713         # generate some changelog records to accumulate on MDT0
16714         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16715         touch $DIR/$tdir/$tfile                 # open 1
16716
16717         OPENS=$(changelog_dump | grep -c "OPEN")
16718         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16719
16720         # must be no MKDIR it wasn't set as user mask
16721         MKDIR=$(changelog_dump | grep -c "MKDIR")
16722         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16723
16724         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16725                                 mdd.$mdt.changelog_current_mask -n)
16726         # register maskless user
16727         changelog_register || error "changelog_register failed"
16728         # effective mask should be not changed because it is not minimal
16729         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16730                                 mdd.$mdt.changelog_current_mask -n)
16731         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16732         # set server mask to minimal value
16733         changelog_chmask "MARK"
16734         # check effective mask again, should be treated as DEFMASK now
16735         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16736                                 mdd.$mdt.changelog_current_mask -n)
16737         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16738
16739         do_facet $SINGLEMDS $LCTL --device $mdt \
16740                                 changelog_deregister -u test_160o ||
16741                 error "cannot deregister by name"
16742 }
16743 run_test 160o "changelog user name and mask"
16744
16745 test_160p() {
16746         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16747         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16748                 skip "Need MDS version at least 2.14.51"
16749         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16750         local cl_users
16751         local cl_user1
16752         local entry_count
16753
16754         # Create a user
16755         changelog_register || error "first changelog_register failed"
16756
16757         cl_users=(${CL_USERS[mds1]})
16758         cl_user1="${cl_users[0]}"
16759
16760         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16761         createmany -m $DIR/$tdir/$tfile 50 ||
16762                 error "create $DIR/$tdir/$tfile failed"
16763         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16764         rm -rf $DIR/$tdir
16765
16766         # check changelogs have been generated
16767         entry_count=$(changelog_dump | wc -l)
16768         ((entry_count != 0)) || error "no changelog entries found"
16769
16770         # remove changelog_users and check that orphan entries are removed
16771         stop mds1
16772         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $(mdsdevname 1)"
16773         start mds1 || error "cannot start mdt"
16774         entry_count=$(changelog_dump | wc -l)
16775         ((entry_count == 0)) ||
16776                 error "found $entry_count changelog entries, expected none"
16777 }
16778 run_test 160p "Changelog orphan cleanup with no users"
16779
16780 test_160q() {
16781         local mdt="$(facet_svc $SINGLEMDS)"
16782         local clu
16783
16784         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16785         remote_mds_nodsh && skip "remote MDS with nodsh"
16786         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16787                 skip "Need MDS version at least 2.14.54"
16788
16789         # set server mask to minimal value like server init does
16790         changelog_chmask "MARK"
16791         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16792                 error "changelog_register failed"
16793         # check effective mask again, should be treated as DEFMASK now
16794         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16795                                 mdd.$mdt.changelog_current_mask -n)
16796         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
16797                 error "changelog_deregister failed"
16798         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16799 }
16800 run_test 160q "changelog effective mask is DEFMASK if not set"
16801
16802 test_160s() {
16803         remote_mds_nodsh && skip "remote MDS with nodsh"
16804         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
16805                 skip "Need MDS version at least 2.14.55"
16806
16807         local mdts=$(comma_list $(mdts_nodes))
16808
16809         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
16810         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
16811                                        fail_val=$((24 * 3600 * 10))
16812
16813         # Create a user which is 10 days old
16814         changelog_register || error "first changelog_register failed"
16815         local cl_users
16816         declare -A cl_user1
16817         local i
16818
16819         # generate some changelog records to accumulate on each MDT
16820         # use all_char because created files should be evenly distributed
16821         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16822                 error "test_mkdir $tdir failed"
16823         for ((i = 0; i < MDSCOUNT; i++)); do
16824                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16825                         error "create $DIR/$tdir/d$i.1 failed"
16826         done
16827
16828         # check changelogs have been generated
16829         local nbcl=$(changelog_dump | wc -l)
16830         (( nbcl > 0 )) || error "no changelogs found"
16831
16832         # reduce the max_idle_indexes value to make sure we exceed it
16833         for param in "changelog_max_idle_indexes=2097446912" \
16834                      "changelog_max_idle_time=2592000" \
16835                      "changelog_gc=1" \
16836                      "changelog_min_gc_interval=2"; do
16837                 local MDT0=$(facet_svc $SINGLEMDS)
16838                 local var="${param%=*}"
16839                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16840
16841                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16842                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16843                         error "unable to set mdd.*.$param"
16844         done
16845
16846         local start=$SECONDS
16847         for i in $(seq $MDSCOUNT); do
16848                 cl_users=(${CL_USERS[mds$i]})
16849                 cl_user1[mds$i]="${cl_users[0]}"
16850
16851                 [[ -n "${cl_user1[mds$i]}" ]] ||
16852                         error "mds$i: no user registered"
16853         done
16854
16855         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
16856         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
16857
16858         # ensure we are past the previous changelog_min_gc_interval set above
16859         local sleep2=$((start + 2 - SECONDS))
16860         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16861
16862         # Generate one more changelog to trigger GC
16863         for ((i = 0; i < MDSCOUNT; i++)); do
16864                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
16865                         error "create $DIR/$tdir/d$i.3 failed"
16866         done
16867
16868         # ensure gc thread is done
16869         for node in $(mdts_nodes); do
16870                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
16871                         error "$node: GC-thread not done"
16872         done
16873
16874         do_nodes $mdts $LCTL set_param fail_loc=0
16875
16876         for (( i = 1; i <= MDSCOUNT; i++ )); do
16877                 # check cl_user1 is purged
16878                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
16879                         error "mds$i: User ${cl_user1[mds$i]} is registered"
16880         done
16881         return 0
16882 }
16883 run_test 160s "changelog garbage collect on idle records * time"
16884
16885 test_161a() {
16886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16887
16888         test_mkdir -c1 $DIR/$tdir
16889         cp /etc/hosts $DIR/$tdir/$tfile
16890         test_mkdir -c1 $DIR/$tdir/foo1
16891         test_mkdir -c1 $DIR/$tdir/foo2
16892         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16893         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16894         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16895         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16896         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16897         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16898                 $LFS fid2path $DIR $FID
16899                 error "bad link ea"
16900         fi
16901         # middle
16902         rm $DIR/$tdir/foo2/zachary
16903         # last
16904         rm $DIR/$tdir/foo2/thor
16905         # first
16906         rm $DIR/$tdir/$tfile
16907         # rename
16908         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16909         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16910                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16911         rm $DIR/$tdir/foo2/maggie
16912
16913         # overflow the EA
16914         local longname=$tfile.avg_len_is_thirty_two_
16915         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16916                 error_noexit 'failed to unlink many hardlinks'" EXIT
16917         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16918                 error "failed to hardlink many files"
16919         links=$($LFS fid2path $DIR $FID | wc -l)
16920         echo -n "${links}/1000 links in link EA"
16921         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16922 }
16923 run_test 161a "link ea sanity"
16924
16925 test_161b() {
16926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16927         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16928
16929         local MDTIDX=1
16930         local remote_dir=$DIR/$tdir/remote_dir
16931
16932         mkdir -p $DIR/$tdir
16933         $LFS mkdir -i $MDTIDX $remote_dir ||
16934                 error "create remote directory failed"
16935
16936         cp /etc/hosts $remote_dir/$tfile
16937         mkdir -p $remote_dir/foo1
16938         mkdir -p $remote_dir/foo2
16939         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16940         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16941         ln $remote_dir/$tfile $remote_dir/foo1/luna
16942         ln $remote_dir/$tfile $remote_dir/foo2/thor
16943
16944         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16945                      tr -d ']')
16946         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16947                 $LFS fid2path $DIR $FID
16948                 error "bad link ea"
16949         fi
16950         # middle
16951         rm $remote_dir/foo2/zachary
16952         # last
16953         rm $remote_dir/foo2/thor
16954         # first
16955         rm $remote_dir/$tfile
16956         # rename
16957         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16958         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16959         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16960                 $LFS fid2path $DIR $FID
16961                 error "bad link rename"
16962         fi
16963         rm $remote_dir/foo2/maggie
16964
16965         # overflow the EA
16966         local longname=filename_avg_len_is_thirty_two_
16967         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
16968                 error "failed to hardlink many files"
16969         links=$($LFS fid2path $DIR $FID | wc -l)
16970         echo -n "${links}/1000 links in link EA"
16971         [[ ${links} -gt 60 ]] ||
16972                 error "expected at least 60 links in link EA"
16973         unlinkmany $remote_dir/foo2/$longname 1000 ||
16974         error "failed to unlink many hardlinks"
16975 }
16976 run_test 161b "link ea sanity under remote directory"
16977
16978 test_161c() {
16979         remote_mds_nodsh && skip "remote MDS with nodsh"
16980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16981         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
16982                 skip "Need MDS version at least 2.1.5"
16983
16984         # define CLF_RENAME_LAST 0x0001
16985         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
16986         changelog_register || error "changelog_register failed"
16987
16988         rm -rf $DIR/$tdir
16989         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
16990         touch $DIR/$tdir/foo_161c
16991         touch $DIR/$tdir/bar_161c
16992         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16993         changelog_dump | grep RENME | tail -n 5
16994         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16995         changelog_clear 0 || error "changelog_clear failed"
16996         if [ x$flags != "x0x1" ]; then
16997                 error "flag $flags is not 0x1"
16998         fi
16999
17000         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17001         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17002         touch $DIR/$tdir/foo_161c
17003         touch $DIR/$tdir/bar_161c
17004         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17005         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17006         changelog_dump | grep RENME | tail -n 5
17007         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17008         changelog_clear 0 || error "changelog_clear failed"
17009         if [ x$flags != "x0x0" ]; then
17010                 error "flag $flags is not 0x0"
17011         fi
17012         echo "rename overwrite a target having nlink > 1," \
17013                 "changelog record has flags of $flags"
17014
17015         # rename doesn't overwrite a target (changelog flag 0x0)
17016         touch $DIR/$tdir/foo_161c
17017         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17018         changelog_dump | grep RENME | tail -n 5
17019         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17020         changelog_clear 0 || error "changelog_clear failed"
17021         if [ x$flags != "x0x0" ]; then
17022                 error "flag $flags is not 0x0"
17023         fi
17024         echo "rename doesn't overwrite a target," \
17025                 "changelog record has flags of $flags"
17026
17027         # define CLF_UNLINK_LAST 0x0001
17028         # unlink a file having nlink = 1 (changelog flag 0x1)
17029         rm -f $DIR/$tdir/foo2_161c
17030         changelog_dump | grep UNLNK | tail -n 5
17031         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17032         changelog_clear 0 || error "changelog_clear failed"
17033         if [ x$flags != "x0x1" ]; then
17034                 error "flag $flags is not 0x1"
17035         fi
17036         echo "unlink a file having nlink = 1," \
17037                 "changelog record has flags of $flags"
17038
17039         # unlink a file having nlink > 1 (changelog flag 0x0)
17040         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17041         rm -f $DIR/$tdir/foobar_161c
17042         changelog_dump | grep UNLNK | tail -n 5
17043         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17044         changelog_clear 0 || error "changelog_clear failed"
17045         if [ x$flags != "x0x0" ]; then
17046                 error "flag $flags is not 0x0"
17047         fi
17048         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17049 }
17050 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17051
17052 test_161d() {
17053         remote_mds_nodsh && skip "remote MDS with nodsh"
17054         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17055
17056         local pid
17057         local fid
17058
17059         changelog_register || error "changelog_register failed"
17060
17061         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17062         # interfer with $MOUNT/.lustre/fid/ access
17063         mkdir $DIR/$tdir
17064         [[ $? -eq 0 ]] || error "mkdir failed"
17065
17066         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17067         $LCTL set_param fail_loc=0x8000140c
17068         # 5s pause
17069         $LCTL set_param fail_val=5
17070
17071         # create file
17072         echo foofoo > $DIR/$tdir/$tfile &
17073         pid=$!
17074
17075         # wait for create to be delayed
17076         sleep 2
17077
17078         ps -p $pid
17079         [[ $? -eq 0 ]] || error "create should be blocked"
17080
17081         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17082         stack_trap "rm -f $tempfile"
17083         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17084         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17085         # some delay may occur during ChangeLog publishing and file read just
17086         # above, that could allow file write to happen finally
17087         [[ -s $tempfile ]] && echo "file should be empty"
17088
17089         $LCTL set_param fail_loc=0
17090
17091         wait $pid
17092         [[ $? -eq 0 ]] || error "create failed"
17093 }
17094 run_test 161d "create with concurrent .lustre/fid access"
17095
17096 check_path() {
17097         local expected="$1"
17098         shift
17099         local fid="$2"
17100
17101         local path
17102         path=$($LFS fid2path "$@")
17103         local rc=$?
17104
17105         if [ $rc -ne 0 ]; then
17106                 error "path looked up of '$expected' failed: rc=$rc"
17107         elif [ "$path" != "$expected" ]; then
17108                 error "path looked up '$path' instead of '$expected'"
17109         else
17110                 echo "FID '$fid' resolves to path '$path' as expected"
17111         fi
17112 }
17113
17114 test_162a() { # was test_162
17115         test_mkdir -p -c1 $DIR/$tdir/d2
17116         touch $DIR/$tdir/d2/$tfile
17117         touch $DIR/$tdir/d2/x1
17118         touch $DIR/$tdir/d2/x2
17119         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17120         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17121         # regular file
17122         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17123         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17124
17125         # softlink
17126         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17127         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17128         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17129
17130         # softlink to wrong file
17131         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17132         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17133         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17134
17135         # hardlink
17136         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17137         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17138         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17139         # fid2path dir/fsname should both work
17140         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17141         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17142
17143         # hardlink count: check that there are 2 links
17144         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17145         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17146
17147         # hardlink indexing: remove the first link
17148         rm $DIR/$tdir/d2/p/q/r/hlink
17149         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17150 }
17151 run_test 162a "path lookup sanity"
17152
17153 test_162b() {
17154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17155         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17156
17157         mkdir $DIR/$tdir
17158         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17159                                 error "create striped dir failed"
17160
17161         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17162                                         tail -n 1 | awk '{print $2}')
17163         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17164
17165         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17166         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17167
17168         # regular file
17169         for ((i=0;i<5;i++)); do
17170                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17171                         error "get fid for f$i failed"
17172                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17173
17174                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17175                         error "get fid for d$i failed"
17176                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17177         done
17178
17179         return 0
17180 }
17181 run_test 162b "striped directory path lookup sanity"
17182
17183 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17184 test_162c() {
17185         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17186                 skip "Need MDS version at least 2.7.51"
17187
17188         local lpath=$tdir.local
17189         local rpath=$tdir.remote
17190
17191         test_mkdir $DIR/$lpath
17192         test_mkdir $DIR/$rpath
17193
17194         for ((i = 0; i <= 101; i++)); do
17195                 lpath="$lpath/$i"
17196                 mkdir $DIR/$lpath
17197                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17198                         error "get fid for local directory $DIR/$lpath failed"
17199                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17200
17201                 rpath="$rpath/$i"
17202                 test_mkdir $DIR/$rpath
17203                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17204                         error "get fid for remote directory $DIR/$rpath failed"
17205                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17206         done
17207
17208         return 0
17209 }
17210 run_test 162c "fid2path works with paths 100 or more directories deep"
17211
17212 oalr_event_count() {
17213         local event="${1}"
17214         local trace="${2}"
17215
17216         awk -v name="${FSNAME}-OST0000" \
17217             -v event="${event}" \
17218             '$1 == "TRACE" && $2 == event && $3 == name' \
17219             "${trace}" |
17220         wc -l
17221 }
17222
17223 oalr_expect_event_count() {
17224         local event="${1}"
17225         local trace="${2}"
17226         local expect="${3}"
17227         local count
17228
17229         count=$(oalr_event_count "${event}" "${trace}")
17230         if ((count == expect)); then
17231                 return 0
17232         fi
17233
17234         error_noexit "${event} event count was '${count}', expected ${expect}"
17235         cat "${trace}" >&2
17236         exit 1
17237 }
17238
17239 cleanup_165() {
17240         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17241         stop ost1
17242         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17243 }
17244
17245 setup_165() {
17246         sync # Flush previous IOs so we can count log entries.
17247         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17248         stack_trap cleanup_165 EXIT
17249 }
17250
17251 test_165a() {
17252         local trace="/tmp/${tfile}.trace"
17253         local rc
17254         local count
17255
17256         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17257                 skip "OFD access log unsupported"
17258
17259         setup_165
17260         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17261         sleep 5
17262
17263         do_facet ost1 ofd_access_log_reader --list
17264         stop ost1
17265
17266         do_facet ost1 killall -TERM ofd_access_log_reader
17267         wait
17268         rc=$?
17269
17270         if ((rc != 0)); then
17271                 error "ofd_access_log_reader exited with rc = '${rc}'"
17272         fi
17273
17274         # Parse trace file for discovery events:
17275         oalr_expect_event_count alr_log_add "${trace}" 1
17276         oalr_expect_event_count alr_log_eof "${trace}" 1
17277         oalr_expect_event_count alr_log_free "${trace}" 1
17278 }
17279 run_test 165a "ofd access log discovery"
17280
17281 test_165b() {
17282         local trace="/tmp/${tfile}.trace"
17283         local file="${DIR}/${tfile}"
17284         local pfid1
17285         local pfid2
17286         local -a entry
17287         local rc
17288         local count
17289         local size
17290         local flags
17291
17292         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17293                 skip "OFD access log unsupported"
17294
17295         setup_165
17296         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17297         sleep 5
17298
17299         do_facet ost1 ofd_access_log_reader --list
17300
17301         lfs setstripe -c 1 -i 0 "${file}"
17302         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17303                 error "cannot create '${file}'"
17304
17305         sleep 5
17306         do_facet ost1 killall -TERM ofd_access_log_reader
17307         wait
17308         rc=$?
17309
17310         if ((rc != 0)); then
17311                 error "ofd_access_log_reader exited with rc = '${rc}'"
17312         fi
17313
17314         oalr_expect_event_count alr_log_entry "${trace}" 1
17315
17316         pfid1=$($LFS path2fid "${file}")
17317
17318         # 1     2             3   4    5     6   7    8    9     10
17319         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17320         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17321
17322         echo "entry = '${entry[*]}'" >&2
17323
17324         pfid2=${entry[4]}
17325         if [[ "${pfid1}" != "${pfid2}" ]]; then
17326                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17327         fi
17328
17329         size=${entry[8]}
17330         if ((size != 1048576)); then
17331                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17332         fi
17333
17334         flags=${entry[10]}
17335         if [[ "${flags}" != "w" ]]; then
17336                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17337         fi
17338
17339         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17340         sleep 5
17341
17342         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17343                 error "cannot read '${file}'"
17344         sleep 5
17345
17346         do_facet ost1 killall -TERM ofd_access_log_reader
17347         wait
17348         rc=$?
17349
17350         if ((rc != 0)); then
17351                 error "ofd_access_log_reader exited with rc = '${rc}'"
17352         fi
17353
17354         oalr_expect_event_count alr_log_entry "${trace}" 1
17355
17356         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17357         echo "entry = '${entry[*]}'" >&2
17358
17359         pfid2=${entry[4]}
17360         if [[ "${pfid1}" != "${pfid2}" ]]; then
17361                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17362         fi
17363
17364         size=${entry[8]}
17365         if ((size != 524288)); then
17366                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17367         fi
17368
17369         flags=${entry[10]}
17370         if [[ "${flags}" != "r" ]]; then
17371                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17372         fi
17373 }
17374 run_test 165b "ofd access log entries are produced and consumed"
17375
17376 test_165c() {
17377         local trace="/tmp/${tfile}.trace"
17378         local file="${DIR}/${tdir}/${tfile}"
17379
17380         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17381                 skip "OFD access log unsupported"
17382
17383         test_mkdir "${DIR}/${tdir}"
17384
17385         setup_165
17386         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17387         sleep 5
17388
17389         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17390
17391         # 4096 / 64 = 64. Create twice as many entries.
17392         for ((i = 0; i < 128; i++)); do
17393                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17394                         error "cannot create file"
17395         done
17396
17397         sync
17398
17399         do_facet ost1 killall -TERM ofd_access_log_reader
17400         wait
17401         rc=$?
17402         if ((rc != 0)); then
17403                 error "ofd_access_log_reader exited with rc = '${rc}'"
17404         fi
17405
17406         unlinkmany  "${file}-%d" 128
17407 }
17408 run_test 165c "full ofd access logs do not block IOs"
17409
17410 oal_get_read_count() {
17411         local stats="$1"
17412
17413         # STATS lustre-OST0001 alr_read_count 1
17414
17415         do_facet ost1 cat "${stats}" |
17416         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17417              END { print count; }'
17418 }
17419
17420 oal_expect_read_count() {
17421         local stats="$1"
17422         local count
17423         local expect="$2"
17424
17425         # Ask ofd_access_log_reader to write stats.
17426         do_facet ost1 killall -USR1 ofd_access_log_reader
17427
17428         # Allow some time for things to happen.
17429         sleep 1
17430
17431         count=$(oal_get_read_count "${stats}")
17432         if ((count == expect)); then
17433                 return 0
17434         fi
17435
17436         error_noexit "bad read count, got ${count}, expected ${expect}"
17437         do_facet ost1 cat "${stats}" >&2
17438         exit 1
17439 }
17440
17441 test_165d() {
17442         local stats="/tmp/${tfile}.stats"
17443         local file="${DIR}/${tdir}/${tfile}"
17444         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17445
17446         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17447                 skip "OFD access log unsupported"
17448
17449         test_mkdir "${DIR}/${tdir}"
17450
17451         setup_165
17452         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17453         sleep 5
17454
17455         lfs setstripe -c 1 -i 0 "${file}"
17456
17457         do_facet ost1 lctl set_param "${param}=rw"
17458         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17459                 error "cannot create '${file}'"
17460         oal_expect_read_count "${stats}" 1
17461
17462         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17463                 error "cannot read '${file}'"
17464         oal_expect_read_count "${stats}" 2
17465
17466         do_facet ost1 lctl set_param "${param}=r"
17467         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17468                 error "cannot create '${file}'"
17469         oal_expect_read_count "${stats}" 2
17470
17471         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17472                 error "cannot read '${file}'"
17473         oal_expect_read_count "${stats}" 3
17474
17475         do_facet ost1 lctl set_param "${param}=w"
17476         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17477                 error "cannot create '${file}'"
17478         oal_expect_read_count "${stats}" 4
17479
17480         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17481                 error "cannot read '${file}'"
17482         oal_expect_read_count "${stats}" 4
17483
17484         do_facet ost1 lctl set_param "${param}=0"
17485         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17486                 error "cannot create '${file}'"
17487         oal_expect_read_count "${stats}" 4
17488
17489         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17490                 error "cannot read '${file}'"
17491         oal_expect_read_count "${stats}" 4
17492
17493         do_facet ost1 killall -TERM ofd_access_log_reader
17494         wait
17495         rc=$?
17496         if ((rc != 0)); then
17497                 error "ofd_access_log_reader exited with rc = '${rc}'"
17498         fi
17499 }
17500 run_test 165d "ofd_access_log mask works"
17501
17502 test_165e() {
17503         local stats="/tmp/${tfile}.stats"
17504         local file0="${DIR}/${tdir}-0/${tfile}"
17505         local file1="${DIR}/${tdir}-1/${tfile}"
17506
17507         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17508                 skip "OFD access log unsupported"
17509
17510         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17511
17512         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17513         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17514
17515         lfs setstripe -c 1 -i 0 "${file0}"
17516         lfs setstripe -c 1 -i 0 "${file1}"
17517
17518         setup_165
17519         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17520         sleep 5
17521
17522         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17523                 error "cannot create '${file0}'"
17524         sync
17525         oal_expect_read_count "${stats}" 0
17526
17527         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17528                 error "cannot create '${file1}'"
17529         sync
17530         oal_expect_read_count "${stats}" 1
17531
17532         do_facet ost1 killall -TERM ofd_access_log_reader
17533         wait
17534         rc=$?
17535         if ((rc != 0)); then
17536                 error "ofd_access_log_reader exited with rc = '${rc}'"
17537         fi
17538 }
17539 run_test 165e "ofd_access_log MDT index filter works"
17540
17541 test_165f() {
17542         local trace="/tmp/${tfile}.trace"
17543         local rc
17544         local count
17545
17546         setup_165
17547         do_facet ost1 timeout 60 ofd_access_log_reader \
17548                 --exit-on-close --debug=- --trace=- > "${trace}" &
17549         sleep 5
17550         stop ost1
17551
17552         wait
17553         rc=$?
17554
17555         if ((rc != 0)); then
17556                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17557                 cat "${trace}"
17558                 exit 1
17559         fi
17560 }
17561 run_test 165f "ofd_access_log_reader --exit-on-close works"
17562
17563 test_169() {
17564         # do directio so as not to populate the page cache
17565         log "creating a 10 Mb file"
17566         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17567                 error "multiop failed while creating a file"
17568         log "starting reads"
17569         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17570         log "truncating the file"
17571         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17572                 error "multiop failed while truncating the file"
17573         log "killing dd"
17574         kill %+ || true # reads might have finished
17575         echo "wait until dd is finished"
17576         wait
17577         log "removing the temporary file"
17578         rm -rf $DIR/$tfile || error "tmp file removal failed"
17579 }
17580 run_test 169 "parallel read and truncate should not deadlock"
17581
17582 test_170() {
17583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17584
17585         $LCTL clear     # bug 18514
17586         $LCTL debug_daemon start $TMP/${tfile}_log_good
17587         touch $DIR/$tfile
17588         $LCTL debug_daemon stop
17589         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17590                 error "sed failed to read log_good"
17591
17592         $LCTL debug_daemon start $TMP/${tfile}_log_good
17593         rm -rf $DIR/$tfile
17594         $LCTL debug_daemon stop
17595
17596         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17597                error "lctl df log_bad failed"
17598
17599         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17600         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17601
17602         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17603         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17604
17605         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17606                 error "bad_line good_line1 good_line2 are empty"
17607
17608         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17609         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17610         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17611
17612         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17613         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17614         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17615
17616         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17617                 error "bad_line_new good_line_new are empty"
17618
17619         local expected_good=$((good_line1 + good_line2*2))
17620
17621         rm -f $TMP/${tfile}*
17622         # LU-231, short malformed line may not be counted into bad lines
17623         if [ $bad_line -ne $bad_line_new ] &&
17624                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17625                 error "expected $bad_line bad lines, but got $bad_line_new"
17626                 return 1
17627         fi
17628
17629         if [ $expected_good -ne $good_line_new ]; then
17630                 error "expected $expected_good good lines, but got $good_line_new"
17631                 return 2
17632         fi
17633         true
17634 }
17635 run_test 170 "test lctl df to handle corrupted log ====================="
17636
17637 test_171() { # bug20592
17638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17639
17640         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17641         $LCTL set_param fail_loc=0x50e
17642         $LCTL set_param fail_val=3000
17643         multiop_bg_pause $DIR/$tfile O_s || true
17644         local MULTIPID=$!
17645         kill -USR1 $MULTIPID
17646         # cause log dump
17647         sleep 3
17648         wait $MULTIPID
17649         if dmesg | grep "recursive fault"; then
17650                 error "caught a recursive fault"
17651         fi
17652         $LCTL set_param fail_loc=0
17653         true
17654 }
17655 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17656
17657 # it would be good to share it with obdfilter-survey/iokit-libecho code
17658 setup_obdecho_osc () {
17659         local rc=0
17660         local ost_nid=$1
17661         local obdfilter_name=$2
17662         echo "Creating new osc for $obdfilter_name on $ost_nid"
17663         # make sure we can find loopback nid
17664         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17665
17666         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17667                            ${obdfilter_name}_osc_UUID || rc=2; }
17668         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17669                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17670         return $rc
17671 }
17672
17673 cleanup_obdecho_osc () {
17674         local obdfilter_name=$1
17675         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17676         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17677         return 0
17678 }
17679
17680 obdecho_test() {
17681         local OBD=$1
17682         local node=$2
17683         local pages=${3:-64}
17684         local rc=0
17685         local id
17686
17687         local count=10
17688         local obd_size=$(get_obd_size $node $OBD)
17689         local page_size=$(get_page_size $node)
17690         if [[ -n "$obd_size" ]]; then
17691                 local new_count=$((obd_size / (pages * page_size / 1024)))
17692                 [[ $new_count -ge $count ]] || count=$new_count
17693         fi
17694
17695         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17696         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17697                            rc=2; }
17698         if [ $rc -eq 0 ]; then
17699             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17700             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17701         fi
17702         echo "New object id is $id"
17703         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17704                            rc=4; }
17705         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17706                            "test_brw $count w v $pages $id" || rc=4; }
17707         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17708                            rc=4; }
17709         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17710                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17711         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17712                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17713         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17714         return $rc
17715 }
17716
17717 test_180a() {
17718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17719
17720         if ! [ -d /sys/fs/lustre/echo_client ] &&
17721            ! module_loaded obdecho; then
17722                 load_module obdecho/obdecho &&
17723                         stack_trap "rmmod obdecho" EXIT ||
17724                         error "unable to load obdecho on client"
17725         fi
17726
17727         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17728         local host=$($LCTL get_param -n osc.$osc.import |
17729                      awk '/current_connection:/ { print $2 }' )
17730         local target=$($LCTL get_param -n osc.$osc.import |
17731                        awk '/target:/ { print $2 }' )
17732         target=${target%_UUID}
17733
17734         if [ -n "$target" ]; then
17735                 setup_obdecho_osc $host $target &&
17736                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17737                         { error "obdecho setup failed with $?"; return; }
17738
17739                 obdecho_test ${target}_osc client ||
17740                         error "obdecho_test failed on ${target}_osc"
17741         else
17742                 $LCTL get_param osc.$osc.import
17743                 error "there is no osc.$osc.import target"
17744         fi
17745 }
17746 run_test 180a "test obdecho on osc"
17747
17748 test_180b() {
17749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17750         remote_ost_nodsh && skip "remote OST with nodsh"
17751
17752         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17753                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17754                 error "failed to load module obdecho"
17755
17756         local target=$(do_facet ost1 $LCTL dl |
17757                        awk '/obdfilter/ { print $4; exit; }')
17758
17759         if [ -n "$target" ]; then
17760                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17761         else
17762                 do_facet ost1 $LCTL dl
17763                 error "there is no obdfilter target on ost1"
17764         fi
17765 }
17766 run_test 180b "test obdecho directly on obdfilter"
17767
17768 test_180c() { # LU-2598
17769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17770         remote_ost_nodsh && skip "remote OST with nodsh"
17771         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17772                 skip "Need MDS version at least 2.4.0"
17773
17774         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17775                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17776                 error "failed to load module obdecho"
17777
17778         local target=$(do_facet ost1 $LCTL dl |
17779                        awk '/obdfilter/ { print $4; exit; }')
17780
17781         if [ -n "$target" ]; then
17782                 local pages=16384 # 64MB bulk I/O RPC size
17783
17784                 obdecho_test "$target" ost1 "$pages" ||
17785                         error "obdecho_test with pages=$pages failed with $?"
17786         else
17787                 do_facet ost1 $LCTL dl
17788                 error "there is no obdfilter target on ost1"
17789         fi
17790 }
17791 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17792
17793 test_181() { # bug 22177
17794         test_mkdir $DIR/$tdir
17795         # create enough files to index the directory
17796         createmany -o $DIR/$tdir/foobar 4000
17797         # print attributes for debug purpose
17798         lsattr -d .
17799         # open dir
17800         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17801         MULTIPID=$!
17802         # remove the files & current working dir
17803         unlinkmany $DIR/$tdir/foobar 4000
17804         rmdir $DIR/$tdir
17805         kill -USR1 $MULTIPID
17806         wait $MULTIPID
17807         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17808         return 0
17809 }
17810 run_test 181 "Test open-unlinked dir ========================"
17811
17812 test_182() {
17813         local fcount=1000
17814         local tcount=10
17815
17816         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17817
17818         $LCTL set_param mdc.*.rpc_stats=clear
17819
17820         for (( i = 0; i < $tcount; i++ )) ; do
17821                 mkdir $DIR/$tdir/$i
17822         done
17823
17824         for (( i = 0; i < $tcount; i++ )) ; do
17825                 createmany -o $DIR/$tdir/$i/f- $fcount &
17826         done
17827         wait
17828
17829         for (( i = 0; i < $tcount; i++ )) ; do
17830                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17831         done
17832         wait
17833
17834         $LCTL get_param mdc.*.rpc_stats
17835
17836         rm -rf $DIR/$tdir
17837 }
17838 run_test 182 "Test parallel modify metadata operations ================"
17839
17840 test_183() { # LU-2275
17841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17842         remote_mds_nodsh && skip "remote MDS with nodsh"
17843         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17844                 skip "Need MDS version at least 2.3.56"
17845
17846         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17847         echo aaa > $DIR/$tdir/$tfile
17848
17849 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17850         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17851
17852         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17853         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17854
17855         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17856
17857         # Flush negative dentry cache
17858         touch $DIR/$tdir/$tfile
17859
17860         # We are not checking for any leaked references here, they'll
17861         # become evident next time we do cleanup with module unload.
17862         rm -rf $DIR/$tdir
17863 }
17864 run_test 183 "No crash or request leak in case of strange dispositions ========"
17865
17866 # test suite 184 is for LU-2016, LU-2017
17867 test_184a() {
17868         check_swap_layouts_support
17869
17870         dir0=$DIR/$tdir/$testnum
17871         test_mkdir -p -c1 $dir0
17872         ref1=/etc/passwd
17873         ref2=/etc/group
17874         file1=$dir0/f1
17875         file2=$dir0/f2
17876         $LFS setstripe -c1 $file1
17877         cp $ref1 $file1
17878         $LFS setstripe -c2 $file2
17879         cp $ref2 $file2
17880         gen1=$($LFS getstripe -g $file1)
17881         gen2=$($LFS getstripe -g $file2)
17882
17883         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17884         gen=$($LFS getstripe -g $file1)
17885         [[ $gen1 != $gen ]] ||
17886                 error "Layout generation on $file1 does not change"
17887         gen=$($LFS getstripe -g $file2)
17888         [[ $gen2 != $gen ]] ||
17889                 error "Layout generation on $file2 does not change"
17890
17891         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17892         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17893
17894         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17895 }
17896 run_test 184a "Basic layout swap"
17897
17898 test_184b() {
17899         check_swap_layouts_support
17900
17901         dir0=$DIR/$tdir/$testnum
17902         mkdir -p $dir0 || error "creating dir $dir0"
17903         file1=$dir0/f1
17904         file2=$dir0/f2
17905         file3=$dir0/f3
17906         dir1=$dir0/d1
17907         dir2=$dir0/d2
17908         mkdir $dir1 $dir2
17909         $LFS setstripe -c1 $file1
17910         $LFS setstripe -c2 $file2
17911         $LFS setstripe -c1 $file3
17912         chown $RUNAS_ID $file3
17913         gen1=$($LFS getstripe -g $file1)
17914         gen2=$($LFS getstripe -g $file2)
17915
17916         $LFS swap_layouts $dir1 $dir2 &&
17917                 error "swap of directories layouts should fail"
17918         $LFS swap_layouts $dir1 $file1 &&
17919                 error "swap of directory and file layouts should fail"
17920         $RUNAS $LFS swap_layouts $file1 $file2 &&
17921                 error "swap of file we cannot write should fail"
17922         $LFS swap_layouts $file1 $file3 &&
17923                 error "swap of file with different owner should fail"
17924         /bin/true # to clear error code
17925 }
17926 run_test 184b "Forbidden layout swap (will generate errors)"
17927
17928 test_184c() {
17929         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
17930         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
17931         check_swap_layouts_support
17932         check_swap_layout_no_dom $DIR
17933
17934         local dir0=$DIR/$tdir/$testnum
17935         mkdir -p $dir0 || error "creating dir $dir0"
17936
17937         local ref1=$dir0/ref1
17938         local ref2=$dir0/ref2
17939         local file1=$dir0/file1
17940         local file2=$dir0/file2
17941         # create a file large enough for the concurrent test
17942         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
17943         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
17944         echo "ref file size: ref1($(stat -c %s $ref1))," \
17945              "ref2($(stat -c %s $ref2))"
17946
17947         cp $ref2 $file2
17948         dd if=$ref1 of=$file1 bs=16k &
17949         local DD_PID=$!
17950
17951         # Make sure dd starts to copy file, but wait at most 5 seconds
17952         local loops=0
17953         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
17954
17955         $LFS swap_layouts $file1 $file2
17956         local rc=$?
17957         wait $DD_PID
17958         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
17959         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
17960
17961         # how many bytes copied before swapping layout
17962         local copied=$(stat -c %s $file2)
17963         local remaining=$(stat -c %s $ref1)
17964         remaining=$((remaining - copied))
17965         echo "Copied $copied bytes before swapping layout..."
17966
17967         cmp -n $copied $file1 $ref2 | grep differ &&
17968                 error "Content mismatch [0, $copied) of ref2 and file1"
17969         cmp -n $copied $file2 $ref1 ||
17970                 error "Content mismatch [0, $copied) of ref1 and file2"
17971         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
17972                 error "Content mismatch [$copied, EOF) of ref1 and file1"
17973
17974         # clean up
17975         rm -f $ref1 $ref2 $file1 $file2
17976 }
17977 run_test 184c "Concurrent write and layout swap"
17978
17979 test_184d() {
17980         check_swap_layouts_support
17981         check_swap_layout_no_dom $DIR
17982         [ -z "$(which getfattr 2>/dev/null)" ] &&
17983                 skip_env "no getfattr command"
17984
17985         local file1=$DIR/$tdir/$tfile-1
17986         local file2=$DIR/$tdir/$tfile-2
17987         local file3=$DIR/$tdir/$tfile-3
17988         local lovea1
17989         local lovea2
17990
17991         mkdir -p $DIR/$tdir
17992         touch $file1 || error "create $file1 failed"
17993         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17994                 error "create $file2 failed"
17995         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17996                 error "create $file3 failed"
17997         lovea1=$(get_layout_param $file1)
17998
17999         $LFS swap_layouts $file2 $file3 ||
18000                 error "swap $file2 $file3 layouts failed"
18001         $LFS swap_layouts $file1 $file2 ||
18002                 error "swap $file1 $file2 layouts failed"
18003
18004         lovea2=$(get_layout_param $file2)
18005         echo "$lovea1"
18006         echo "$lovea2"
18007         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18008
18009         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18010         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18011 }
18012 run_test 184d "allow stripeless layouts swap"
18013
18014 test_184e() {
18015         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18016                 skip "Need MDS version at least 2.6.94"
18017         check_swap_layouts_support
18018         check_swap_layout_no_dom $DIR
18019         [ -z "$(which getfattr 2>/dev/null)" ] &&
18020                 skip_env "no getfattr command"
18021
18022         local file1=$DIR/$tdir/$tfile-1
18023         local file2=$DIR/$tdir/$tfile-2
18024         local file3=$DIR/$tdir/$tfile-3
18025         local lovea
18026
18027         mkdir -p $DIR/$tdir
18028         touch $file1 || error "create $file1 failed"
18029         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18030                 error "create $file2 failed"
18031         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18032                 error "create $file3 failed"
18033
18034         $LFS swap_layouts $file1 $file2 ||
18035                 error "swap $file1 $file2 layouts failed"
18036
18037         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18038         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18039
18040         echo 123 > $file1 || error "Should be able to write into $file1"
18041
18042         $LFS swap_layouts $file1 $file3 ||
18043                 error "swap $file1 $file3 layouts failed"
18044
18045         echo 123 > $file1 || error "Should be able to write into $file1"
18046
18047         rm -rf $file1 $file2 $file3
18048 }
18049 run_test 184e "Recreate layout after stripeless layout swaps"
18050
18051 test_184f() {
18052         # Create a file with name longer than sizeof(struct stat) ==
18053         # 144 to see if we can get chars from the file name to appear
18054         # in the returned striping. Note that 'f' == 0x66.
18055         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18056
18057         mkdir -p $DIR/$tdir
18058         mcreate $DIR/$tdir/$file
18059         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18060                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18061         fi
18062 }
18063 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18064
18065 test_185() { # LU-2441
18066         # LU-3553 - no volatile file support in old servers
18067         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18068                 skip "Need MDS version at least 2.3.60"
18069
18070         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18071         touch $DIR/$tdir/spoo
18072         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18073         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18074                 error "cannot create/write a volatile file"
18075         [ "$FILESET" == "" ] &&
18076         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18077                 error "FID is still valid after close"
18078
18079         multiop_bg_pause $DIR/$tdir vVw4096_c
18080         local multi_pid=$!
18081
18082         local OLD_IFS=$IFS
18083         IFS=":"
18084         local fidv=($fid)
18085         IFS=$OLD_IFS
18086         # assume that the next FID for this client is sequential, since stdout
18087         # is unfortunately eaten by multiop_bg_pause
18088         local n=$((${fidv[1]} + 1))
18089         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18090         if [ "$FILESET" == "" ]; then
18091                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18092                         error "FID is missing before close"
18093         fi
18094         kill -USR1 $multi_pid
18095         # 1 second delay, so if mtime change we will see it
18096         sleep 1
18097         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18098         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18099 }
18100 run_test 185 "Volatile file support"
18101
18102 function create_check_volatile() {
18103         local idx=$1
18104         local tgt
18105
18106         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18107         local PID=$!
18108         sleep 1
18109         local FID=$(cat /tmp/${tfile}.fid)
18110         [ "$FID" == "" ] && error "can't get FID for volatile"
18111         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18112         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18113         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18114         kill -USR1 $PID
18115         wait
18116         sleep 1
18117         cancel_lru_locks mdc # flush opencache
18118         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18119         return 0
18120 }
18121
18122 test_185a(){
18123         # LU-12516 - volatile creation via .lustre
18124         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18125                 skip "Need MDS version at least 2.3.55"
18126
18127         create_check_volatile 0
18128         [ $MDSCOUNT -lt 2 ] && return 0
18129
18130         # DNE case
18131         create_check_volatile 1
18132
18133         return 0
18134 }
18135 run_test 185a "Volatile file creation in .lustre/fid/"
18136
18137 test_187a() {
18138         remote_mds_nodsh && skip "remote MDS with nodsh"
18139         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18140                 skip "Need MDS version at least 2.3.0"
18141
18142         local dir0=$DIR/$tdir/$testnum
18143         mkdir -p $dir0 || error "creating dir $dir0"
18144
18145         local file=$dir0/file1
18146         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18147         local dv1=$($LFS data_version $file)
18148         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18149         local dv2=$($LFS data_version $file)
18150         [[ $dv1 != $dv2 ]] ||
18151                 error "data version did not change on write $dv1 == $dv2"
18152
18153         # clean up
18154         rm -f $file1
18155 }
18156 run_test 187a "Test data version change"
18157
18158 test_187b() {
18159         remote_mds_nodsh && skip "remote MDS with nodsh"
18160         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18161                 skip "Need MDS version at least 2.3.0"
18162
18163         local dir0=$DIR/$tdir/$testnum
18164         mkdir -p $dir0 || error "creating dir $dir0"
18165
18166         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18167         [[ ${DV[0]} != ${DV[1]} ]] ||
18168                 error "data version did not change on write"\
18169                       " ${DV[0]} == ${DV[1]}"
18170
18171         # clean up
18172         rm -f $file1
18173 }
18174 run_test 187b "Test data version change on volatile file"
18175
18176 test_200() {
18177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18178         remote_mgs_nodsh && skip "remote MGS with nodsh"
18179         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18180
18181         local POOL=${POOL:-cea1}
18182         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18183         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18184         # Pool OST targets
18185         local first_ost=0
18186         local last_ost=$(($OSTCOUNT - 1))
18187         local ost_step=2
18188         local ost_list=$(seq $first_ost $ost_step $last_ost)
18189         local ost_range="$first_ost $last_ost $ost_step"
18190         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18191         local file_dir=$POOL_ROOT/file_tst
18192         local subdir=$test_path/subdir
18193         local rc=0
18194
18195         while : ; do
18196                 # former test_200a test_200b
18197                 pool_add $POOL                          || { rc=$? ; break; }
18198                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18199                 # former test_200c test_200d
18200                 mkdir -p $test_path
18201                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18202                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18203                 mkdir -p $subdir
18204                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18205                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18206                                                         || { rc=$? ; break; }
18207                 # former test_200e test_200f
18208                 local files=$((OSTCOUNT*3))
18209                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18210                                                         || { rc=$? ; break; }
18211                 pool_create_files $POOL $file_dir $files "$ost_list" \
18212                                                         || { rc=$? ; break; }
18213                 # former test_200g test_200h
18214                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18215                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18216
18217                 # former test_201a test_201b test_201c
18218                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18219
18220                 local f=$test_path/$tfile
18221                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18222                 pool_remove $POOL $f                    || { rc=$? ; break; }
18223                 break
18224         done
18225
18226         destroy_test_pools
18227
18228         return $rc
18229 }
18230 run_test 200 "OST pools"
18231
18232 # usage: default_attr <count | size | offset>
18233 default_attr() {
18234         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18235 }
18236
18237 # usage: check_default_stripe_attr
18238 check_default_stripe_attr() {
18239         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18240         case $1 in
18241         --stripe-count|-c)
18242                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18243         --stripe-size|-S)
18244                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18245         --stripe-index|-i)
18246                 EXPECTED=-1;;
18247         *)
18248                 error "unknown getstripe attr '$1'"
18249         esac
18250
18251         [ $ACTUAL == $EXPECTED ] ||
18252                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18253 }
18254
18255 test_204a() {
18256         test_mkdir $DIR/$tdir
18257         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18258
18259         check_default_stripe_attr --stripe-count
18260         check_default_stripe_attr --stripe-size
18261         check_default_stripe_attr --stripe-index
18262 }
18263 run_test 204a "Print default stripe attributes"
18264
18265 test_204b() {
18266         test_mkdir $DIR/$tdir
18267         $LFS setstripe --stripe-count 1 $DIR/$tdir
18268
18269         check_default_stripe_attr --stripe-size
18270         check_default_stripe_attr --stripe-index
18271 }
18272 run_test 204b "Print default stripe size and offset"
18273
18274 test_204c() {
18275         test_mkdir $DIR/$tdir
18276         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18277
18278         check_default_stripe_attr --stripe-count
18279         check_default_stripe_attr --stripe-index
18280 }
18281 run_test 204c "Print default stripe count and offset"
18282
18283 test_204d() {
18284         test_mkdir $DIR/$tdir
18285         $LFS setstripe --stripe-index 0 $DIR/$tdir
18286
18287         check_default_stripe_attr --stripe-count
18288         check_default_stripe_attr --stripe-size
18289 }
18290 run_test 204d "Print default stripe count and size"
18291
18292 test_204e() {
18293         test_mkdir $DIR/$tdir
18294         $LFS setstripe -d $DIR/$tdir
18295
18296         check_default_stripe_attr --stripe-count --raw
18297         check_default_stripe_attr --stripe-size --raw
18298         check_default_stripe_attr --stripe-index --raw
18299 }
18300 run_test 204e "Print raw stripe attributes"
18301
18302 test_204f() {
18303         test_mkdir $DIR/$tdir
18304         $LFS setstripe --stripe-count 1 $DIR/$tdir
18305
18306         check_default_stripe_attr --stripe-size --raw
18307         check_default_stripe_attr --stripe-index --raw
18308 }
18309 run_test 204f "Print raw stripe size and offset"
18310
18311 test_204g() {
18312         test_mkdir $DIR/$tdir
18313         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18314
18315         check_default_stripe_attr --stripe-count --raw
18316         check_default_stripe_attr --stripe-index --raw
18317 }
18318 run_test 204g "Print raw stripe count and offset"
18319
18320 test_204h() {
18321         test_mkdir $DIR/$tdir
18322         $LFS setstripe --stripe-index 0 $DIR/$tdir
18323
18324         check_default_stripe_attr --stripe-count --raw
18325         check_default_stripe_attr --stripe-size --raw
18326 }
18327 run_test 204h "Print raw stripe count and size"
18328
18329 # Figure out which job scheduler is being used, if any,
18330 # or use a fake one
18331 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18332         JOBENV=SLURM_JOB_ID
18333 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18334         JOBENV=LSB_JOBID
18335 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18336         JOBENV=PBS_JOBID
18337 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18338         JOBENV=LOADL_STEP_ID
18339 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18340         JOBENV=JOB_ID
18341 else
18342         $LCTL list_param jobid_name > /dev/null 2>&1
18343         if [ $? -eq 0 ]; then
18344                 JOBENV=nodelocal
18345         else
18346                 JOBENV=FAKE_JOBID
18347         fi
18348 fi
18349 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18350
18351 verify_jobstats() {
18352         local cmd=($1)
18353         shift
18354         local facets="$@"
18355
18356 # we don't really need to clear the stats for this test to work, since each
18357 # command has a unique jobid, but it makes debugging easier if needed.
18358 #       for facet in $facets; do
18359 #               local dev=$(convert_facet2label $facet)
18360 #               # clear old jobstats
18361 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18362 #       done
18363
18364         # use a new JobID for each test, or we might see an old one
18365         [ "$JOBENV" = "FAKE_JOBID" ] &&
18366                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18367
18368         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18369
18370         [ "$JOBENV" = "nodelocal" ] && {
18371                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18372                 $LCTL set_param jobid_name=$FAKE_JOBID
18373                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18374         }
18375
18376         log "Test: ${cmd[*]}"
18377         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18378
18379         if [ $JOBENV = "FAKE_JOBID" ]; then
18380                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18381         else
18382                 ${cmd[*]}
18383         fi
18384
18385         # all files are created on OST0000
18386         for facet in $facets; do
18387                 local stats="*.$(convert_facet2label $facet).job_stats"
18388
18389                 # strip out libtool wrappers for in-tree executables
18390                 if (( $(do_facet $facet lctl get_param $stats |
18391                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18392                         do_facet $facet lctl get_param $stats
18393                         error "No jobstats for $JOBVAL found on $facet::$stats"
18394                 fi
18395         done
18396 }
18397
18398 jobstats_set() {
18399         local new_jobenv=$1
18400
18401         set_persistent_param_and_check client "jobid_var" \
18402                 "$FSNAME.sys.jobid_var" $new_jobenv
18403 }
18404
18405 test_205a() { # Job stats
18406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18407         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18408                 skip "Need MDS version with at least 2.7.1"
18409         remote_mgs_nodsh && skip "remote MGS with nodsh"
18410         remote_mds_nodsh && skip "remote MDS with nodsh"
18411         remote_ost_nodsh && skip "remote OST with nodsh"
18412         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18413                 skip "Server doesn't support jobstats"
18414         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18415
18416         local old_jobenv=$($LCTL get_param -n jobid_var)
18417         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18418
18419         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18420                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18421         else
18422                 stack_trap "do_facet mgs $PERM_CMD \
18423                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18424         fi
18425         changelog_register
18426
18427         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18428                                 mdt.*.job_cleanup_interval | head -n 1)
18429         local new_interval=5
18430         do_facet $SINGLEMDS \
18431                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18432         stack_trap "do_facet $SINGLEMDS \
18433                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18434         local start=$SECONDS
18435
18436         local cmd
18437         # mkdir
18438         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18439         verify_jobstats "$cmd" "$SINGLEMDS"
18440         # rmdir
18441         cmd="rmdir $DIR/$tdir"
18442         verify_jobstats "$cmd" "$SINGLEMDS"
18443         # mkdir on secondary MDT
18444         if [ $MDSCOUNT -gt 1 ]; then
18445                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18446                 verify_jobstats "$cmd" "mds2"
18447         fi
18448         # mknod
18449         cmd="mknod $DIR/$tfile c 1 3"
18450         verify_jobstats "$cmd" "$SINGLEMDS"
18451         # unlink
18452         cmd="rm -f $DIR/$tfile"
18453         verify_jobstats "$cmd" "$SINGLEMDS"
18454         # create all files on OST0000 so verify_jobstats can find OST stats
18455         # open & close
18456         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18457         verify_jobstats "$cmd" "$SINGLEMDS"
18458         # setattr
18459         cmd="touch $DIR/$tfile"
18460         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18461         # write
18462         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18463         verify_jobstats "$cmd" "ost1"
18464         # read
18465         cancel_lru_locks osc
18466         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18467         verify_jobstats "$cmd" "ost1"
18468         # truncate
18469         cmd="$TRUNCATE $DIR/$tfile 0"
18470         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18471         # rename
18472         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18473         verify_jobstats "$cmd" "$SINGLEMDS"
18474         # jobstats expiry - sleep until old stats should be expired
18475         local left=$((new_interval + 5 - (SECONDS - start)))
18476         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18477                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18478                         "0" $left
18479         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18480         verify_jobstats "$cmd" "$SINGLEMDS"
18481         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18482             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18483
18484         # Ensure that jobid are present in changelog (if supported by MDS)
18485         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18486                 changelog_dump | tail -10
18487                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18488                 [ $jobids -eq 9 ] ||
18489                         error "Wrong changelog jobid count $jobids != 9"
18490
18491                 # LU-5862
18492                 JOBENV="disable"
18493                 jobstats_set $JOBENV
18494                 touch $DIR/$tfile
18495                 changelog_dump | grep $tfile
18496                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18497                 [ $jobids -eq 0 ] ||
18498                         error "Unexpected jobids when jobid_var=$JOBENV"
18499         fi
18500
18501         # test '%j' access to environment variable - if supported
18502         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18503                 JOBENV="JOBCOMPLEX"
18504                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18505
18506                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18507         fi
18508
18509         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18510                 JOBENV="JOBCOMPLEX"
18511                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18512
18513                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18514         fi
18515
18516         # test '%j' access to per-session jobid - if supported
18517         if lctl list_param jobid_this_session > /dev/null 2>&1
18518         then
18519                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18520                 lctl set_param jobid_this_session=$USER
18521
18522                 JOBENV="JOBCOMPLEX"
18523                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18524
18525                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18526         fi
18527 }
18528 run_test 205a "Verify job stats"
18529
18530 # LU-13117, LU-13597
18531 test_205b() {
18532         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18533                 skip "Need MDS version at least 2.13.54.91"
18534
18535         job_stats="mdt.*.job_stats"
18536         $LCTL set_param $job_stats=clear
18537         # Setting jobid_var to USER might not be supported
18538         $LCTL set_param jobid_var=USER || true
18539         $LCTL set_param jobid_name="%e.%u"
18540         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18541         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18542                 grep "job_id:.*foolish" &&
18543                         error "Unexpected jobid found"
18544         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18545                 grep "open:.*min.*max.*sum" ||
18546                         error "wrong job_stats format found"
18547 }
18548 run_test 205b "Verify job stats jobid and output format"
18549
18550 # LU-13733
18551 test_205c() {
18552         $LCTL set_param llite.*.stats=0
18553         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18554         $LCTL get_param llite.*.stats
18555         $LCTL get_param llite.*.stats | grep \
18556                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18557                         error "wrong client stats format found"
18558 }
18559 run_test 205c "Verify client stats format"
18560
18561 # LU-1480, LU-1773 and LU-1657
18562 test_206() {
18563         mkdir -p $DIR/$tdir
18564         $LFS setstripe -c -1 $DIR/$tdir
18565 #define OBD_FAIL_LOV_INIT 0x1403
18566         $LCTL set_param fail_loc=0xa0001403
18567         $LCTL set_param fail_val=1
18568         touch $DIR/$tdir/$tfile || true
18569 }
18570 run_test 206 "fail lov_init_raid0() doesn't lbug"
18571
18572 test_207a() {
18573         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18574         local fsz=`stat -c %s $DIR/$tfile`
18575         cancel_lru_locks mdc
18576
18577         # do not return layout in getattr intent
18578 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18579         $LCTL set_param fail_loc=0x170
18580         local sz=`stat -c %s $DIR/$tfile`
18581
18582         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18583
18584         rm -rf $DIR/$tfile
18585 }
18586 run_test 207a "can refresh layout at glimpse"
18587
18588 test_207b() {
18589         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18590         local cksum=`md5sum $DIR/$tfile`
18591         local fsz=`stat -c %s $DIR/$tfile`
18592         cancel_lru_locks mdc
18593         cancel_lru_locks osc
18594
18595         # do not return layout in getattr intent
18596 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18597         $LCTL set_param fail_loc=0x171
18598
18599         # it will refresh layout after the file is opened but before read issues
18600         echo checksum is "$cksum"
18601         echo "$cksum" |md5sum -c --quiet || error "file differs"
18602
18603         rm -rf $DIR/$tfile
18604 }
18605 run_test 207b "can refresh layout at open"
18606
18607 test_208() {
18608         # FIXME: in this test suite, only RD lease is used. This is okay
18609         # for now as only exclusive open is supported. After generic lease
18610         # is done, this test suite should be revised. - Jinshan
18611
18612         remote_mds_nodsh && skip "remote MDS with nodsh"
18613         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18614                 skip "Need MDS version at least 2.4.52"
18615
18616         echo "==== test 1: verify get lease work"
18617         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18618
18619         echo "==== test 2: verify lease can be broken by upcoming open"
18620         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18621         local PID=$!
18622         sleep 2
18623
18624         $MULTIOP $DIR/$tfile oO_RDWR:c
18625         kill -USR1 $PID && wait $PID || error "break lease error"
18626
18627         echo "==== test 3: verify lease can't be granted if an open already exists"
18628         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18629         local PID=$!
18630         sleep 2
18631
18632         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18633         kill -USR1 $PID && wait $PID || error "open file error"
18634
18635         echo "==== test 4: lease can sustain over recovery"
18636         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18637         PID=$!
18638         sleep 2
18639
18640         fail mds1
18641
18642         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18643
18644         echo "==== test 5: lease broken can't be regained by replay"
18645         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18646         PID=$!
18647         sleep 2
18648
18649         # open file to break lease and then recovery
18650         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18651         fail mds1
18652
18653         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18654
18655         rm -f $DIR/$tfile
18656 }
18657 run_test 208 "Exclusive open"
18658
18659 test_209() {
18660         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18661                 skip_env "must have disp_stripe"
18662
18663         touch $DIR/$tfile
18664         sync; sleep 5; sync;
18665
18666         echo 3 > /proc/sys/vm/drop_caches
18667         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18668                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18669         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18670
18671         # open/close 500 times
18672         for i in $(seq 500); do
18673                 cat $DIR/$tfile
18674         done
18675
18676         echo 3 > /proc/sys/vm/drop_caches
18677         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18678                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18679         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18680
18681         echo "before: $req_before, after: $req_after"
18682         [ $((req_after - req_before)) -ge 300 ] &&
18683                 error "open/close requests are not freed"
18684         return 0
18685 }
18686 run_test 209 "read-only open/close requests should be freed promptly"
18687
18688 test_210() {
18689         local pid
18690
18691         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18692         pid=$!
18693         sleep 1
18694
18695         $LFS getstripe $DIR/$tfile
18696         kill -USR1 $pid
18697         wait $pid || error "multiop failed"
18698
18699         $MULTIOP $DIR/$tfile oO_RDONLY:eR_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 run_test 210 "lfs getstripe does not break leases"
18708
18709 test_212() {
18710         size=`date +%s`
18711         size=$((size % 8192 + 1))
18712         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18713         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18714         rm -f $DIR/f212 $DIR/f212.xyz
18715 }
18716 run_test 212 "Sendfile test ============================================"
18717
18718 test_213() {
18719         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18720         cancel_lru_locks osc
18721         lctl set_param fail_loc=0x8000040f
18722         # generate a read lock
18723         cat $DIR/$tfile > /dev/null
18724         # write to the file, it will try to cancel the above read lock.
18725         cat /etc/hosts >> $DIR/$tfile
18726 }
18727 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18728
18729 test_214() { # for bug 20133
18730         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18731         for (( i=0; i < 340; i++ )) ; do
18732                 touch $DIR/$tdir/d214c/a$i
18733         done
18734
18735         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18736         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18737         ls $DIR/d214c || error "ls $DIR/d214c failed"
18738         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18739         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18740 }
18741 run_test 214 "hash-indexed directory test - bug 20133"
18742
18743 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18744 create_lnet_proc_files() {
18745         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18746 }
18747
18748 # counterpart of create_lnet_proc_files
18749 remove_lnet_proc_files() {
18750         rm -f $TMP/lnet_$1.sys
18751 }
18752
18753 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18754 # 3rd arg as regexp for body
18755 check_lnet_proc_stats() {
18756         local l=$(cat "$TMP/lnet_$1" |wc -l)
18757         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18758
18759         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18760 }
18761
18762 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18763 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18764 # optional and can be regexp for 2nd line (lnet.routes case)
18765 check_lnet_proc_entry() {
18766         local blp=2          # blp stands for 'position of 1st line of body'
18767         [ -z "$5" ] || blp=3 # lnet.routes case
18768
18769         local l=$(cat "$TMP/lnet_$1" |wc -l)
18770         # subtracting one from $blp because the body can be empty
18771         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18772
18773         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18774                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18775
18776         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18777                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18778
18779         # bail out if any unexpected line happened
18780         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18781         [ "$?" != 0 ] || error "$2 misformatted"
18782 }
18783
18784 test_215() { # for bugs 18102, 21079, 21517
18785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18786
18787         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18788         local P='[1-9][0-9]*'           # positive numeric
18789         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18790         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18791         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18792         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18793
18794         local L1 # regexp for 1st line
18795         local L2 # regexp for 2nd line (optional)
18796         local BR # regexp for the rest (body)
18797
18798         # lnet.stats should look as 11 space-separated non-negative numerics
18799         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18800         create_lnet_proc_files "stats"
18801         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18802         remove_lnet_proc_files "stats"
18803
18804         # lnet.routes should look like this:
18805         # Routing disabled/enabled
18806         # net hops priority state router
18807         # where net is a string like tcp0, hops > 0, priority >= 0,
18808         # state is up/down,
18809         # router is a string like 192.168.1.1@tcp2
18810         L1="^Routing (disabled|enabled)$"
18811         L2="^net +hops +priority +state +router$"
18812         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18813         create_lnet_proc_files "routes"
18814         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18815         remove_lnet_proc_files "routes"
18816
18817         # lnet.routers should look like this:
18818         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18819         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18820         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18821         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18822         L1="^ref +rtr_ref +alive +router$"
18823         BR="^$P +$P +(up|down) +$NID$"
18824         create_lnet_proc_files "routers"
18825         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18826         remove_lnet_proc_files "routers"
18827
18828         # lnet.peers should look like this:
18829         # nid refs state last max rtr min tx min queue
18830         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18831         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18832         # numeric (0 or >0 or <0), queue >= 0.
18833         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18834         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18835         create_lnet_proc_files "peers"
18836         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18837         remove_lnet_proc_files "peers"
18838
18839         # lnet.buffers  should look like this:
18840         # pages count credits min
18841         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18842         L1="^pages +count +credits +min$"
18843         BR="^ +$N +$N +$I +$I$"
18844         create_lnet_proc_files "buffers"
18845         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18846         remove_lnet_proc_files "buffers"
18847
18848         # lnet.nis should look like this:
18849         # nid status alive refs peer rtr max tx min
18850         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18851         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18852         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18853         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18854         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18855         create_lnet_proc_files "nis"
18856         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18857         remove_lnet_proc_files "nis"
18858
18859         # can we successfully write to lnet.stats?
18860         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18861 }
18862 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18863
18864 test_216() { # bug 20317
18865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18866         remote_ost_nodsh && skip "remote OST with nodsh"
18867
18868         local node
18869         local facets=$(get_facets OST)
18870         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18871
18872         save_lustre_params client "osc.*.contention_seconds" > $p
18873         save_lustre_params $facets \
18874                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18875         save_lustre_params $facets \
18876                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18877         save_lustre_params $facets \
18878                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18879         clear_stats osc.*.osc_stats
18880
18881         # agressive lockless i/o settings
18882         do_nodes $(comma_list $(osts_nodes)) \
18883                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18884                         ldlm.namespaces.filter-*.contended_locks=0 \
18885                         ldlm.namespaces.filter-*.contention_seconds=60"
18886         lctl set_param -n osc.*.contention_seconds=60
18887
18888         $DIRECTIO write $DIR/$tfile 0 10 4096
18889         $CHECKSTAT -s 40960 $DIR/$tfile
18890
18891         # disable lockless i/o
18892         do_nodes $(comma_list $(osts_nodes)) \
18893                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18894                         ldlm.namespaces.filter-*.contended_locks=32 \
18895                         ldlm.namespaces.filter-*.contention_seconds=0"
18896         lctl set_param -n osc.*.contention_seconds=0
18897         clear_stats osc.*.osc_stats
18898
18899         dd if=/dev/zero of=$DIR/$tfile count=0
18900         $CHECKSTAT -s 0 $DIR/$tfile
18901
18902         restore_lustre_params <$p
18903         rm -f $p
18904         rm $DIR/$tfile
18905 }
18906 run_test 216 "check lockless direct write updates file size and kms correctly"
18907
18908 test_217() { # bug 22430
18909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18910
18911         local node
18912         local nid
18913
18914         for node in $(nodes_list); do
18915                 nid=$(host_nids_address $node $NETTYPE)
18916                 if [[ $nid = *-* ]] ; then
18917                         echo "lctl ping $(h2nettype $nid)"
18918                         lctl ping $(h2nettype $nid)
18919                 else
18920                         echo "skipping $node (no hyphen detected)"
18921                 fi
18922         done
18923 }
18924 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18925
18926 test_218() {
18927        # do directio so as not to populate the page cache
18928        log "creating a 10 Mb file"
18929        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
18930        log "starting reads"
18931        dd if=$DIR/$tfile of=/dev/null bs=4096 &
18932        log "truncating the file"
18933        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
18934        log "killing dd"
18935        kill %+ || true # reads might have finished
18936        echo "wait until dd is finished"
18937        wait
18938        log "removing the temporary file"
18939        rm -rf $DIR/$tfile || error "tmp file removal failed"
18940 }
18941 run_test 218 "parallel read and truncate should not deadlock"
18942
18943 test_219() {
18944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18945
18946         # write one partial page
18947         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
18948         # set no grant so vvp_io_commit_write will do sync write
18949         $LCTL set_param fail_loc=0x411
18950         # write a full page at the end of file
18951         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
18952
18953         $LCTL set_param fail_loc=0
18954         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
18955         $LCTL set_param fail_loc=0x411
18956         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
18957
18958         # LU-4201
18959         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
18960         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
18961 }
18962 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
18963
18964 test_220() { #LU-325
18965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18966         remote_ost_nodsh && skip "remote OST with nodsh"
18967         remote_mds_nodsh && skip "remote MDS with nodsh"
18968         remote_mgs_nodsh && skip "remote MGS with nodsh"
18969
18970         local OSTIDX=0
18971
18972         # create on MDT0000 so the last_id and next_id are correct
18973         mkdir_on_mdt0 $DIR/$tdir
18974         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
18975         OST=${OST%_UUID}
18976
18977         # on the mdt's osc
18978         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
18979         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
18980                         osp.$mdtosc_proc1.prealloc_last_id)
18981         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
18982                         osp.$mdtosc_proc1.prealloc_next_id)
18983
18984         $LFS df -i
18985
18986         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
18987         #define OBD_FAIL_OST_ENOINO              0x229
18988         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
18989         create_pool $FSNAME.$TESTNAME || return 1
18990         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
18991
18992         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
18993
18994         MDSOBJS=$((last_id - next_id))
18995         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
18996
18997         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
18998         echo "OST still has $count kbytes free"
18999
19000         echo "create $MDSOBJS files @next_id..."
19001         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19002
19003         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19004                         osp.$mdtosc_proc1.prealloc_last_id)
19005         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19006                         osp.$mdtosc_proc1.prealloc_next_id)
19007
19008         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19009         $LFS df -i
19010
19011         echo "cleanup..."
19012
19013         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19014         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19015
19016         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19017                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19018         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19019                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19020         echo "unlink $MDSOBJS files @$next_id..."
19021         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19022 }
19023 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19024
19025 test_221() {
19026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19027
19028         dd if=`which date` of=$MOUNT/date oflag=sync
19029         chmod +x $MOUNT/date
19030
19031         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19032         $LCTL set_param fail_loc=0x80001401
19033
19034         $MOUNT/date > /dev/null
19035         rm -f $MOUNT/date
19036 }
19037 run_test 221 "make sure fault and truncate race to not cause OOM"
19038
19039 test_222a () {
19040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19041
19042         rm -rf $DIR/$tdir
19043         test_mkdir $DIR/$tdir
19044         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19045         createmany -o $DIR/$tdir/$tfile 10
19046         cancel_lru_locks mdc
19047         cancel_lru_locks osc
19048         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19049         $LCTL set_param fail_loc=0x31a
19050         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19051         $LCTL set_param fail_loc=0
19052         rm -r $DIR/$tdir
19053 }
19054 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19055
19056 test_222b () {
19057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19058
19059         rm -rf $DIR/$tdir
19060         test_mkdir $DIR/$tdir
19061         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19062         createmany -o $DIR/$tdir/$tfile 10
19063         cancel_lru_locks mdc
19064         cancel_lru_locks osc
19065         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19066         $LCTL set_param fail_loc=0x31a
19067         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19068         $LCTL set_param fail_loc=0
19069 }
19070 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19071
19072 test_223 () {
19073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19074
19075         rm -rf $DIR/$tdir
19076         test_mkdir $DIR/$tdir
19077         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19078         createmany -o $DIR/$tdir/$tfile 10
19079         cancel_lru_locks mdc
19080         cancel_lru_locks osc
19081         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19082         $LCTL set_param fail_loc=0x31b
19083         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19084         $LCTL set_param fail_loc=0
19085         rm -r $DIR/$tdir
19086 }
19087 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19088
19089 test_224a() { # LU-1039, MRP-303
19090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19091         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19092         $LCTL set_param fail_loc=0x508
19093         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19094         $LCTL set_param fail_loc=0
19095         df $DIR
19096 }
19097 run_test 224a "Don't panic on bulk IO failure"
19098
19099 test_224bd_sub() { # LU-1039, MRP-303
19100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19101         local timeout=$1
19102
19103         shift
19104         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19105
19106         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19107
19108         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19109         cancel_lru_locks osc
19110         set_checksums 0
19111         stack_trap "set_checksums $ORIG_CSUM" EXIT
19112         local at_max_saved=0
19113
19114         # adaptive timeouts may prevent seeing the issue
19115         if at_is_enabled; then
19116                 at_max_saved=$(at_max_get mds)
19117                 at_max_set 0 mds client
19118                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19119         fi
19120
19121         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19122         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19123         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19124
19125         do_facet ost1 $LCTL set_param fail_loc=0
19126         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19127         df $DIR
19128 }
19129
19130 test_224b() {
19131         test_224bd_sub 3 error "dd failed"
19132 }
19133 run_test 224b "Don't panic on bulk IO failure"
19134
19135 test_224c() { # LU-6441
19136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19137         remote_mds_nodsh && skip "remote MDS with nodsh"
19138
19139         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19140         save_writethrough $p
19141         set_cache writethrough on
19142
19143         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19144         local at_max=$($LCTL get_param -n at_max)
19145         local timeout=$($LCTL get_param -n timeout)
19146         local test_at="at_max"
19147         local param_at="$FSNAME.sys.at_max"
19148         local test_timeout="timeout"
19149         local param_timeout="$FSNAME.sys.timeout"
19150
19151         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19152
19153         set_persistent_param_and_check client "$test_at" "$param_at" 0
19154         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19155
19156         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19157         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19158         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19159         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19160         sync
19161         do_facet ost1 "$LCTL set_param fail_loc=0"
19162
19163         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19164         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19165                 $timeout
19166
19167         $LCTL set_param -n $pages_per_rpc
19168         restore_lustre_params < $p
19169         rm -f $p
19170 }
19171 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19172
19173 test_224d() { # LU-11169
19174         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19175 }
19176 run_test 224d "Don't corrupt data on bulk IO timeout"
19177
19178 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19179 test_225a () {
19180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19181         if [ -z ${MDSSURVEY} ]; then
19182                 skip_env "mds-survey not found"
19183         fi
19184         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19185                 skip "Need MDS version at least 2.2.51"
19186
19187         local mds=$(facet_host $SINGLEMDS)
19188         local target=$(do_nodes $mds 'lctl dl' |
19189                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19190
19191         local cmd1="file_count=1000 thrhi=4"
19192         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19193         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19194         local cmd="$cmd1 $cmd2 $cmd3"
19195
19196         rm -f ${TMP}/mds_survey*
19197         echo + $cmd
19198         eval $cmd || error "mds-survey with zero-stripe failed"
19199         cat ${TMP}/mds_survey*
19200         rm -f ${TMP}/mds_survey*
19201 }
19202 run_test 225a "Metadata survey sanity with zero-stripe"
19203
19204 test_225b () {
19205         if [ -z ${MDSSURVEY} ]; then
19206                 skip_env "mds-survey not found"
19207         fi
19208         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19209                 skip "Need MDS version at least 2.2.51"
19210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19211         remote_mds_nodsh && skip "remote MDS with nodsh"
19212         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19213                 skip_env "Need to mount OST to test"
19214         fi
19215
19216         local mds=$(facet_host $SINGLEMDS)
19217         local target=$(do_nodes $mds 'lctl dl' |
19218                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19219
19220         local cmd1="file_count=1000 thrhi=4"
19221         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19222         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19223         local cmd="$cmd1 $cmd2 $cmd3"
19224
19225         rm -f ${TMP}/mds_survey*
19226         echo + $cmd
19227         eval $cmd || error "mds-survey with stripe_count failed"
19228         cat ${TMP}/mds_survey*
19229         rm -f ${TMP}/mds_survey*
19230 }
19231 run_test 225b "Metadata survey sanity with stripe_count = 1"
19232
19233 mcreate_path2fid () {
19234         local mode=$1
19235         local major=$2
19236         local minor=$3
19237         local name=$4
19238         local desc=$5
19239         local path=$DIR/$tdir/$name
19240         local fid
19241         local rc
19242         local fid_path
19243
19244         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19245                 error "cannot create $desc"
19246
19247         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19248         rc=$?
19249         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19250
19251         fid_path=$($LFS fid2path $MOUNT $fid)
19252         rc=$?
19253         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19254
19255         [ "$path" == "$fid_path" ] ||
19256                 error "fid2path returned $fid_path, expected $path"
19257
19258         echo "pass with $path and $fid"
19259 }
19260
19261 test_226a () {
19262         rm -rf $DIR/$tdir
19263         mkdir -p $DIR/$tdir
19264
19265         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19266         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19267         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19268         mcreate_path2fid 0040666 0 0 dir "directory"
19269         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19270         mcreate_path2fid 0100666 0 0 file "regular file"
19271         mcreate_path2fid 0120666 0 0 link "symbolic link"
19272         mcreate_path2fid 0140666 0 0 sock "socket"
19273 }
19274 run_test 226a "call path2fid and fid2path on files of all type"
19275
19276 test_226b () {
19277         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19278
19279         local MDTIDX=1
19280
19281         rm -rf $DIR/$tdir
19282         mkdir -p $DIR/$tdir
19283         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19284                 error "create remote directory failed"
19285         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19286         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19287                                 "character special file (null)"
19288         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19289                                 "character special file (no device)"
19290         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19291         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19292                                 "block special file (loop)"
19293         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19294         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19295         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19296 }
19297 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19298
19299 test_226c () {
19300         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19301         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19302                 skip "Need MDS version at least 2.13.55"
19303
19304         local submnt=/mnt/submnt
19305         local srcfile=/etc/passwd
19306         local dstfile=$submnt/passwd
19307         local path
19308         local fid
19309
19310         rm -rf $DIR/$tdir
19311         rm -rf $submnt
19312         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19313                 error "create remote directory failed"
19314         mkdir -p $submnt || error "create $submnt failed"
19315         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19316                 error "mount $submnt failed"
19317         stack_trap "umount $submnt" EXIT
19318
19319         cp $srcfile $dstfile
19320         fid=$($LFS path2fid $dstfile)
19321         path=$($LFS fid2path $submnt "$fid")
19322         [ "$path" = "$dstfile" ] ||
19323                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19324 }
19325 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19326
19327 # LU-1299 Executing or running ldd on a truncated executable does not
19328 # cause an out-of-memory condition.
19329 test_227() {
19330         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19331         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19332
19333         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19334         chmod +x $MOUNT/date
19335
19336         $MOUNT/date > /dev/null
19337         ldd $MOUNT/date > /dev/null
19338         rm -f $MOUNT/date
19339 }
19340 run_test 227 "running truncated executable does not cause OOM"
19341
19342 # LU-1512 try to reuse idle OI blocks
19343 test_228a() {
19344         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19345         remote_mds_nodsh && skip "remote MDS with nodsh"
19346         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19347
19348         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19349         local myDIR=$DIR/$tdir
19350
19351         mkdir -p $myDIR
19352         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19353         $LCTL set_param fail_loc=0x80001002
19354         createmany -o $myDIR/t- 10000
19355         $LCTL set_param fail_loc=0
19356         # The guard is current the largest FID holder
19357         touch $myDIR/guard
19358         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19359                     tr -d '[')
19360         local IDX=$(($SEQ % 64))
19361
19362         do_facet $SINGLEMDS sync
19363         # Make sure journal flushed.
19364         sleep 6
19365         local blk1=$(do_facet $SINGLEMDS \
19366                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19367                      grep Blockcount | awk '{print $4}')
19368
19369         # Remove old files, some OI blocks will become idle.
19370         unlinkmany $myDIR/t- 10000
19371         # Create new files, idle OI blocks should be reused.
19372         createmany -o $myDIR/t- 2000
19373         do_facet $SINGLEMDS sync
19374         # Make sure journal flushed.
19375         sleep 6
19376         local blk2=$(do_facet $SINGLEMDS \
19377                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19378                      grep Blockcount | awk '{print $4}')
19379
19380         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19381 }
19382 run_test 228a "try to reuse idle OI blocks"
19383
19384 test_228b() {
19385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19386         remote_mds_nodsh && skip "remote MDS with nodsh"
19387         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19388
19389         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19390         local myDIR=$DIR/$tdir
19391
19392         mkdir -p $myDIR
19393         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19394         $LCTL set_param fail_loc=0x80001002
19395         createmany -o $myDIR/t- 10000
19396         $LCTL set_param fail_loc=0
19397         # The guard is current the largest FID holder
19398         touch $myDIR/guard
19399         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19400                     tr -d '[')
19401         local IDX=$(($SEQ % 64))
19402
19403         do_facet $SINGLEMDS sync
19404         # Make sure journal flushed.
19405         sleep 6
19406         local blk1=$(do_facet $SINGLEMDS \
19407                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19408                      grep Blockcount | awk '{print $4}')
19409
19410         # Remove old files, some OI blocks will become idle.
19411         unlinkmany $myDIR/t- 10000
19412
19413         # stop the MDT
19414         stop $SINGLEMDS || error "Fail to stop MDT."
19415         # remount the MDT
19416         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
19417
19418         df $MOUNT || error "Fail to df."
19419         # Create new files, idle OI blocks should be reused.
19420         createmany -o $myDIR/t- 2000
19421         do_facet $SINGLEMDS sync
19422         # Make sure journal flushed.
19423         sleep 6
19424         local blk2=$(do_facet $SINGLEMDS \
19425                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19426                      grep Blockcount | awk '{print $4}')
19427
19428         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19429 }
19430 run_test 228b "idle OI blocks can be reused after MDT restart"
19431
19432 #LU-1881
19433 test_228c() {
19434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19435         remote_mds_nodsh && skip "remote MDS with nodsh"
19436         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19437
19438         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19439         local myDIR=$DIR/$tdir
19440
19441         mkdir -p $myDIR
19442         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19443         $LCTL set_param fail_loc=0x80001002
19444         # 20000 files can guarantee there are index nodes in the OI file
19445         createmany -o $myDIR/t- 20000
19446         $LCTL set_param fail_loc=0
19447         # The guard is current the largest FID holder
19448         touch $myDIR/guard
19449         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19450                     tr -d '[')
19451         local IDX=$(($SEQ % 64))
19452
19453         do_facet $SINGLEMDS sync
19454         # Make sure journal flushed.
19455         sleep 6
19456         local blk1=$(do_facet $SINGLEMDS \
19457                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19458                      grep Blockcount | awk '{print $4}')
19459
19460         # Remove old files, some OI blocks will become idle.
19461         unlinkmany $myDIR/t- 20000
19462         rm -f $myDIR/guard
19463         # The OI file should become empty now
19464
19465         # Create new files, idle OI blocks should be reused.
19466         createmany -o $myDIR/t- 2000
19467         do_facet $SINGLEMDS sync
19468         # Make sure journal flushed.
19469         sleep 6
19470         local blk2=$(do_facet $SINGLEMDS \
19471                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19472                      grep Blockcount | awk '{print $4}')
19473
19474         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19475 }
19476 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19477
19478 test_229() { # LU-2482, LU-3448
19479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19480         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19481         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19482                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19483
19484         rm -f $DIR/$tfile
19485
19486         # Create a file with a released layout and stripe count 2.
19487         $MULTIOP $DIR/$tfile H2c ||
19488                 error "failed to create file with released layout"
19489
19490         $LFS getstripe -v $DIR/$tfile
19491
19492         local pattern=$($LFS getstripe -L $DIR/$tfile)
19493         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19494
19495         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19496                 error "getstripe"
19497         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19498         stat $DIR/$tfile || error "failed to stat released file"
19499
19500         chown $RUNAS_ID $DIR/$tfile ||
19501                 error "chown $RUNAS_ID $DIR/$tfile failed"
19502
19503         chgrp $RUNAS_ID $DIR/$tfile ||
19504                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19505
19506         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19507         rm $DIR/$tfile || error "failed to remove released file"
19508 }
19509 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19510
19511 test_230a() {
19512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19513         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19514         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19515                 skip "Need MDS version at least 2.11.52"
19516
19517         local MDTIDX=1
19518
19519         test_mkdir $DIR/$tdir
19520         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19521         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19522         [ $mdt_idx -ne 0 ] &&
19523                 error "create local directory on wrong MDT $mdt_idx"
19524
19525         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19526                         error "create remote directory failed"
19527         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19528         [ $mdt_idx -ne $MDTIDX ] &&
19529                 error "create remote directory on wrong MDT $mdt_idx"
19530
19531         createmany -o $DIR/$tdir/test_230/t- 10 ||
19532                 error "create files on remote directory failed"
19533         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19534         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19535         rm -r $DIR/$tdir || error "unlink remote directory failed"
19536 }
19537 run_test 230a "Create remote directory and files under the remote directory"
19538
19539 test_230b() {
19540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19541         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19542         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19543                 skip "Need MDS version at least 2.11.52"
19544
19545         local MDTIDX=1
19546         local mdt_index
19547         local i
19548         local file
19549         local pid
19550         local stripe_count
19551         local migrate_dir=$DIR/$tdir/migrate_dir
19552         local other_dir=$DIR/$tdir/other_dir
19553
19554         test_mkdir $DIR/$tdir
19555         test_mkdir -i0 -c1 $migrate_dir
19556         test_mkdir -i0 -c1 $other_dir
19557         for ((i=0; i<10; i++)); do
19558                 mkdir -p $migrate_dir/dir_${i}
19559                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19560                         error "create files under remote dir failed $i"
19561         done
19562
19563         cp /etc/passwd $migrate_dir/$tfile
19564         cp /etc/passwd $other_dir/$tfile
19565         chattr +SAD $migrate_dir
19566         chattr +SAD $migrate_dir/$tfile
19567
19568         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19569         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19570         local old_dir_mode=$(stat -c%f $migrate_dir)
19571         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19572
19573         mkdir -p $migrate_dir/dir_default_stripe2
19574         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19575         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19576
19577         mkdir -p $other_dir
19578         ln $migrate_dir/$tfile $other_dir/luna
19579         ln $migrate_dir/$tfile $migrate_dir/sofia
19580         ln $other_dir/$tfile $migrate_dir/david
19581         ln -s $migrate_dir/$tfile $other_dir/zachary
19582         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19583         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19584
19585         local len
19586         local lnktgt
19587
19588         # inline symlink
19589         for len in 58 59 60; do
19590                 lnktgt=$(str_repeat 'l' $len)
19591                 touch $migrate_dir/$lnktgt
19592                 ln -s $lnktgt $migrate_dir/${len}char_ln
19593         done
19594
19595         # PATH_MAX
19596         for len in 4094 4095; do
19597                 lnktgt=$(str_repeat 'l' $len)
19598                 ln -s $lnktgt $migrate_dir/${len}char_ln
19599         done
19600
19601         # NAME_MAX
19602         for len in 254 255; do
19603                 touch $migrate_dir/$(str_repeat 'l' $len)
19604         done
19605
19606         $LFS migrate -m $MDTIDX $migrate_dir ||
19607                 error "fails on migrating remote dir to MDT1"
19608
19609         echo "migratate to MDT1, then checking.."
19610         for ((i = 0; i < 10; i++)); do
19611                 for file in $(find $migrate_dir/dir_${i}); do
19612                         mdt_index=$($LFS getstripe -m $file)
19613                         # broken symlink getstripe will fail
19614                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19615                                 error "$file is not on MDT${MDTIDX}"
19616                 done
19617         done
19618
19619         # the multiple link file should still in MDT0
19620         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19621         [ $mdt_index == 0 ] ||
19622                 error "$file is not on MDT${MDTIDX}"
19623
19624         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19625         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19626                 error " expect $old_dir_flag get $new_dir_flag"
19627
19628         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19629         [ "$old_file_flag" = "$new_file_flag" ] ||
19630                 error " expect $old_file_flag get $new_file_flag"
19631
19632         local new_dir_mode=$(stat -c%f $migrate_dir)
19633         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19634                 error "expect mode $old_dir_mode get $new_dir_mode"
19635
19636         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19637         [ "$old_file_mode" = "$new_file_mode" ] ||
19638                 error "expect mode $old_file_mode get $new_file_mode"
19639
19640         diff /etc/passwd $migrate_dir/$tfile ||
19641                 error "$tfile different after migration"
19642
19643         diff /etc/passwd $other_dir/luna ||
19644                 error "luna different after migration"
19645
19646         diff /etc/passwd $migrate_dir/sofia ||
19647                 error "sofia different after migration"
19648
19649         diff /etc/passwd $migrate_dir/david ||
19650                 error "david different after migration"
19651
19652         diff /etc/passwd $other_dir/zachary ||
19653                 error "zachary different after migration"
19654
19655         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19656                 error "${tfile}_ln different after migration"
19657
19658         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19659                 error "${tfile}_ln_other different after migration"
19660
19661         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19662         [ $stripe_count = 2 ] ||
19663                 error "dir strpe_count $d != 2 after migration."
19664
19665         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19666         [ $stripe_count = 2 ] ||
19667                 error "file strpe_count $d != 2 after migration."
19668
19669         #migrate back to MDT0
19670         MDTIDX=0
19671
19672         $LFS migrate -m $MDTIDX $migrate_dir ||
19673                 error "fails on migrating remote dir to MDT0"
19674
19675         echo "migrate back to MDT0, checking.."
19676         for file in $(find $migrate_dir); do
19677                 mdt_index=$($LFS getstripe -m $file)
19678                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19679                         error "$file is not on MDT${MDTIDX}"
19680         done
19681
19682         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19683         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19684                 error " expect $old_dir_flag get $new_dir_flag"
19685
19686         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19687         [ "$old_file_flag" = "$new_file_flag" ] ||
19688                 error " expect $old_file_flag get $new_file_flag"
19689
19690         local new_dir_mode=$(stat -c%f $migrate_dir)
19691         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19692                 error "expect mode $old_dir_mode get $new_dir_mode"
19693
19694         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19695         [ "$old_file_mode" = "$new_file_mode" ] ||
19696                 error "expect mode $old_file_mode get $new_file_mode"
19697
19698         diff /etc/passwd ${migrate_dir}/$tfile ||
19699                 error "$tfile different after migration"
19700
19701         diff /etc/passwd ${other_dir}/luna ||
19702                 error "luna different after migration"
19703
19704         diff /etc/passwd ${migrate_dir}/sofia ||
19705                 error "sofia different after migration"
19706
19707         diff /etc/passwd ${other_dir}/zachary ||
19708                 error "zachary different after migration"
19709
19710         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19711                 error "${tfile}_ln different after migration"
19712
19713         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19714                 error "${tfile}_ln_other different after migration"
19715
19716         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19717         [ $stripe_count = 2 ] ||
19718                 error "dir strpe_count $d != 2 after migration."
19719
19720         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19721         [ $stripe_count = 2 ] ||
19722                 error "file strpe_count $d != 2 after migration."
19723
19724         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19725 }
19726 run_test 230b "migrate directory"
19727
19728 test_230c() {
19729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19730         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19731         remote_mds_nodsh && skip "remote MDS with nodsh"
19732         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19733                 skip "Need MDS version at least 2.11.52"
19734
19735         local MDTIDX=1
19736         local total=3
19737         local mdt_index
19738         local file
19739         local migrate_dir=$DIR/$tdir/migrate_dir
19740
19741         #If migrating directory fails in the middle, all entries of
19742         #the directory is still accessiable.
19743         test_mkdir $DIR/$tdir
19744         test_mkdir -i0 -c1 $migrate_dir
19745         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19746         stat $migrate_dir
19747         createmany -o $migrate_dir/f $total ||
19748                 error "create files under ${migrate_dir} failed"
19749
19750         # fail after migrating top dir, and this will fail only once, so the
19751         # first sub file migration will fail (currently f3), others succeed.
19752         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19753         do_facet mds1 lctl set_param fail_loc=0x1801
19754         local t=$(ls $migrate_dir | wc -l)
19755         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19756                 error "migrate should fail"
19757         local u=$(ls $migrate_dir | wc -l)
19758         [ "$u" == "$t" ] || error "$u != $t during migration"
19759
19760         # add new dir/file should succeed
19761         mkdir $migrate_dir/dir ||
19762                 error "mkdir failed under migrating directory"
19763         touch $migrate_dir/file ||
19764                 error "create file failed under migrating directory"
19765
19766         # add file with existing name should fail
19767         for file in $migrate_dir/f*; do
19768                 stat $file > /dev/null || error "stat $file failed"
19769                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19770                         error "open(O_CREAT|O_EXCL) $file should fail"
19771                 $MULTIOP $file m && error "create $file should fail"
19772                 touch $DIR/$tdir/remote_dir/$tfile ||
19773                         error "touch $tfile failed"
19774                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19775                         error "link $file should fail"
19776                 mdt_index=$($LFS getstripe -m $file)
19777                 if [ $mdt_index == 0 ]; then
19778                         # file failed to migrate is not allowed to rename to
19779                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19780                                 error "rename to $file should fail"
19781                 else
19782                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19783                                 error "rename to $file failed"
19784                 fi
19785                 echo hello >> $file || error "write $file failed"
19786         done
19787
19788         # resume migration with different options should fail
19789         $LFS migrate -m 0 $migrate_dir &&
19790                 error "migrate -m 0 $migrate_dir should fail"
19791
19792         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19793                 error "migrate -c 2 $migrate_dir should fail"
19794
19795         # resume migration should succeed
19796         $LFS migrate -m $MDTIDX $migrate_dir ||
19797                 error "migrate $migrate_dir failed"
19798
19799         echo "Finish migration, then checking.."
19800         for file in $(find $migrate_dir); do
19801                 mdt_index=$($LFS getstripe -m $file)
19802                 [ $mdt_index == $MDTIDX ] ||
19803                         error "$file is not on MDT${MDTIDX}"
19804         done
19805
19806         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19807 }
19808 run_test 230c "check directory accessiblity if migration failed"
19809
19810 test_230d() {
19811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19812         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19813         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19814                 skip "Need MDS version at least 2.11.52"
19815         # LU-11235
19816         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19817
19818         local migrate_dir=$DIR/$tdir/migrate_dir
19819         local old_index
19820         local new_index
19821         local old_count
19822         local new_count
19823         local new_hash
19824         local mdt_index
19825         local i
19826         local j
19827
19828         old_index=$((RANDOM % MDSCOUNT))
19829         old_count=$((MDSCOUNT - old_index))
19830         new_index=$((RANDOM % MDSCOUNT))
19831         new_count=$((MDSCOUNT - new_index))
19832         new_hash=1 # for all_char
19833
19834         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19835         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19836
19837         test_mkdir $DIR/$tdir
19838         test_mkdir -i $old_index -c $old_count $migrate_dir
19839
19840         for ((i=0; i<100; i++)); do
19841                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19842                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19843                         error "create files under remote dir failed $i"
19844         done
19845
19846         echo -n "Migrate from MDT$old_index "
19847         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19848         echo -n "to MDT$new_index"
19849         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19850         echo
19851
19852         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19853         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19854                 error "migrate remote dir error"
19855
19856         echo "Finish migration, then checking.."
19857         for file in $(find $migrate_dir -maxdepth 1); do
19858                 mdt_index=$($LFS getstripe -m $file)
19859                 if [ $mdt_index -lt $new_index ] ||
19860                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19861                         error "$file is on MDT$mdt_index"
19862                 fi
19863         done
19864
19865         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19866 }
19867 run_test 230d "check migrate big directory"
19868
19869 test_230e() {
19870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19871         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19872         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19873                 skip "Need MDS version at least 2.11.52"
19874
19875         local i
19876         local j
19877         local a_fid
19878         local b_fid
19879
19880         mkdir_on_mdt0 $DIR/$tdir
19881         mkdir $DIR/$tdir/migrate_dir
19882         mkdir $DIR/$tdir/other_dir
19883         touch $DIR/$tdir/migrate_dir/a
19884         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19885         ls $DIR/$tdir/other_dir
19886
19887         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19888                 error "migrate dir fails"
19889
19890         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19891         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19892
19893         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19894         [ $mdt_index == 0 ] || error "a is not on MDT0"
19895
19896         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19897                 error "migrate dir fails"
19898
19899         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19900         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19901
19902         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19903         [ $mdt_index == 1 ] || error "a is not on MDT1"
19904
19905         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19906         [ $mdt_index == 1 ] || error "b is not on MDT1"
19907
19908         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19909         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19910
19911         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19912
19913         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19914 }
19915 run_test 230e "migrate mulitple local link files"
19916
19917 test_230f() {
19918         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19919         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19920         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19921                 skip "Need MDS version at least 2.11.52"
19922
19923         local a_fid
19924         local ln_fid
19925
19926         mkdir -p $DIR/$tdir
19927         mkdir $DIR/$tdir/migrate_dir
19928         $LFS mkdir -i1 $DIR/$tdir/other_dir
19929         touch $DIR/$tdir/migrate_dir/a
19930         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
19931         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
19932         ls $DIR/$tdir/other_dir
19933
19934         # a should be migrated to MDT1, since no other links on MDT0
19935         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19936                 error "#1 migrate dir fails"
19937         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19938         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19939         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19940         [ $mdt_index == 1 ] || error "a is not on MDT1"
19941
19942         # a should stay on MDT1, because it is a mulitple link file
19943         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19944                 error "#2 migrate dir fails"
19945         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19946         [ $mdt_index == 1 ] || error "a is not on MDT1"
19947
19948         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19949                 error "#3 migrate dir fails"
19950
19951         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19952         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
19953         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
19954
19955         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
19956         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
19957
19958         # a should be migrated to MDT0, since no other links on MDT1
19959         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19960                 error "#4 migrate dir fails"
19961         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19962         [ $mdt_index == 0 ] || error "a is not on MDT0"
19963
19964         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19965 }
19966 run_test 230f "migrate mulitple remote link files"
19967
19968 test_230g() {
19969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19970         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19971         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19972                 skip "Need MDS version at least 2.11.52"
19973
19974         mkdir -p $DIR/$tdir/migrate_dir
19975
19976         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
19977                 error "migrating dir to non-exist MDT succeeds"
19978         true
19979 }
19980 run_test 230g "migrate dir to non-exist MDT"
19981
19982 test_230h() {
19983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19984         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19985         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19986                 skip "Need MDS version at least 2.11.52"
19987
19988         local mdt_index
19989
19990         mkdir -p $DIR/$tdir/migrate_dir
19991
19992         $LFS migrate -m1 $DIR &&
19993                 error "migrating mountpoint1 should fail"
19994
19995         $LFS migrate -m1 $DIR/$tdir/.. &&
19996                 error "migrating mountpoint2 should fail"
19997
19998         # same as mv
19999         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20000                 error "migrating $tdir/migrate_dir/.. should fail"
20001
20002         true
20003 }
20004 run_test 230h "migrate .. and root"
20005
20006 test_230i() {
20007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20008         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20009         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20010                 skip "Need MDS version at least 2.11.52"
20011
20012         mkdir -p $DIR/$tdir/migrate_dir
20013
20014         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20015                 error "migration fails with a tailing slash"
20016
20017         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20018                 error "migration fails with two tailing slashes"
20019 }
20020 run_test 230i "lfs migrate -m tolerates trailing slashes"
20021
20022 test_230j() {
20023         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20024         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20025                 skip "Need MDS version at least 2.11.52"
20026
20027         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20028         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20029                 error "create $tfile failed"
20030         cat /etc/passwd > $DIR/$tdir/$tfile
20031
20032         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20033
20034         cmp /etc/passwd $DIR/$tdir/$tfile ||
20035                 error "DoM file mismatch after migration"
20036 }
20037 run_test 230j "DoM file data not changed after dir migration"
20038
20039 test_230k() {
20040         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20041         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20042                 skip "Need MDS version at least 2.11.56"
20043
20044         local total=20
20045         local files_on_starting_mdt=0
20046
20047         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20048         $LFS getdirstripe $DIR/$tdir
20049         for i in $(seq $total); do
20050                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20051                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20052                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20053         done
20054
20055         echo "$files_on_starting_mdt files on MDT0"
20056
20057         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20058         $LFS getdirstripe $DIR/$tdir
20059
20060         files_on_starting_mdt=0
20061         for i in $(seq $total); do
20062                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20063                         error "file $tfile.$i mismatch after migration"
20064                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20065                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20066         done
20067
20068         echo "$files_on_starting_mdt files on MDT1 after migration"
20069         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20070
20071         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20072         $LFS getdirstripe $DIR/$tdir
20073
20074         files_on_starting_mdt=0
20075         for i in $(seq $total); do
20076                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20077                         error "file $tfile.$i mismatch after 2nd migration"
20078                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20079                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20080         done
20081
20082         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20083         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20084
20085         true
20086 }
20087 run_test 230k "file data not changed after dir migration"
20088
20089 test_230l() {
20090         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20091         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20092                 skip "Need MDS version at least 2.11.56"
20093
20094         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20095         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20096                 error "create files under remote dir failed $i"
20097         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20098 }
20099 run_test 230l "readdir between MDTs won't crash"
20100
20101 test_230m() {
20102         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20103         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20104                 skip "Need MDS version at least 2.11.56"
20105
20106         local MDTIDX=1
20107         local mig_dir=$DIR/$tdir/migrate_dir
20108         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20109         local shortstr="b"
20110         local val
20111
20112         echo "Creating files and dirs with xattrs"
20113         test_mkdir $DIR/$tdir
20114         test_mkdir -i0 -c1 $mig_dir
20115         mkdir $mig_dir/dir
20116         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20117                 error "cannot set xattr attr1 on dir"
20118         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20119                 error "cannot set xattr attr2 on dir"
20120         touch $mig_dir/dir/f0
20121         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20122                 error "cannot set xattr attr1 on file"
20123         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20124                 error "cannot set xattr attr2 on file"
20125         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20126         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20127         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20128         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20129         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20130         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20131         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20132         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20133         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20134
20135         echo "Migrating to MDT1"
20136         $LFS migrate -m $MDTIDX $mig_dir ||
20137                 error "fails on migrating dir to MDT1"
20138
20139         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20140         echo "Checking xattrs"
20141         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20142         [ "$val" = $longstr ] ||
20143                 error "expecting xattr1 $longstr on dir, found $val"
20144         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20145         [ "$val" = $shortstr ] ||
20146                 error "expecting xattr2 $shortstr on dir, found $val"
20147         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20148         [ "$val" = $longstr ] ||
20149                 error "expecting xattr1 $longstr on file, found $val"
20150         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20151         [ "$val" = $shortstr ] ||
20152                 error "expecting xattr2 $shortstr on file, found $val"
20153 }
20154 run_test 230m "xattrs not changed after dir migration"
20155
20156 test_230n() {
20157         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20158         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20159                 skip "Need MDS version at least 2.13.53"
20160
20161         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20162         cat /etc/hosts > $DIR/$tdir/$tfile
20163         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20164         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20165
20166         cmp /etc/hosts $DIR/$tdir/$tfile ||
20167                 error "File data mismatch after migration"
20168 }
20169 run_test 230n "Dir migration with mirrored file"
20170
20171 test_230o() {
20172         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20173         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20174                 skip "Need MDS version at least 2.13.52"
20175
20176         local mdts=$(comma_list $(mdts_nodes))
20177         local timeout=100
20178         local restripe_status
20179         local delta
20180         local i
20181
20182         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20183
20184         # in case "crush" hash type is not set
20185         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20186
20187         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20188                            mdt.*MDT0000.enable_dir_restripe)
20189         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20190         stack_trap "do_nodes $mdts $LCTL set_param \
20191                     mdt.*.enable_dir_restripe=$restripe_status"
20192
20193         mkdir $DIR/$tdir
20194         createmany -m $DIR/$tdir/f 100 ||
20195                 error "create files under remote dir failed $i"
20196         createmany -d $DIR/$tdir/d 100 ||
20197                 error "create dirs under remote dir failed $i"
20198
20199         for i in $(seq 2 $MDSCOUNT); do
20200                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20201                 $LFS setdirstripe -c $i $DIR/$tdir ||
20202                         error "split -c $i $tdir failed"
20203                 wait_update $HOSTNAME \
20204                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20205                         error "dir split not finished"
20206                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20207                         awk '/migrate/ {sum += $2} END { print sum }')
20208                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20209                 # delta is around total_files/stripe_count
20210                 (( $delta < 200 / (i - 1) + 4 )) ||
20211                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20212         done
20213 }
20214 run_test 230o "dir split"
20215
20216 test_230p() {
20217         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20218         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20219                 skip "Need MDS version at least 2.13.52"
20220
20221         local mdts=$(comma_list $(mdts_nodes))
20222         local timeout=100
20223         local restripe_status
20224         local delta
20225         local c
20226
20227         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20228
20229         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20230
20231         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20232                            mdt.*MDT0000.enable_dir_restripe)
20233         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20234         stack_trap "do_nodes $mdts $LCTL set_param \
20235                     mdt.*.enable_dir_restripe=$restripe_status"
20236
20237         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20238         createmany -m $DIR/$tdir/f 100 ||
20239                 error "create files under remote dir failed"
20240         createmany -d $DIR/$tdir/d 100 ||
20241                 error "create dirs under remote dir failed"
20242
20243         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20244                 local mdt_hash="crush"
20245
20246                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20247                 $LFS setdirstripe -c $c $DIR/$tdir ||
20248                         error "split -c $c $tdir failed"
20249                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20250                         mdt_hash="$mdt_hash,fixed"
20251                 elif [ $c -eq 1 ]; then
20252                         mdt_hash="none"
20253                 fi
20254                 wait_update $HOSTNAME \
20255                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20256                         error "dir merge not finished"
20257                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20258                         awk '/migrate/ {sum += $2} END { print sum }')
20259                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20260                 # delta is around total_files/stripe_count
20261                 (( delta < 200 / c + 4 )) ||
20262                         error "$delta files migrated >= $((200 / c + 4))"
20263         done
20264 }
20265 run_test 230p "dir merge"
20266
20267 test_230q() {
20268         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20269         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20270                 skip "Need MDS version at least 2.13.52"
20271
20272         local mdts=$(comma_list $(mdts_nodes))
20273         local saved_threshold=$(do_facet mds1 \
20274                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20275         local saved_delta=$(do_facet mds1 \
20276                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20277         local threshold=100
20278         local delta=2
20279         local total=0
20280         local stripe_count=0
20281         local stripe_index
20282         local nr_files
20283         local create
20284
20285         # test with fewer files on ZFS
20286         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20287
20288         stack_trap "do_nodes $mdts $LCTL set_param \
20289                     mdt.*.dir_split_count=$saved_threshold"
20290         stack_trap "do_nodes $mdts $LCTL set_param \
20291                     mdt.*.dir_split_delta=$saved_delta"
20292         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20293         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20294         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20295         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20296         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20297         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20298
20299         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20300         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20301
20302         create=$((threshold * 3 / 2))
20303         while [ $stripe_count -lt $MDSCOUNT ]; do
20304                 createmany -m $DIR/$tdir/f $total $create ||
20305                         error "create sub files failed"
20306                 stat $DIR/$tdir > /dev/null
20307                 total=$((total + create))
20308                 stripe_count=$((stripe_count + delta))
20309                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20310
20311                 wait_update $HOSTNAME \
20312                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20313                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20314
20315                 wait_update $HOSTNAME \
20316                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20317                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20318
20319                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20320                 echo "$nr_files/$total files on MDT$stripe_index after split"
20321                 # allow 10% margin of imbalance with crush hash
20322                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20323                         error "$nr_files files on MDT$stripe_index after split"
20324
20325                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20326                 [ $nr_files -eq $total ] ||
20327                         error "total sub files $nr_files != $total"
20328         done
20329
20330         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20331
20332         echo "fixed layout directory won't auto split"
20333         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20334         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20335                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20336         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20337                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20338 }
20339 run_test 230q "dir auto split"
20340
20341 test_230r() {
20342         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20343         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20344         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20345                 skip "Need MDS version at least 2.13.54"
20346
20347         # maximum amount of local locks:
20348         # parent striped dir - 2 locks
20349         # new stripe in parent to migrate to - 1 lock
20350         # source and target - 2 locks
20351         # Total 5 locks for regular file
20352         mkdir -p $DIR/$tdir
20353         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20354         touch $DIR/$tdir/dir1/eee
20355
20356         # create 4 hardlink for 4 more locks
20357         # Total: 9 locks > RS_MAX_LOCKS (8)
20358         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20359         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20360         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20361         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20362         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20363         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20364         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20365         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20366
20367         cancel_lru_locks mdc
20368
20369         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20370                 error "migrate dir fails"
20371
20372         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20373 }
20374 run_test 230r "migrate with too many local locks"
20375
20376 test_230s() {
20377         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
20378                 skip "Need MDS version at least 2.13.57"
20379
20380         local mdts=$(comma_list $(mdts_nodes))
20381         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20382                                 mdt.*MDT0000.enable_dir_restripe)
20383
20384         stack_trap "do_nodes $mdts $LCTL set_param \
20385                     mdt.*.enable_dir_restripe=$restripe_status"
20386
20387         local st
20388         for st in 0 1; do
20389                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20390                 test_mkdir $DIR/$tdir
20391                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20392                         error "$LFS mkdir doesn't return -EEXIST if target exists"
20393                 rmdir $DIR/$tdir
20394         done
20395 }
20396 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20397
20398 test_230t()
20399 {
20400         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20401         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20402                 skip "Need MDS version at least 2.14.50"
20403
20404         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20405         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20406         $LFS project -p 1 -s $DIR/$tdir ||
20407                 error "set $tdir project id failed"
20408         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20409                 error "set subdir project id failed"
20410         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20411 }
20412 run_test 230t "migrate directory with project ID set"
20413
20414 test_230u()
20415 {
20416         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20417         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20418                 skip "Need MDS version at least 2.14.53"
20419
20420         local count
20421
20422         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20423         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20424         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20425         for i in $(seq 0 $((MDSCOUNT - 1))); do
20426                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20427                 echo "$count dirs migrated to MDT$i"
20428         done
20429         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20430         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20431 }
20432 run_test 230u "migrate directory by QOS"
20433
20434 test_230v()
20435 {
20436         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20437         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20438                 skip "Need MDS version at least 2.14.53"
20439
20440         local count
20441
20442         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20443         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20444         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20445         for i in $(seq 0 $((MDSCOUNT - 1))); do
20446                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20447                 echo "$count subdirs migrated to MDT$i"
20448                 (( i == 3 )) && (( count > 0 )) &&
20449                         error "subdir shouldn't be migrated to MDT3"
20450         done
20451         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20452         (( count == 3 )) || error "dirs migrated to $count MDTs"
20453 }
20454 run_test 230v "subdir migrated to the MDT where its parent is located"
20455
20456 test_230w() {
20457         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20458         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20459                 skip "Need MDS version at least 2.14.53"
20460
20461         mkdir -p $DIR/$tdir/sub || error "mkdir failed"
20462
20463         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
20464                 error "migrate failed"
20465
20466         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
20467                 error "$tdir stripe count mismatch"
20468
20469         (( $($LFS getdirstripe -c $DIR/$tdir/sub) == 0 )) ||
20470                 error "$tdir/sub is striped"
20471 }
20472 run_test 230w "non-recursive mode dir migration"
20473
20474 test_231a()
20475 {
20476         # For simplicity this test assumes that max_pages_per_rpc
20477         # is the same across all OSCs
20478         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20479         local bulk_size=$((max_pages * PAGE_SIZE))
20480         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20481                                        head -n 1)
20482
20483         mkdir -p $DIR/$tdir
20484         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20485                 error "failed to set stripe with -S ${brw_size}M option"
20486
20487         # clear the OSC stats
20488         $LCTL set_param osc.*.stats=0 &>/dev/null
20489         stop_writeback
20490
20491         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20492         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20493                 oflag=direct &>/dev/null || error "dd failed"
20494
20495         sync; sleep 1; sync # just to be safe
20496         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20497         if [ x$nrpcs != "x1" ]; then
20498                 $LCTL get_param osc.*.stats
20499                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20500         fi
20501
20502         start_writeback
20503         # Drop the OSC cache, otherwise we will read from it
20504         cancel_lru_locks osc
20505
20506         # clear the OSC stats
20507         $LCTL set_param osc.*.stats=0 &>/dev/null
20508
20509         # Client reads $bulk_size.
20510         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20511                 iflag=direct &>/dev/null || error "dd failed"
20512
20513         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20514         if [ x$nrpcs != "x1" ]; then
20515                 $LCTL get_param osc.*.stats
20516                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20517         fi
20518 }
20519 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20520
20521 test_231b() {
20522         mkdir -p $DIR/$tdir
20523         local i
20524         for i in {0..1023}; do
20525                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20526                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20527                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20528         done
20529         sync
20530 }
20531 run_test 231b "must not assert on fully utilized OST request buffer"
20532
20533 test_232a() {
20534         mkdir -p $DIR/$tdir
20535         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20536
20537         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20538         do_facet ost1 $LCTL set_param fail_loc=0x31c
20539
20540         # ignore dd failure
20541         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20542
20543         do_facet ost1 $LCTL set_param fail_loc=0
20544         umount_client $MOUNT || error "umount failed"
20545         mount_client $MOUNT || error "mount failed"
20546         stop ost1 || error "cannot stop ost1"
20547         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20548 }
20549 run_test 232a "failed lock should not block umount"
20550
20551 test_232b() {
20552         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20553                 skip "Need MDS version at least 2.10.58"
20554
20555         mkdir -p $DIR/$tdir
20556         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20557         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20558         sync
20559         cancel_lru_locks osc
20560
20561         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20562         do_facet ost1 $LCTL set_param fail_loc=0x31c
20563
20564         # ignore failure
20565         $LFS data_version $DIR/$tdir/$tfile || true
20566
20567         do_facet ost1 $LCTL set_param fail_loc=0
20568         umount_client $MOUNT || error "umount failed"
20569         mount_client $MOUNT || error "mount failed"
20570         stop ost1 || error "cannot stop ost1"
20571         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20572 }
20573 run_test 232b "failed data version lock should not block umount"
20574
20575 test_233a() {
20576         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20577                 skip "Need MDS version at least 2.3.64"
20578         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20579
20580         local fid=$($LFS path2fid $MOUNT)
20581
20582         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20583                 error "cannot access $MOUNT using its FID '$fid'"
20584 }
20585 run_test 233a "checking that OBF of the FS root succeeds"
20586
20587 test_233b() {
20588         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20589                 skip "Need MDS version at least 2.5.90"
20590         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20591
20592         local fid=$($LFS path2fid $MOUNT/.lustre)
20593
20594         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20595                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20596
20597         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20598         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20599                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20600 }
20601 run_test 233b "checking that OBF of the FS .lustre succeeds"
20602
20603 test_234() {
20604         local p="$TMP/sanityN-$TESTNAME.parameters"
20605         save_lustre_params client "llite.*.xattr_cache" > $p
20606         lctl set_param llite.*.xattr_cache 1 ||
20607                 skip_env "xattr cache is not supported"
20608
20609         mkdir -p $DIR/$tdir || error "mkdir failed"
20610         touch $DIR/$tdir/$tfile || error "touch failed"
20611         # OBD_FAIL_LLITE_XATTR_ENOMEM
20612         $LCTL set_param fail_loc=0x1405
20613         getfattr -n user.attr $DIR/$tdir/$tfile &&
20614                 error "getfattr should have failed with ENOMEM"
20615         $LCTL set_param fail_loc=0x0
20616         rm -rf $DIR/$tdir
20617
20618         restore_lustre_params < $p
20619         rm -f $p
20620 }
20621 run_test 234 "xattr cache should not crash on ENOMEM"
20622
20623 test_235() {
20624         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20625                 skip "Need MDS version at least 2.4.52"
20626
20627         flock_deadlock $DIR/$tfile
20628         local RC=$?
20629         case $RC in
20630                 0)
20631                 ;;
20632                 124) error "process hangs on a deadlock"
20633                 ;;
20634                 *) error "error executing flock_deadlock $DIR/$tfile"
20635                 ;;
20636         esac
20637 }
20638 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20639
20640 #LU-2935
20641 test_236() {
20642         check_swap_layouts_support
20643
20644         local ref1=/etc/passwd
20645         local ref2=/etc/group
20646         local file1=$DIR/$tdir/f1
20647         local file2=$DIR/$tdir/f2
20648
20649         test_mkdir -c1 $DIR/$tdir
20650         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20651         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20652         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20653         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20654         local fd=$(free_fd)
20655         local cmd="exec $fd<>$file2"
20656         eval $cmd
20657         rm $file2
20658         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20659                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20660         cmd="exec $fd>&-"
20661         eval $cmd
20662         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20663
20664         #cleanup
20665         rm -rf $DIR/$tdir
20666 }
20667 run_test 236 "Layout swap on open unlinked file"
20668
20669 # LU-4659 linkea consistency
20670 test_238() {
20671         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20672                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20673                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20674                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20675
20676         touch $DIR/$tfile
20677         ln $DIR/$tfile $DIR/$tfile.lnk
20678         touch $DIR/$tfile.new
20679         mv $DIR/$tfile.new $DIR/$tfile
20680         local fid1=$($LFS path2fid $DIR/$tfile)
20681         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20682         local path1=$($LFS fid2path $FSNAME "$fid1")
20683         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20684         local path2=$($LFS fid2path $FSNAME "$fid2")
20685         [ $tfile.lnk == $path2 ] ||
20686                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20687         rm -f $DIR/$tfile*
20688 }
20689 run_test 238 "Verify linkea consistency"
20690
20691 test_239A() { # was test_239
20692         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20693                 skip "Need MDS version at least 2.5.60"
20694
20695         local list=$(comma_list $(mdts_nodes))
20696
20697         mkdir -p $DIR/$tdir
20698         createmany -o $DIR/$tdir/f- 5000
20699         unlinkmany $DIR/$tdir/f- 5000
20700         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20701                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20702         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20703                         osp.*MDT*.sync_in_flight" | calc_sum)
20704         [ "$changes" -eq 0 ] || error "$changes not synced"
20705 }
20706 run_test 239A "osp_sync test"
20707
20708 test_239a() { #LU-5297
20709         remote_mds_nodsh && skip "remote MDS with nodsh"
20710
20711         touch $DIR/$tfile
20712         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20713         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20714         chgrp $RUNAS_GID $DIR/$tfile
20715         wait_delete_completed
20716 }
20717 run_test 239a "process invalid osp sync record correctly"
20718
20719 test_239b() { #LU-5297
20720         remote_mds_nodsh && skip "remote MDS with nodsh"
20721
20722         touch $DIR/$tfile1
20723         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20724         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20725         chgrp $RUNAS_GID $DIR/$tfile1
20726         wait_delete_completed
20727         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20728         touch $DIR/$tfile2
20729         chgrp $RUNAS_GID $DIR/$tfile2
20730         wait_delete_completed
20731 }
20732 run_test 239b "process osp sync record with ENOMEM error correctly"
20733
20734 test_240() {
20735         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20736         remote_mds_nodsh && skip "remote MDS with nodsh"
20737
20738         mkdir -p $DIR/$tdir
20739
20740         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20741                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20742         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20743                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20744
20745         umount_client $MOUNT || error "umount failed"
20746         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20747         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20748         mount_client $MOUNT || error "failed to mount client"
20749
20750         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20751         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20752 }
20753 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20754
20755 test_241_bio() {
20756         local count=$1
20757         local bsize=$2
20758
20759         for LOOP in $(seq $count); do
20760                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20761                 cancel_lru_locks $OSC || true
20762         done
20763 }
20764
20765 test_241_dio() {
20766         local count=$1
20767         local bsize=$2
20768
20769         for LOOP in $(seq $1); do
20770                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20771                         2>/dev/null
20772         done
20773 }
20774
20775 test_241a() { # was test_241
20776         local bsize=$PAGE_SIZE
20777
20778         (( bsize < 40960 )) && bsize=40960
20779         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20780         ls -la $DIR/$tfile
20781         cancel_lru_locks $OSC
20782         test_241_bio 1000 $bsize &
20783         PID=$!
20784         test_241_dio 1000 $bsize
20785         wait $PID
20786 }
20787 run_test 241a "bio vs dio"
20788
20789 test_241b() {
20790         local bsize=$PAGE_SIZE
20791
20792         (( bsize < 40960 )) && bsize=40960
20793         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20794         ls -la $DIR/$tfile
20795         test_241_dio 1000 $bsize &
20796         PID=$!
20797         test_241_dio 1000 $bsize
20798         wait $PID
20799 }
20800 run_test 241b "dio vs dio"
20801
20802 test_242() {
20803         remote_mds_nodsh && skip "remote MDS with nodsh"
20804
20805         mkdir_on_mdt0 $DIR/$tdir
20806         touch $DIR/$tdir/$tfile
20807
20808         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20809         do_facet mds1 lctl set_param fail_loc=0x105
20810         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20811
20812         do_facet mds1 lctl set_param fail_loc=0
20813         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20814 }
20815 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20816
20817 test_243()
20818 {
20819         test_mkdir $DIR/$tdir
20820         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20821 }
20822 run_test 243 "various group lock tests"
20823
20824 test_244a()
20825 {
20826         test_mkdir $DIR/$tdir
20827         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20828         sendfile_grouplock $DIR/$tdir/$tfile || \
20829                 error "sendfile+grouplock failed"
20830         rm -rf $DIR/$tdir
20831 }
20832 run_test 244a "sendfile with group lock tests"
20833
20834 test_244b()
20835 {
20836         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20837
20838         local threads=50
20839         local size=$((1024*1024))
20840
20841         test_mkdir $DIR/$tdir
20842         for i in $(seq 1 $threads); do
20843                 local file=$DIR/$tdir/file_$((i / 10))
20844                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20845                 local pids[$i]=$!
20846         done
20847         for i in $(seq 1 $threads); do
20848                 wait ${pids[$i]}
20849         done
20850 }
20851 run_test 244b "multi-threaded write with group lock"
20852
20853 test_245() {
20854         local flagname="multi_mod_rpcs"
20855         local connect_data_name="max_mod_rpcs"
20856         local out
20857
20858         # check if multiple modify RPCs flag is set
20859         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20860                 grep "connect_flags:")
20861         echo "$out"
20862
20863         echo "$out" | grep -qw $flagname
20864         if [ $? -ne 0 ]; then
20865                 echo "connect flag $flagname is not set"
20866                 return
20867         fi
20868
20869         # check if multiple modify RPCs data is set
20870         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20871         echo "$out"
20872
20873         echo "$out" | grep -qw $connect_data_name ||
20874                 error "import should have connect data $connect_data_name"
20875 }
20876 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
20877
20878 cleanup_247() {
20879         local submount=$1
20880
20881         trap 0
20882         umount_client $submount
20883         rmdir $submount
20884 }
20885
20886 test_247a() {
20887         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20888                 grep -q subtree ||
20889                 skip_env "Fileset feature is not supported"
20890
20891         local submount=${MOUNT}_$tdir
20892
20893         mkdir $MOUNT/$tdir
20894         mkdir -p $submount || error "mkdir $submount failed"
20895         FILESET="$FILESET/$tdir" mount_client $submount ||
20896                 error "mount $submount failed"
20897         trap "cleanup_247 $submount" EXIT
20898         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
20899         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
20900                 error "read $MOUNT/$tdir/$tfile failed"
20901         cleanup_247 $submount
20902 }
20903 run_test 247a "mount subdir as fileset"
20904
20905 test_247b() {
20906         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20907                 skip_env "Fileset feature is not supported"
20908
20909         local submount=${MOUNT}_$tdir
20910
20911         rm -rf $MOUNT/$tdir
20912         mkdir -p $submount || error "mkdir $submount failed"
20913         SKIP_FILESET=1
20914         FILESET="$FILESET/$tdir" mount_client $submount &&
20915                 error "mount $submount should fail"
20916         rmdir $submount
20917 }
20918 run_test 247b "mount subdir that dose not exist"
20919
20920 test_247c() {
20921         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20922                 skip_env "Fileset feature is not supported"
20923
20924         local submount=${MOUNT}_$tdir
20925
20926         mkdir -p $MOUNT/$tdir/dir1
20927         mkdir -p $submount || error "mkdir $submount failed"
20928         trap "cleanup_247 $submount" EXIT
20929         FILESET="$FILESET/$tdir" mount_client $submount ||
20930                 error "mount $submount failed"
20931         local fid=$($LFS path2fid $MOUNT/)
20932         $LFS fid2path $submount $fid && error "fid2path should fail"
20933         cleanup_247 $submount
20934 }
20935 run_test 247c "running fid2path outside subdirectory root"
20936
20937 test_247d() {
20938         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20939                 skip "Fileset feature is not supported"
20940
20941         local submount=${MOUNT}_$tdir
20942
20943         mkdir -p $MOUNT/$tdir/dir1
20944         mkdir -p $submount || error "mkdir $submount failed"
20945         FILESET="$FILESET/$tdir" mount_client $submount ||
20946                 error "mount $submount failed"
20947         trap "cleanup_247 $submount" EXIT
20948
20949         local td=$submount/dir1
20950         local fid=$($LFS path2fid $td)
20951         [ -z "$fid" ] && error "path2fid unable to get $td FID"
20952
20953         # check that we get the same pathname back
20954         local rootpath
20955         local found
20956         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
20957                 echo "$rootpath $fid"
20958                 found=$($LFS fid2path $rootpath "$fid")
20959                 [ -n "found" ] || error "fid2path should succeed"
20960                 [ "$found" == "$td" ] || error "fid2path $found != $td"
20961         done
20962         # check wrong root path format
20963         rootpath=$submount"_wrong"
20964         found=$($LFS fid2path $rootpath "$fid")
20965         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
20966
20967         cleanup_247 $submount
20968 }
20969 run_test 247d "running fid2path inside subdirectory root"
20970
20971 # LU-8037
20972 test_247e() {
20973         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20974                 grep -q subtree ||
20975                 skip "Fileset feature is not supported"
20976
20977         local submount=${MOUNT}_$tdir
20978
20979         mkdir $MOUNT/$tdir
20980         mkdir -p $submount || error "mkdir $submount failed"
20981         FILESET="$FILESET/.." mount_client $submount &&
20982                 error "mount $submount should fail"
20983         rmdir $submount
20984 }
20985 run_test 247e "mount .. as fileset"
20986
20987 test_247f() {
20988         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20989         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20990                 skip "Need at least version 2.13.52"
20991         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20992                 skip "Need at least version 2.14.50"
20993         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20994                 grep -q subtree ||
20995                 skip "Fileset feature is not supported"
20996
20997         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20998         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
20999                 error "mkdir remote failed"
21000         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21001                 error "mkdir remote/subdir failed"
21002         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21003                 error "mkdir striped failed"
21004         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21005
21006         local submount=${MOUNT}_$tdir
21007
21008         mkdir -p $submount || error "mkdir $submount failed"
21009         stack_trap "rmdir $submount"
21010
21011         local dir
21012         local stat
21013         local fileset=$FILESET
21014         local mdts=$(comma_list $(mdts_nodes))
21015
21016         stat=$(do_facet mds1 $LCTL get_param -n \
21017                 mdt.*MDT0000.enable_remote_subdir_mount)
21018         stack_trap "do_nodes $mdts $LCTL set_param \
21019                 mdt.*.enable_remote_subdir_mount=$stat"
21020
21021         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21022         stack_trap "umount_client $submount"
21023         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21024                 error "mount remote dir $dir should fail"
21025
21026         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21027                 $tdir/striped/. ; do
21028                 FILESET="$fileset/$dir" mount_client $submount ||
21029                         error "mount $dir failed"
21030                 umount_client $submount
21031         done
21032
21033         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21034         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21035                 error "mount $tdir/remote failed"
21036 }
21037 run_test 247f "mount striped or remote directory as fileset"
21038
21039 test_247g() {
21040         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21041         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21042                 skip "Need at least version 2.14.50"
21043
21044         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21045                 error "mkdir $tdir failed"
21046         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21047
21048         local submount=${MOUNT}_$tdir
21049
21050         mkdir -p $submount || error "mkdir $submount failed"
21051         stack_trap "rmdir $submount"
21052
21053         FILESET="$fileset/$tdir" mount_client $submount ||
21054                 error "mount $dir failed"
21055         stack_trap "umount $submount"
21056
21057         local mdts=$(comma_list $(mdts_nodes))
21058
21059         local nrpcs
21060
21061         stat $submount > /dev/null
21062         cancel_lru_locks $MDC
21063         stat $submount > /dev/null
21064         stat $submount/$tfile > /dev/null
21065         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21066         stat $submount/$tfile > /dev/null
21067         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21068                 awk '/getattr/ {sum += $2} END {print sum}')
21069
21070         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21071 }
21072 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21073
21074 test_248a() {
21075         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21076         [ -z "$fast_read_sav" ] && skip "no fast read support"
21077
21078         # create a large file for fast read verification
21079         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21080
21081         # make sure the file is created correctly
21082         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21083                 { rm -f $DIR/$tfile; skip "file creation error"; }
21084
21085         echo "Test 1: verify that fast read is 4 times faster on cache read"
21086
21087         # small read with fast read enabled
21088         $LCTL set_param -n llite.*.fast_read=1
21089         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21090                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21091                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21092         # small read with fast read disabled
21093         $LCTL set_param -n llite.*.fast_read=0
21094         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21095                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21096                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21097
21098         # verify that fast read is 4 times faster for cache read
21099         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21100                 error_not_in_vm "fast read was not 4 times faster: " \
21101                            "$t_fast vs $t_slow"
21102
21103         echo "Test 2: verify the performance between big and small read"
21104         $LCTL set_param -n llite.*.fast_read=1
21105
21106         # 1k non-cache read
21107         cancel_lru_locks osc
21108         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21109                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21110                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21111
21112         # 1M non-cache read
21113         cancel_lru_locks osc
21114         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21115                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21116                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21117
21118         # verify that big IO is not 4 times faster than small IO
21119         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21120                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21121
21122         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21123         rm -f $DIR/$tfile
21124 }
21125 run_test 248a "fast read verification"
21126
21127 test_248b() {
21128         # Default short_io_bytes=16384, try both smaller and larger sizes.
21129         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21130         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21131         echo "bs=53248 count=113 normal buffered write"
21132         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21133                 error "dd of initial data file failed"
21134         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21135
21136         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21137         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21138                 error "dd with sync normal writes failed"
21139         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21140
21141         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21142         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21143                 error "dd with sync small writes failed"
21144         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21145
21146         cancel_lru_locks osc
21147
21148         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21149         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21150         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21151         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21152                 iflag=direct || error "dd with O_DIRECT small read failed"
21153         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21154         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21155                 error "compare $TMP/$tfile.1 failed"
21156
21157         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21158         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21159
21160         # just to see what the maximum tunable value is, and test parsing
21161         echo "test invalid parameter 2MB"
21162         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21163                 error "too-large short_io_bytes allowed"
21164         echo "test maximum parameter 512KB"
21165         # if we can set a larger short_io_bytes, run test regardless of version
21166         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21167                 # older clients may not allow setting it this large, that's OK
21168                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21169                         skip "Need at least client version 2.13.50"
21170                 error "medium short_io_bytes failed"
21171         fi
21172         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21173         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21174
21175         echo "test large parameter 64KB"
21176         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21177         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21178
21179         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21180         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21181                 error "dd with sync large writes failed"
21182         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21183
21184         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21185         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21186         num=$((113 * 4096 / PAGE_SIZE))
21187         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21188         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21189                 error "dd with O_DIRECT large writes failed"
21190         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21191                 error "compare $DIR/$tfile.3 failed"
21192
21193         cancel_lru_locks osc
21194
21195         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21196         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21197                 error "dd with O_DIRECT large read failed"
21198         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21199                 error "compare $TMP/$tfile.2 failed"
21200
21201         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21202         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21203                 error "dd with O_DIRECT large read failed"
21204         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21205                 error "compare $TMP/$tfile.3 failed"
21206 }
21207 run_test 248b "test short_io read and write for both small and large sizes"
21208
21209 test_249() { # LU-7890
21210         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21211                 skip "Need at least version 2.8.54"
21212
21213         rm -f $DIR/$tfile
21214         $LFS setstripe -c 1 $DIR/$tfile
21215         # Offset 2T == 4k * 512M
21216         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21217                 error "dd to 2T offset failed"
21218 }
21219 run_test 249 "Write above 2T file size"
21220
21221 test_250() {
21222         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21223          && skip "no 16TB file size limit on ZFS"
21224
21225         $LFS setstripe -c 1 $DIR/$tfile
21226         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21227         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21228         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21229         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21230                 conv=notrunc,fsync && error "append succeeded"
21231         return 0
21232 }
21233 run_test 250 "Write above 16T limit"
21234
21235 test_251() {
21236         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21237
21238         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21239         #Skip once - writing the first stripe will succeed
21240         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21241         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21242                 error "short write happened"
21243
21244         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21245         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21246                 error "short read happened"
21247
21248         rm -f $DIR/$tfile
21249 }
21250 run_test 251 "Handling short read and write correctly"
21251
21252 test_252() {
21253         remote_mds_nodsh && skip "remote MDS with nodsh"
21254         remote_ost_nodsh && skip "remote OST with nodsh"
21255         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21256                 skip_env "ldiskfs only test"
21257         fi
21258
21259         local tgt
21260         local dev
21261         local out
21262         local uuid
21263         local num
21264         local gen
21265
21266         # check lr_reader on OST0000
21267         tgt=ost1
21268         dev=$(facet_device $tgt)
21269         out=$(do_facet $tgt $LR_READER $dev)
21270         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21271         echo "$out"
21272         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21273         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21274                 error "Invalid uuid returned by $LR_READER on target $tgt"
21275         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21276
21277         # check lr_reader -c on MDT0000
21278         tgt=mds1
21279         dev=$(facet_device $tgt)
21280         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21281                 skip "$LR_READER does not support additional options"
21282         fi
21283         out=$(do_facet $tgt $LR_READER -c $dev)
21284         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21285         echo "$out"
21286         num=$(echo "$out" | grep -c "mdtlov")
21287         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21288                 error "Invalid number of mdtlov clients returned by $LR_READER"
21289         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21290
21291         # check lr_reader -cr on MDT0000
21292         out=$(do_facet $tgt $LR_READER -cr $dev)
21293         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21294         echo "$out"
21295         echo "$out" | grep -q "^reply_data:$" ||
21296                 error "$LR_READER should have returned 'reply_data' section"
21297         num=$(echo "$out" | grep -c "client_generation")
21298         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21299 }
21300 run_test 252 "check lr_reader tool"
21301
21302 test_253() {
21303         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21304         remote_mds_nodsh && skip "remote MDS with nodsh"
21305         remote_mgs_nodsh && skip "remote MGS with nodsh"
21306
21307         local ostidx=0
21308         local rc=0
21309         local ost_name=$(ostname_from_index $ostidx)
21310
21311         # on the mdt's osc
21312         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21313         do_facet $SINGLEMDS $LCTL get_param -n \
21314                 osp.$mdtosc_proc1.reserved_mb_high ||
21315                 skip  "remote MDS does not support reserved_mb_high"
21316
21317         rm -rf $DIR/$tdir
21318         wait_mds_ost_sync
21319         wait_delete_completed
21320         mkdir $DIR/$tdir
21321
21322         pool_add $TESTNAME || error "Pool creation failed"
21323         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21324
21325         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21326                 error "Setstripe failed"
21327
21328         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21329
21330         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21331                     grep "watermarks")
21332         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21333
21334         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21335                         osp.$mdtosc_proc1.prealloc_status)
21336         echo "prealloc_status $oa_status"
21337
21338         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21339                 error "File creation should fail"
21340
21341         #object allocation was stopped, but we still able to append files
21342         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21343                 oflag=append || error "Append failed"
21344
21345         rm -f $DIR/$tdir/$tfile.0
21346
21347         # For this test, we want to delete the files we created to go out of
21348         # space but leave the watermark, so we remain nearly out of space
21349         ost_watermarks_enospc_delete_files $tfile $ostidx
21350
21351         wait_delete_completed
21352
21353         sleep_maxage
21354
21355         for i in $(seq 10 12); do
21356                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21357                         2>/dev/null || error "File creation failed after rm"
21358         done
21359
21360         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21361                         osp.$mdtosc_proc1.prealloc_status)
21362         echo "prealloc_status $oa_status"
21363
21364         if (( oa_status != 0 )); then
21365                 error "Object allocation still disable after rm"
21366         fi
21367 }
21368 run_test 253 "Check object allocation limit"
21369
21370 test_254() {
21371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21372         remote_mds_nodsh && skip "remote MDS with nodsh"
21373
21374         local mdt=$(facet_svc $SINGLEMDS)
21375
21376         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21377                 skip "MDS does not support changelog_size"
21378
21379         local cl_user
21380
21381         changelog_register || error "changelog_register failed"
21382
21383         changelog_clear 0 || error "changelog_clear failed"
21384
21385         local size1=$(do_facet $SINGLEMDS \
21386                       $LCTL get_param -n mdd.$mdt.changelog_size)
21387         echo "Changelog size $size1"
21388
21389         rm -rf $DIR/$tdir
21390         $LFS mkdir -i 0 $DIR/$tdir
21391         # change something
21392         mkdir -p $DIR/$tdir/pics/2008/zachy
21393         touch $DIR/$tdir/pics/2008/zachy/timestamp
21394         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21395         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21396         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21397         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21398         rm $DIR/$tdir/pics/desktop.jpg
21399
21400         local size2=$(do_facet $SINGLEMDS \
21401                       $LCTL get_param -n mdd.$mdt.changelog_size)
21402         echo "Changelog size after work $size2"
21403
21404         (( $size2 > $size1 )) ||
21405                 error "new Changelog size=$size2 less than old size=$size1"
21406 }
21407 run_test 254 "Check changelog size"
21408
21409 ladvise_no_type()
21410 {
21411         local type=$1
21412         local file=$2
21413
21414         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21415                 awk -F: '{print $2}' | grep $type > /dev/null
21416         if [ $? -ne 0 ]; then
21417                 return 0
21418         fi
21419         return 1
21420 }
21421
21422 ladvise_no_ioctl()
21423 {
21424         local file=$1
21425
21426         lfs ladvise -a willread $file > /dev/null 2>&1
21427         if [ $? -eq 0 ]; then
21428                 return 1
21429         fi
21430
21431         lfs ladvise -a willread $file 2>&1 |
21432                 grep "Inappropriate ioctl for device" > /dev/null
21433         if [ $? -eq 0 ]; then
21434                 return 0
21435         fi
21436         return 1
21437 }
21438
21439 percent() {
21440         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21441 }
21442
21443 # run a random read IO workload
21444 # usage: random_read_iops <filename> <filesize> <iosize>
21445 random_read_iops() {
21446         local file=$1
21447         local fsize=$2
21448         local iosize=${3:-4096}
21449
21450         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21451                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21452 }
21453
21454 drop_file_oss_cache() {
21455         local file="$1"
21456         local nodes="$2"
21457
21458         $LFS ladvise -a dontneed $file 2>/dev/null ||
21459                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21460 }
21461
21462 ladvise_willread_performance()
21463 {
21464         local repeat=10
21465         local average_origin=0
21466         local average_cache=0
21467         local average_ladvise=0
21468
21469         for ((i = 1; i <= $repeat; i++)); do
21470                 echo "Iter $i/$repeat: reading without willread hint"
21471                 cancel_lru_locks osc
21472                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21473                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21474                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21475                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21476
21477                 cancel_lru_locks osc
21478                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21479                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21480                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21481
21482                 cancel_lru_locks osc
21483                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21484                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21485                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21486                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21487                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21488         done
21489         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21490         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21491         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21492
21493         speedup_cache=$(percent $average_cache $average_origin)
21494         speedup_ladvise=$(percent $average_ladvise $average_origin)
21495
21496         echo "Average uncached read: $average_origin"
21497         echo "Average speedup with OSS cached read: " \
21498                 "$average_cache = +$speedup_cache%"
21499         echo "Average speedup with ladvise willread: " \
21500                 "$average_ladvise = +$speedup_ladvise%"
21501
21502         local lowest_speedup=20
21503         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
21504                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
21505                         "got $average_cache%. Skipping ladvise willread check."
21506                 return 0
21507         fi
21508
21509         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21510         # it is still good to run until then to exercise 'ladvise willread'
21511         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21512                 [ "$ost1_FSTYPE" = "zfs" ] &&
21513                 echo "osd-zfs does not support dontneed or drop_caches" &&
21514                 return 0
21515
21516         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21517         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
21518                 error_not_in_vm "Speedup with willread is less than " \
21519                         "$lowest_speedup%, got $average_ladvise%"
21520 }
21521
21522 test_255a() {
21523         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21524                 skip "lustre < 2.8.54 does not support ladvise "
21525         remote_ost_nodsh && skip "remote OST with nodsh"
21526
21527         stack_trap "rm -f $DIR/$tfile"
21528         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21529
21530         ladvise_no_type willread $DIR/$tfile &&
21531                 skip "willread ladvise is not supported"
21532
21533         ladvise_no_ioctl $DIR/$tfile &&
21534                 skip "ladvise ioctl is not supported"
21535
21536         local size_mb=100
21537         local size=$((size_mb * 1048576))
21538         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21539                 error "dd to $DIR/$tfile failed"
21540
21541         lfs ladvise -a willread $DIR/$tfile ||
21542                 error "Ladvise failed with no range argument"
21543
21544         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21545                 error "Ladvise failed with no -l or -e argument"
21546
21547         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21548                 error "Ladvise failed with only -e argument"
21549
21550         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21551                 error "Ladvise failed with only -l argument"
21552
21553         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21554                 error "End offset should not be smaller than start offset"
21555
21556         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21557                 error "End offset should not be equal to start offset"
21558
21559         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21560                 error "Ladvise failed with overflowing -s argument"
21561
21562         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21563                 error "Ladvise failed with overflowing -e argument"
21564
21565         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21566                 error "Ladvise failed with overflowing -l argument"
21567
21568         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21569                 error "Ladvise succeeded with conflicting -l and -e arguments"
21570
21571         echo "Synchronous ladvise should wait"
21572         local delay=4
21573 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21574         do_nodes $(comma_list $(osts_nodes)) \
21575                 $LCTL set_param fail_val=$delay fail_loc=0x237
21576
21577         local start_ts=$SECONDS
21578         lfs ladvise -a willread $DIR/$tfile ||
21579                 error "Ladvise failed with no range argument"
21580         local end_ts=$SECONDS
21581         local inteval_ts=$((end_ts - start_ts))
21582
21583         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21584                 error "Synchronous advice didn't wait reply"
21585         fi
21586
21587         echo "Asynchronous ladvise shouldn't wait"
21588         local start_ts=$SECONDS
21589         lfs ladvise -a willread -b $DIR/$tfile ||
21590                 error "Ladvise failed with no range argument"
21591         local end_ts=$SECONDS
21592         local inteval_ts=$((end_ts - start_ts))
21593
21594         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21595                 error "Asynchronous advice blocked"
21596         fi
21597
21598         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21599         ladvise_willread_performance
21600 }
21601 run_test 255a "check 'lfs ladvise -a willread'"
21602
21603 facet_meminfo() {
21604         local facet=$1
21605         local info=$2
21606
21607         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21608 }
21609
21610 test_255b() {
21611         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21612                 skip "lustre < 2.8.54 does not support ladvise "
21613         remote_ost_nodsh && skip "remote OST with nodsh"
21614
21615         stack_trap "rm -f $DIR/$tfile"
21616         lfs setstripe -c 1 -i 0 $DIR/$tfile
21617
21618         ladvise_no_type dontneed $DIR/$tfile &&
21619                 skip "dontneed ladvise is not supported"
21620
21621         ladvise_no_ioctl $DIR/$tfile &&
21622                 skip "ladvise ioctl is not supported"
21623
21624         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21625                 [ "$ost1_FSTYPE" = "zfs" ] &&
21626                 skip "zfs-osd does not support 'ladvise dontneed'"
21627
21628         local size_mb=100
21629         local size=$((size_mb * 1048576))
21630         # In order to prevent disturbance of other processes, only check 3/4
21631         # of the memory usage
21632         local kibibytes=$((size_mb * 1024 * 3 / 4))
21633
21634         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21635                 error "dd to $DIR/$tfile failed"
21636
21637         #force write to complete before dropping OST cache & checking memory
21638         sync
21639
21640         local total=$(facet_meminfo ost1 MemTotal)
21641         echo "Total memory: $total KiB"
21642
21643         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21644         local before_read=$(facet_meminfo ost1 Cached)
21645         echo "Cache used before read: $before_read KiB"
21646
21647         lfs ladvise -a willread $DIR/$tfile ||
21648                 error "Ladvise willread failed"
21649         local after_read=$(facet_meminfo ost1 Cached)
21650         echo "Cache used after read: $after_read KiB"
21651
21652         lfs ladvise -a dontneed $DIR/$tfile ||
21653                 error "Ladvise dontneed again failed"
21654         local no_read=$(facet_meminfo ost1 Cached)
21655         echo "Cache used after dontneed ladvise: $no_read KiB"
21656
21657         if [ $total -lt $((before_read + kibibytes)) ]; then
21658                 echo "Memory is too small, abort checking"
21659                 return 0
21660         fi
21661
21662         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21663                 error "Ladvise willread should use more memory" \
21664                         "than $kibibytes KiB"
21665         fi
21666
21667         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21668                 error "Ladvise dontneed should release more memory" \
21669                         "than $kibibytes KiB"
21670         fi
21671 }
21672 run_test 255b "check 'lfs ladvise -a dontneed'"
21673
21674 test_255c() {
21675         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21676                 skip "lustre < 2.10.50 does not support lockahead"
21677
21678         local ost1_imp=$(get_osc_import_name client ost1)
21679         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21680                          cut -d'.' -f2)
21681         local count
21682         local new_count
21683         local difference
21684         local i
21685         local rc
21686
21687         test_mkdir -p $DIR/$tdir
21688         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21689
21690         #test 10 returns only success/failure
21691         i=10
21692         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21693         rc=$?
21694         if [ $rc -eq 255 ]; then
21695                 error "Ladvise test${i} failed, ${rc}"
21696         fi
21697
21698         #test 11 counts lock enqueue requests, all others count new locks
21699         i=11
21700         count=$(do_facet ost1 \
21701                 $LCTL get_param -n ost.OSS.ost.stats)
21702         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21703
21704         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21705         rc=$?
21706         if [ $rc -eq 255 ]; then
21707                 error "Ladvise test${i} failed, ${rc}"
21708         fi
21709
21710         new_count=$(do_facet ost1 \
21711                 $LCTL get_param -n ost.OSS.ost.stats)
21712         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21713                    awk '{ print $2 }')
21714
21715         difference="$((new_count - count))"
21716         if [ $difference -ne $rc ]; then
21717                 error "Ladvise test${i}, bad enqueue count, returned " \
21718                       "${rc}, actual ${difference}"
21719         fi
21720
21721         for i in $(seq 12 21); do
21722                 # If we do not do this, we run the risk of having too many
21723                 # locks and starting lock cancellation while we are checking
21724                 # lock counts.
21725                 cancel_lru_locks osc
21726
21727                 count=$($LCTL get_param -n \
21728                        ldlm.namespaces.$imp_name.lock_unused_count)
21729
21730                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21731                 rc=$?
21732                 if [ $rc -eq 255 ]; then
21733                         error "Ladvise test ${i} failed, ${rc}"
21734                 fi
21735
21736                 new_count=$($LCTL get_param -n \
21737                        ldlm.namespaces.$imp_name.lock_unused_count)
21738                 difference="$((new_count - count))"
21739
21740                 # Test 15 output is divided by 100 to map down to valid return
21741                 if [ $i -eq 15 ]; then
21742                         rc="$((rc * 100))"
21743                 fi
21744
21745                 if [ $difference -ne $rc ]; then
21746                         error "Ladvise test ${i}, bad lock count, returned " \
21747                               "${rc}, actual ${difference}"
21748                 fi
21749         done
21750
21751         #test 22 returns only success/failure
21752         i=22
21753         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21754         rc=$?
21755         if [ $rc -eq 255 ]; then
21756                 error "Ladvise test${i} failed, ${rc}"
21757         fi
21758 }
21759 run_test 255c "suite of ladvise lockahead tests"
21760
21761 test_256() {
21762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21763         remote_mds_nodsh && skip "remote MDS with nodsh"
21764         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21765         changelog_users $SINGLEMDS | grep "^cl" &&
21766                 skip "active changelog user"
21767
21768         local cl_user
21769         local cat_sl
21770         local mdt_dev
21771
21772         mdt_dev=$(mdsdevname 1)
21773         echo $mdt_dev
21774
21775         changelog_register || error "changelog_register failed"
21776
21777         rm -rf $DIR/$tdir
21778         mkdir_on_mdt0 $DIR/$tdir
21779
21780         changelog_clear 0 || error "changelog_clear failed"
21781
21782         # change something
21783         touch $DIR/$tdir/{1..10}
21784
21785         # stop the MDT
21786         stop $SINGLEMDS || error "Fail to stop MDT"
21787
21788         # remount the MDT
21789
21790         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
21791
21792         #after mount new plainllog is used
21793         touch $DIR/$tdir/{11..19}
21794         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21795         stack_trap "rm -f $tmpfile"
21796         cat_sl=$(do_facet $SINGLEMDS "sync; \
21797                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21798                  llog_reader $tmpfile | grep -c type=1064553b")
21799         do_facet $SINGLEMDS llog_reader $tmpfile
21800
21801         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21802
21803         changelog_clear 0 || error "changelog_clear failed"
21804
21805         cat_sl=$(do_facet $SINGLEMDS "sync; \
21806                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21807                  llog_reader $tmpfile | grep -c type=1064553b")
21808
21809         if (( cat_sl == 2 )); then
21810                 error "Empty plain llog was not deleted from changelog catalog"
21811         elif (( cat_sl != 1 )); then
21812                 error "Active plain llog shouldn't be deleted from catalog"
21813         fi
21814 }
21815 run_test 256 "Check llog delete for empty and not full state"
21816
21817 test_257() {
21818         remote_mds_nodsh && skip "remote MDS with nodsh"
21819         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21820                 skip "Need MDS version at least 2.8.55"
21821
21822         test_mkdir $DIR/$tdir
21823
21824         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21825                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21826         stat $DIR/$tdir
21827
21828 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21829         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21830         local facet=mds$((mdtidx + 1))
21831         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21832         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21833
21834         stop $facet || error "stop MDS failed"
21835         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21836                 error "start MDS fail"
21837         wait_recovery_complete $facet
21838 }
21839 run_test 257 "xattr locks are not lost"
21840
21841 # Verify we take the i_mutex when security requires it
21842 test_258a() {
21843 #define OBD_FAIL_IMUTEX_SEC 0x141c
21844         $LCTL set_param fail_loc=0x141c
21845         touch $DIR/$tfile
21846         chmod u+s $DIR/$tfile
21847         chmod a+rwx $DIR/$tfile
21848         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21849         RC=$?
21850         if [ $RC -ne 0 ]; then
21851                 error "error, failed to take i_mutex, rc=$?"
21852         fi
21853         rm -f $DIR/$tfile
21854 }
21855 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21856
21857 # Verify we do NOT take the i_mutex in the normal case
21858 test_258b() {
21859 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21860         $LCTL set_param fail_loc=0x141d
21861         touch $DIR/$tfile
21862         chmod a+rwx $DIR
21863         chmod a+rw $DIR/$tfile
21864         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21865         RC=$?
21866         if [ $RC -ne 0 ]; then
21867                 error "error, took i_mutex unnecessarily, rc=$?"
21868         fi
21869         rm -f $DIR/$tfile
21870
21871 }
21872 run_test 258b "verify i_mutex security behavior"
21873
21874 test_259() {
21875         local file=$DIR/$tfile
21876         local before
21877         local after
21878
21879         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21880
21881         stack_trap "rm -f $file" EXIT
21882
21883         wait_delete_completed
21884         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21885         echo "before: $before"
21886
21887         $LFS setstripe -i 0 -c 1 $file
21888         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21889         sync_all_data
21890         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21891         echo "after write: $after"
21892
21893 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
21894         do_facet ost1 $LCTL set_param fail_loc=0x2301
21895         $TRUNCATE $file 0
21896         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21897         echo "after truncate: $after"
21898
21899         stop ost1
21900         do_facet ost1 $LCTL set_param fail_loc=0
21901         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21902         sleep 2
21903         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21904         echo "after restart: $after"
21905         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
21906                 error "missing truncate?"
21907
21908         return 0
21909 }
21910 run_test 259 "crash at delayed truncate"
21911
21912 test_260() {
21913 #define OBD_FAIL_MDC_CLOSE               0x806
21914         $LCTL set_param fail_loc=0x80000806
21915         touch $DIR/$tfile
21916
21917 }
21918 run_test 260 "Check mdc_close fail"
21919
21920 ### Data-on-MDT sanity tests ###
21921 test_270a() {
21922         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21923                 skip "Need MDS version at least 2.10.55 for DoM"
21924
21925         # create DoM file
21926         local dom=$DIR/$tdir/dom_file
21927         local tmp=$DIR/$tdir/tmp_file
21928
21929         mkdir_on_mdt0 $DIR/$tdir
21930
21931         # basic checks for DoM component creation
21932         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
21933                 error "Can set MDT layout to non-first entry"
21934
21935         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
21936                 error "Can define multiple entries as MDT layout"
21937
21938         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
21939
21940         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
21941         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
21942         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
21943
21944         local mdtidx=$($LFS getstripe -m $dom)
21945         local mdtname=MDT$(printf %04x $mdtidx)
21946         local facet=mds$((mdtidx + 1))
21947         local space_check=1
21948
21949         # Skip free space checks with ZFS
21950         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
21951
21952         # write
21953         sync
21954         local size_tmp=$((65536 * 3))
21955         local mdtfree1=$(do_facet $facet \
21956                          lctl get_param -n osd*.*$mdtname.kbytesfree)
21957
21958         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21959         # check also direct IO along write
21960         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
21961         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21962         sync
21963         cmp $tmp $dom || error "file data is different"
21964         [ $(stat -c%s $dom) == $size_tmp ] ||
21965                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21966         if [ $space_check == 1 ]; then
21967                 local mdtfree2=$(do_facet $facet \
21968                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
21969
21970                 # increase in usage from by $size_tmp
21971                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21972                         error "MDT free space wrong after write: " \
21973                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21974         fi
21975
21976         # truncate
21977         local size_dom=10000
21978
21979         $TRUNCATE $dom $size_dom
21980         [ $(stat -c%s $dom) == $size_dom ] ||
21981                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
21982         if [ $space_check == 1 ]; then
21983                 mdtfree1=$(do_facet $facet \
21984                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21985                 # decrease in usage from $size_tmp to new $size_dom
21986                 [ $(($mdtfree1 - $mdtfree2)) -ge \
21987                   $(((size_tmp - size_dom) / 1024)) ] ||
21988                         error "MDT free space is wrong after truncate: " \
21989                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
21990         fi
21991
21992         # append
21993         cat $tmp >> $dom
21994         sync
21995         size_dom=$((size_dom + size_tmp))
21996         [ $(stat -c%s $dom) == $size_dom ] ||
21997                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
21998         if [ $space_check == 1 ]; then
21999                 mdtfree2=$(do_facet $facet \
22000                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22001                 # increase in usage by $size_tmp from previous
22002                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22003                         error "MDT free space is wrong after append: " \
22004                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22005         fi
22006
22007         # delete
22008         rm $dom
22009         if [ $space_check == 1 ]; then
22010                 mdtfree1=$(do_facet $facet \
22011                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22012                 # decrease in usage by $size_dom from previous
22013                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22014                         error "MDT free space is wrong after removal: " \
22015                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22016         fi
22017
22018         # combined striping
22019         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22020                 error "Can't create DoM + OST striping"
22021
22022         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22023         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22024         # check also direct IO along write
22025         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22026         sync
22027         cmp $tmp $dom || error "file data is different"
22028         [ $(stat -c%s $dom) == $size_tmp ] ||
22029                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22030         rm $dom $tmp
22031
22032         return 0
22033 }
22034 run_test 270a "DoM: basic functionality tests"
22035
22036 test_270b() {
22037         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22038                 skip "Need MDS version at least 2.10.55"
22039
22040         local dom=$DIR/$tdir/dom_file
22041         local max_size=1048576
22042
22043         mkdir -p $DIR/$tdir
22044         $LFS setstripe -E $max_size -L mdt $dom
22045
22046         # truncate over the limit
22047         $TRUNCATE $dom $(($max_size + 1)) &&
22048                 error "successful truncate over the maximum size"
22049         # write over the limit
22050         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22051                 error "successful write over the maximum size"
22052         # append over the limit
22053         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22054         echo "12345" >> $dom && error "successful append over the maximum size"
22055         rm $dom
22056
22057         return 0
22058 }
22059 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22060
22061 test_270c() {
22062         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22063                 skip "Need MDS version at least 2.10.55"
22064
22065         mkdir -p $DIR/$tdir
22066         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22067
22068         # check files inherit DoM EA
22069         touch $DIR/$tdir/first
22070         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22071                 error "bad pattern"
22072         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22073                 error "bad stripe count"
22074         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22075                 error "bad stripe size"
22076
22077         # check directory inherits DoM EA and uses it as default
22078         mkdir $DIR/$tdir/subdir
22079         touch $DIR/$tdir/subdir/second
22080         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22081                 error "bad pattern in sub-directory"
22082         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22083                 error "bad stripe count in sub-directory"
22084         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22085                 error "bad stripe size in sub-directory"
22086         return 0
22087 }
22088 run_test 270c "DoM: DoM EA inheritance tests"
22089
22090 test_270d() {
22091         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22092                 skip "Need MDS version at least 2.10.55"
22093
22094         mkdir -p $DIR/$tdir
22095         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22096
22097         # inherit default DoM striping
22098         mkdir $DIR/$tdir/subdir
22099         touch $DIR/$tdir/subdir/f1
22100
22101         # change default directory striping
22102         $LFS setstripe -c 1 $DIR/$tdir/subdir
22103         touch $DIR/$tdir/subdir/f2
22104         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22105                 error "wrong default striping in file 2"
22106         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22107                 error "bad pattern in file 2"
22108         return 0
22109 }
22110 run_test 270d "DoM: change striping from DoM to RAID0"
22111
22112 test_270e() {
22113         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22114                 skip "Need MDS version at least 2.10.55"
22115
22116         mkdir -p $DIR/$tdir/dom
22117         mkdir -p $DIR/$tdir/norm
22118         DOMFILES=20
22119         NORMFILES=10
22120         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22121         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22122
22123         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22124         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22125
22126         # find DoM files by layout
22127         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22128         [ $NUM -eq  $DOMFILES ] ||
22129                 error "lfs find -L: found $NUM, expected $DOMFILES"
22130         echo "Test 1: lfs find 20 DOM files by layout: OK"
22131
22132         # there should be 1 dir with default DOM striping
22133         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22134         [ $NUM -eq  1 ] ||
22135                 error "lfs find -L: found $NUM, expected 1 dir"
22136         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22137
22138         # find DoM files by stripe size
22139         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22140         [ $NUM -eq  $DOMFILES ] ||
22141                 error "lfs find -S: found $NUM, expected $DOMFILES"
22142         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22143
22144         # find files by stripe offset except DoM files
22145         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22146         [ $NUM -eq  $NORMFILES ] ||
22147                 error "lfs find -i: found $NUM, expected $NORMFILES"
22148         echo "Test 5: lfs find no DOM files by stripe index: OK"
22149         return 0
22150 }
22151 run_test 270e "DoM: lfs find with DoM files test"
22152
22153 test_270f() {
22154         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22155                 skip "Need MDS version at least 2.10.55"
22156
22157         local mdtname=${FSNAME}-MDT0000-mdtlov
22158         local dom=$DIR/$tdir/dom_file
22159         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22160                                                 lod.$mdtname.dom_stripesize)
22161         local dom_limit=131072
22162
22163         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22164         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22165                                                 lod.$mdtname.dom_stripesize)
22166         [ ${dom_limit} -eq ${dom_current} ] ||
22167                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22168
22169         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22170         $LFS setstripe -d $DIR/$tdir
22171         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22172                 error "Can't set directory default striping"
22173
22174         # exceed maximum stripe size
22175         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22176                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22177         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22178                 error "Able to create DoM component size more than LOD limit"
22179
22180         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22181         dom_current=$(do_facet mds1 $LCTL get_param -n \
22182                                                 lod.$mdtname.dom_stripesize)
22183         [ 0 -eq ${dom_current} ] ||
22184                 error "Can't set zero DoM stripe limit"
22185         rm $dom
22186
22187         # attempt to create DoM file on server with disabled DoM should
22188         # remove DoM entry from layout and be succeed
22189         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22190                 error "Can't create DoM file (DoM is disabled)"
22191         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22192                 error "File has DoM component while DoM is disabled"
22193         rm $dom
22194
22195         # attempt to create DoM file with only DoM stripe should return error
22196         $LFS setstripe -E $dom_limit -L mdt $dom &&
22197                 error "Able to create DoM-only file while DoM is disabled"
22198
22199         # too low values to be aligned with smallest stripe size 64K
22200         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22201         dom_current=$(do_facet mds1 $LCTL get_param -n \
22202                                                 lod.$mdtname.dom_stripesize)
22203         [ 30000 -eq ${dom_current} ] &&
22204                 error "Can set too small DoM stripe limit"
22205
22206         # 64K is a minimal stripe size in Lustre, expect limit of that size
22207         [ 65536 -eq ${dom_current} ] ||
22208                 error "Limit is not set to 64K but ${dom_current}"
22209
22210         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22211         dom_current=$(do_facet mds1 $LCTL get_param -n \
22212                                                 lod.$mdtname.dom_stripesize)
22213         echo $dom_current
22214         [ 2147483648 -eq ${dom_current} ] &&
22215                 error "Can set too large DoM stripe limit"
22216
22217         do_facet mds1 $LCTL set_param -n \
22218                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22219         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22220                 error "Can't create DoM component size after limit change"
22221         do_facet mds1 $LCTL set_param -n \
22222                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22223         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22224                 error "Can't create DoM file after limit decrease"
22225         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22226                 error "Can create big DoM component after limit decrease"
22227         touch ${dom}_def ||
22228                 error "Can't create file with old default layout"
22229
22230         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22231         return 0
22232 }
22233 run_test 270f "DoM: maximum DoM stripe size checks"
22234
22235 test_270g() {
22236         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22237                 skip "Need MDS version at least 2.13.52"
22238         local dom=$DIR/$tdir/$tfile
22239
22240         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22241         local lodname=${FSNAME}-MDT0000-mdtlov
22242
22243         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22244         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22245         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22246         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22247
22248         local dom_limit=1024
22249         local dom_threshold="50%"
22250
22251         $LFS setstripe -d $DIR/$tdir
22252         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22253                 error "Can't set directory default striping"
22254
22255         do_facet mds1 $LCTL set_param -n \
22256                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22257         # set 0 threshold and create DOM file to change tunable stripesize
22258         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22259         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22260                 error "Failed to create $dom file"
22261         # now tunable dom_cur_stripesize should reach maximum
22262         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22263                                         lod.${lodname}.dom_stripesize_cur_kb)
22264         [[ $dom_current == $dom_limit ]] ||
22265                 error "Current DOM stripesize is not maximum"
22266         rm $dom
22267
22268         # set threshold for further tests
22269         do_facet mds1 $LCTL set_param -n \
22270                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22271         echo "DOM threshold is $dom_threshold free space"
22272         local dom_def
22273         local dom_set
22274         # Spoof bfree to exceed threshold
22275         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22276         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22277         for spfree in 40 20 0 15 30 55; do
22278                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22279                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22280                         error "Failed to create $dom file"
22281                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22282                                         lod.${lodname}.dom_stripesize_cur_kb)
22283                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22284                 [[ $dom_def != $dom_current ]] ||
22285                         error "Default stripe size was not changed"
22286                 if [[ $spfree > 0 ]] ; then
22287                         dom_set=$($LFS getstripe -S $dom)
22288                         [[ $dom_set == $((dom_def * 1024)) ]] ||
22289                                 error "DOM component size is still old"
22290                 else
22291                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22292                                 error "DoM component is set with no free space"
22293                 fi
22294                 rm $dom
22295                 dom_current=$dom_def
22296         done
22297 }
22298 run_test 270g "DoM: default DoM stripe size depends on free space"
22299
22300 test_270h() {
22301         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22302                 skip "Need MDS version at least 2.13.53"
22303
22304         local mdtname=${FSNAME}-MDT0000-mdtlov
22305         local dom=$DIR/$tdir/$tfile
22306         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22307
22308         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22309         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22310
22311         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22312         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22313                 error "can't create OST file"
22314         # mirrored file with DOM entry in the second mirror
22315         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22316                 error "can't create mirror with DoM component"
22317
22318         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22319
22320         # DOM component in the middle and has other enries in the same mirror,
22321         # should succeed but lost DoM component
22322         $LFS setstripe --copy=${dom}_1 $dom ||
22323                 error "Can't create file from OST|DOM mirror layout"
22324         # check new file has no DoM layout after all
22325         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22326                 error "File has DoM component while DoM is disabled"
22327 }
22328 run_test 270h "DoM: DoM stripe removal when disabled on server"
22329
22330 test_270i() {
22331         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22332                 skip "Need MDS version at least 2.14.54"
22333
22334         mkdir $DIR/$tdir
22335         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22336                 error "setstripe should fail" || true
22337 }
22338 run_test 270i "DoM: setting invalid DoM striping should fail"
22339
22340 test_271a() {
22341         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22342                 skip "Need MDS version at least 2.10.55"
22343
22344         local dom=$DIR/$tdir/dom
22345
22346         mkdir -p $DIR/$tdir
22347
22348         $LFS setstripe -E 1024K -L mdt $dom
22349
22350         lctl set_param -n mdc.*.stats=clear
22351         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22352         cat $dom > /dev/null
22353         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22354         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22355         ls $dom
22356         rm -f $dom
22357 }
22358 run_test 271a "DoM: data is cached for read after write"
22359
22360 test_271b() {
22361         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22362                 skip "Need MDS version at least 2.10.55"
22363
22364         local dom=$DIR/$tdir/dom
22365
22366         mkdir -p $DIR/$tdir
22367
22368         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22369
22370         lctl set_param -n mdc.*.stats=clear
22371         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22372         cancel_lru_locks mdc
22373         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22374         # second stat to check size is cached on client
22375         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22376         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22377         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22378         rm -f $dom
22379 }
22380 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22381
22382 test_271ba() {
22383         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22384                 skip "Need MDS version at least 2.10.55"
22385
22386         local dom=$DIR/$tdir/dom
22387
22388         mkdir -p $DIR/$tdir
22389
22390         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22391
22392         lctl set_param -n mdc.*.stats=clear
22393         lctl set_param -n osc.*.stats=clear
22394         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22395         cancel_lru_locks mdc
22396         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22397         # second stat to check size is cached on client
22398         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22399         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22400         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22401         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22402         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22403         rm -f $dom
22404 }
22405 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22406
22407
22408 get_mdc_stats() {
22409         local mdtidx=$1
22410         local param=$2
22411         local mdt=MDT$(printf %04x $mdtidx)
22412
22413         if [ -z $param ]; then
22414                 lctl get_param -n mdc.*$mdt*.stats
22415         else
22416                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22417         fi
22418 }
22419
22420 test_271c() {
22421         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22422                 skip "Need MDS version at least 2.10.55"
22423
22424         local dom=$DIR/$tdir/dom
22425
22426         mkdir -p $DIR/$tdir
22427
22428         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22429
22430         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22431         local facet=mds$((mdtidx + 1))
22432
22433         cancel_lru_locks mdc
22434         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22435         createmany -o $dom 1000
22436         lctl set_param -n mdc.*.stats=clear
22437         smalliomany -w $dom 1000 200
22438         get_mdc_stats $mdtidx
22439         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22440         # Each file has 1 open, 1 IO enqueues, total 2000
22441         # but now we have also +1 getxattr for security.capability, total 3000
22442         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22443         unlinkmany $dom 1000
22444
22445         cancel_lru_locks mdc
22446         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22447         createmany -o $dom 1000
22448         lctl set_param -n mdc.*.stats=clear
22449         smalliomany -w $dom 1000 200
22450         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22451         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22452         # for OPEN and IO lock.
22453         [ $((enq - enq_2)) -ge 1000 ] ||
22454                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22455         unlinkmany $dom 1000
22456         return 0
22457 }
22458 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22459
22460 cleanup_271def_tests() {
22461         trap 0
22462         rm -f $1
22463 }
22464
22465 test_271d() {
22466         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22467                 skip "Need MDS version at least 2.10.57"
22468
22469         local dom=$DIR/$tdir/dom
22470         local tmp=$TMP/$tfile
22471         trap "cleanup_271def_tests $tmp" EXIT
22472
22473         mkdir -p $DIR/$tdir
22474
22475         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22476
22477         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22478
22479         cancel_lru_locks mdc
22480         dd if=/dev/urandom of=$tmp bs=1000 count=1
22481         dd if=$tmp of=$dom bs=1000 count=1
22482         cancel_lru_locks mdc
22483
22484         cat /etc/hosts >> $tmp
22485         lctl set_param -n mdc.*.stats=clear
22486
22487         # append data to the same file it should update local page
22488         echo "Append to the same page"
22489         cat /etc/hosts >> $dom
22490         local num=$(get_mdc_stats $mdtidx ost_read)
22491         local ra=$(get_mdc_stats $mdtidx req_active)
22492         local rw=$(get_mdc_stats $mdtidx req_waittime)
22493
22494         [ -z $num ] || error "$num READ RPC occured"
22495         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22496         echo "... DONE"
22497
22498         # compare content
22499         cmp $tmp $dom || error "file miscompare"
22500
22501         cancel_lru_locks mdc
22502         lctl set_param -n mdc.*.stats=clear
22503
22504         echo "Open and read file"
22505         cat $dom > /dev/null
22506         local num=$(get_mdc_stats $mdtidx ost_read)
22507         local ra=$(get_mdc_stats $mdtidx req_active)
22508         local rw=$(get_mdc_stats $mdtidx req_waittime)
22509
22510         [ -z $num ] || error "$num READ RPC occured"
22511         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22512         echo "... DONE"
22513
22514         # compare content
22515         cmp $tmp $dom || error "file miscompare"
22516
22517         return 0
22518 }
22519 run_test 271d "DoM: read on open (1K file in reply buffer)"
22520
22521 test_271f() {
22522         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22523                 skip "Need MDS version at least 2.10.57"
22524
22525         local dom=$DIR/$tdir/dom
22526         local tmp=$TMP/$tfile
22527         trap "cleanup_271def_tests $tmp" EXIT
22528
22529         mkdir -p $DIR/$tdir
22530
22531         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22532
22533         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22534
22535         cancel_lru_locks mdc
22536         dd if=/dev/urandom of=$tmp bs=265000 count=1
22537         dd if=$tmp of=$dom bs=265000 count=1
22538         cancel_lru_locks mdc
22539         cat /etc/hosts >> $tmp
22540         lctl set_param -n mdc.*.stats=clear
22541
22542         echo "Append to the same page"
22543         cat /etc/hosts >> $dom
22544         local num=$(get_mdc_stats $mdtidx ost_read)
22545         local ra=$(get_mdc_stats $mdtidx req_active)
22546         local rw=$(get_mdc_stats $mdtidx req_waittime)
22547
22548         [ -z $num ] || error "$num READ RPC occured"
22549         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22550         echo "... DONE"
22551
22552         # compare content
22553         cmp $tmp $dom || error "file miscompare"
22554
22555         cancel_lru_locks mdc
22556         lctl set_param -n mdc.*.stats=clear
22557
22558         echo "Open and read file"
22559         cat $dom > /dev/null
22560         local num=$(get_mdc_stats $mdtidx ost_read)
22561         local ra=$(get_mdc_stats $mdtidx req_active)
22562         local rw=$(get_mdc_stats $mdtidx req_waittime)
22563
22564         [ -z $num ] && num=0
22565         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22566         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22567         echo "... DONE"
22568
22569         # compare content
22570         cmp $tmp $dom || error "file miscompare"
22571
22572         return 0
22573 }
22574 run_test 271f "DoM: read on open (200K file and read tail)"
22575
22576 test_271g() {
22577         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22578                 skip "Skipping due to old client or server version"
22579
22580         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22581         # to get layout
22582         $CHECKSTAT -t file $DIR1/$tfile
22583
22584         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22585         MULTIOP_PID=$!
22586         sleep 1
22587         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22588         $LCTL set_param fail_loc=0x80000314
22589         rm $DIR1/$tfile || error "Unlink fails"
22590         RC=$?
22591         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22592         [ $RC -eq 0 ] || error "Failed write to stale object"
22593 }
22594 run_test 271g "Discard DoM data vs client flush race"
22595
22596 test_272a() {
22597         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22598                 skip "Need MDS version at least 2.11.50"
22599
22600         local dom=$DIR/$tdir/dom
22601         mkdir -p $DIR/$tdir
22602
22603         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22604         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22605                 error "failed to write data into $dom"
22606         local old_md5=$(md5sum $dom)
22607
22608         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22609                 error "failed to migrate to the same DoM component"
22610
22611         local new_md5=$(md5sum $dom)
22612
22613         [ "$old_md5" == "$new_md5" ] ||
22614                 error "md5sum differ: $old_md5, $new_md5"
22615
22616         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22617                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22618 }
22619 run_test 272a "DoM migration: new layout with the same DOM component"
22620
22621 test_272b() {
22622         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22623                 skip "Need MDS version at least 2.11.50"
22624
22625         local dom=$DIR/$tdir/dom
22626         mkdir -p $DIR/$tdir
22627         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22628
22629         local mdtidx=$($LFS getstripe -m $dom)
22630         local mdtname=MDT$(printf %04x $mdtidx)
22631         local facet=mds$((mdtidx + 1))
22632
22633         local mdtfree1=$(do_facet $facet \
22634                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22635         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22636                 error "failed to write data into $dom"
22637         local old_md5=$(md5sum $dom)
22638         cancel_lru_locks mdc
22639         local mdtfree1=$(do_facet $facet \
22640                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22641
22642         $LFS migrate -c2 $dom ||
22643                 error "failed to migrate to the new composite layout"
22644         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22645                 error "MDT stripe was not removed"
22646
22647         cancel_lru_locks mdc
22648         local new_md5=$(md5sum $dom)
22649         [ "$old_md5" == "$new_md5" ] ||
22650                 error "$old_md5 != $new_md5"
22651
22652         # Skip free space checks with ZFS
22653         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22654                 local mdtfree2=$(do_facet $facet \
22655                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22656                 [ $mdtfree2 -gt $mdtfree1 ] ||
22657                         error "MDT space is not freed after migration"
22658         fi
22659         return 0
22660 }
22661 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22662
22663 test_272c() {
22664         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22665                 skip "Need MDS version at least 2.11.50"
22666
22667         local dom=$DIR/$tdir/$tfile
22668         mkdir -p $DIR/$tdir
22669         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22670
22671         local mdtidx=$($LFS getstripe -m $dom)
22672         local mdtname=MDT$(printf %04x $mdtidx)
22673         local facet=mds$((mdtidx + 1))
22674
22675         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22676                 error "failed to write data into $dom"
22677         local old_md5=$(md5sum $dom)
22678         cancel_lru_locks mdc
22679         local mdtfree1=$(do_facet $facet \
22680                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22681
22682         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22683                 error "failed to migrate to the new composite layout"
22684         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22685                 error "MDT stripe was not removed"
22686
22687         cancel_lru_locks mdc
22688         local new_md5=$(md5sum $dom)
22689         [ "$old_md5" == "$new_md5" ] ||
22690                 error "$old_md5 != $new_md5"
22691
22692         # Skip free space checks with ZFS
22693         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22694                 local mdtfree2=$(do_facet $facet \
22695                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22696                 [ $mdtfree2 -gt $mdtfree1 ] ||
22697                         error "MDS space is not freed after migration"
22698         fi
22699         return 0
22700 }
22701 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22702
22703 test_272d() {
22704         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22705                 skip "Need MDS version at least 2.12.55"
22706
22707         local dom=$DIR/$tdir/$tfile
22708         mkdir -p $DIR/$tdir
22709         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22710
22711         local mdtidx=$($LFS getstripe -m $dom)
22712         local mdtname=MDT$(printf %04x $mdtidx)
22713         local facet=mds$((mdtidx + 1))
22714
22715         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22716                 error "failed to write data into $dom"
22717         local old_md5=$(md5sum $dom)
22718         cancel_lru_locks mdc
22719         local mdtfree1=$(do_facet $facet \
22720                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22721
22722         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22723                 error "failed mirroring to the new composite layout"
22724         $LFS mirror resync $dom ||
22725                 error "failed mirror resync"
22726         $LFS mirror split --mirror-id 1 -d $dom ||
22727                 error "failed mirror split"
22728
22729         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22730                 error "MDT stripe was not removed"
22731
22732         cancel_lru_locks mdc
22733         local new_md5=$(md5sum $dom)
22734         [ "$old_md5" == "$new_md5" ] ||
22735                 error "$old_md5 != $new_md5"
22736
22737         # Skip free space checks with ZFS
22738         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22739                 local mdtfree2=$(do_facet $facet \
22740                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22741                 [ $mdtfree2 -gt $mdtfree1 ] ||
22742                         error "MDS space is not freed after DOM mirror deletion"
22743         fi
22744         return 0
22745 }
22746 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22747
22748 test_272e() {
22749         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22750                 skip "Need MDS version at least 2.12.55"
22751
22752         local dom=$DIR/$tdir/$tfile
22753         mkdir -p $DIR/$tdir
22754         $LFS setstripe -c 2 $dom
22755
22756         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22757                 error "failed to write data into $dom"
22758         local old_md5=$(md5sum $dom)
22759         cancel_lru_locks
22760
22761         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22762                 error "failed mirroring to the DOM layout"
22763         $LFS mirror resync $dom ||
22764                 error "failed mirror resync"
22765         $LFS mirror split --mirror-id 1 -d $dom ||
22766                 error "failed mirror split"
22767
22768         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22769                 error "MDT stripe wasn't set"
22770
22771         cancel_lru_locks
22772         local new_md5=$(md5sum $dom)
22773         [ "$old_md5" == "$new_md5" ] ||
22774                 error "$old_md5 != $new_md5"
22775
22776         return 0
22777 }
22778 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22779
22780 test_272f() {
22781         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22782                 skip "Need MDS version at least 2.12.55"
22783
22784         local dom=$DIR/$tdir/$tfile
22785         mkdir -p $DIR/$tdir
22786         $LFS setstripe -c 2 $dom
22787
22788         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22789                 error "failed to write data into $dom"
22790         local old_md5=$(md5sum $dom)
22791         cancel_lru_locks
22792
22793         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22794                 error "failed migrating to the DOM file"
22795
22796         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22797                 error "MDT stripe wasn't set"
22798
22799         cancel_lru_locks
22800         local new_md5=$(md5sum $dom)
22801         [ "$old_md5" != "$new_md5" ] &&
22802                 error "$old_md5 != $new_md5"
22803
22804         return 0
22805 }
22806 run_test 272f "DoM migration: OST-striped file to DOM file"
22807
22808 test_273a() {
22809         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22810                 skip "Need MDS version at least 2.11.50"
22811
22812         # Layout swap cannot be done if either file has DOM component,
22813         # this will never be supported, migration should be used instead
22814
22815         local dom=$DIR/$tdir/$tfile
22816         mkdir -p $DIR/$tdir
22817
22818         $LFS setstripe -c2 ${dom}_plain
22819         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22820         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22821                 error "can swap layout with DoM component"
22822         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22823                 error "can swap layout with DoM component"
22824
22825         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22826         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22827                 error "can swap layout with DoM component"
22828         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22829                 error "can swap layout with DoM component"
22830         return 0
22831 }
22832 run_test 273a "DoM: layout swapping should fail with DOM"
22833
22834 test_273b() {
22835         mkdir -p $DIR/$tdir
22836         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22837
22838 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22839         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22840
22841         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22842 }
22843 run_test 273b "DoM: race writeback and object destroy"
22844
22845 test_275() {
22846         remote_ost_nodsh && skip "remote OST with nodsh"
22847         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22848                 skip "Need OST version >= 2.10.57"
22849
22850         local file=$DIR/$tfile
22851         local oss
22852
22853         oss=$(comma_list $(osts_nodes))
22854
22855         dd if=/dev/urandom of=$file bs=1M count=2 ||
22856                 error "failed to create a file"
22857         cancel_lru_locks osc
22858
22859         #lock 1
22860         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22861                 error "failed to read a file"
22862
22863 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22864         $LCTL set_param fail_loc=0x8000031f
22865
22866         cancel_lru_locks osc &
22867         sleep 1
22868
22869 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22870         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22871         #IO takes another lock, but matches the PENDING one
22872         #and places it to the IO RPC
22873         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22874                 error "failed to read a file with PENDING lock"
22875 }
22876 run_test 275 "Read on a canceled duplicate lock"
22877
22878 test_276() {
22879         remote_ost_nodsh && skip "remote OST with nodsh"
22880         local pid
22881
22882         do_facet ost1 "(while true; do \
22883                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22884                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22885         pid=$!
22886
22887         for LOOP in $(seq 20); do
22888                 stop ost1
22889                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22890         done
22891         kill -9 $pid
22892         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
22893                 rm $TMP/sanity_276_pid"
22894 }
22895 run_test 276 "Race between mount and obd_statfs"
22896
22897 test_277() {
22898         $LCTL set_param ldlm.namespaces.*.lru_size=0
22899         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22900         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22901                         grep ^used_mb | awk '{print $2}')
22902         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
22903         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
22904                 oflag=direct conv=notrunc
22905         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22906                         grep ^used_mb | awk '{print $2}')
22907         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
22908 }
22909 run_test 277 "Direct IO shall drop page cache"
22910
22911 test_278() {
22912         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22913         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22914         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
22915                 skip "needs the same host for mdt1 mdt2" && return
22916
22917         local pid1
22918         local pid2
22919
22920 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22921         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22922         stop mds2 &
22923         pid2=$!
22924
22925         stop mds1
22926
22927         echo "Starting MDTs"
22928         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22929         wait $pid2
22930 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
22931 #will return NULL
22932         do_facet mds2 $LCTL set_param fail_loc=0
22933
22934         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
22935         wait_recovery_complete mds2
22936 }
22937 run_test 278 "Race starting MDS between MDTs stop/start"
22938
22939 test_280() {
22940         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
22941                 skip "Need MGS version at least 2.13.52"
22942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22943         combined_mgs_mds || skip "needs combined MGS/MDT"
22944
22945         umount_client $MOUNT
22946 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
22947         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
22948
22949         mount_client $MOUNT &
22950         sleep 1
22951         stop mgs || error "stop mgs failed"
22952         #for a race mgs would crash
22953         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
22954         # make sure we unmount client before remounting
22955         wait
22956         umount_client $MOUNT
22957         mount_client $MOUNT || error "mount client failed"
22958 }
22959 run_test 280 "Race between MGS umount and client llog processing"
22960
22961 cleanup_test_300() {
22962         trap 0
22963         umask $SAVE_UMASK
22964 }
22965 test_striped_dir() {
22966         local mdt_index=$1
22967         local stripe_count
22968         local stripe_index
22969
22970         mkdir -p $DIR/$tdir
22971
22972         SAVE_UMASK=$(umask)
22973         trap cleanup_test_300 RETURN EXIT
22974
22975         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
22976                                                 $DIR/$tdir/striped_dir ||
22977                 error "set striped dir error"
22978
22979         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
22980         [ "$mode" = "755" ] || error "expect 755 got $mode"
22981
22982         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
22983                 error "getdirstripe failed"
22984         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
22985         if [ "$stripe_count" != "2" ]; then
22986                 error "1:stripe_count is $stripe_count, expect 2"
22987         fi
22988         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
22989         if [ "$stripe_count" != "2" ]; then
22990                 error "2:stripe_count is $stripe_count, expect 2"
22991         fi
22992
22993         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
22994         if [ "$stripe_index" != "$mdt_index" ]; then
22995                 error "stripe_index is $stripe_index, expect $mdt_index"
22996         fi
22997
22998         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22999                 error "nlink error after create striped dir"
23000
23001         mkdir $DIR/$tdir/striped_dir/a
23002         mkdir $DIR/$tdir/striped_dir/b
23003
23004         stat $DIR/$tdir/striped_dir/a ||
23005                 error "create dir under striped dir failed"
23006         stat $DIR/$tdir/striped_dir/b ||
23007                 error "create dir under striped dir failed"
23008
23009         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23010                 error "nlink error after mkdir"
23011
23012         rmdir $DIR/$tdir/striped_dir/a
23013         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23014                 error "nlink error after rmdir"
23015
23016         rmdir $DIR/$tdir/striped_dir/b
23017         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23018                 error "nlink error after rmdir"
23019
23020         chattr +i $DIR/$tdir/striped_dir
23021         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23022                 error "immutable flags not working under striped dir!"
23023         chattr -i $DIR/$tdir/striped_dir
23024
23025         rmdir $DIR/$tdir/striped_dir ||
23026                 error "rmdir striped dir error"
23027
23028         cleanup_test_300
23029
23030         true
23031 }
23032
23033 test_300a() {
23034         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23035                 skip "skipped for lustre < 2.7.0"
23036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23037         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23038
23039         test_striped_dir 0 || error "failed on striped dir on MDT0"
23040         test_striped_dir 1 || error "failed on striped dir on MDT0"
23041 }
23042 run_test 300a "basic striped dir sanity test"
23043
23044 test_300b() {
23045         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23046                 skip "skipped for lustre < 2.7.0"
23047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23048         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23049
23050         local i
23051         local mtime1
23052         local mtime2
23053         local mtime3
23054
23055         test_mkdir $DIR/$tdir || error "mkdir fail"
23056         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23057                 error "set striped dir error"
23058         for i in {0..9}; do
23059                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23060                 sleep 1
23061                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23062                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23063                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23064                 sleep 1
23065                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23066                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23067                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23068         done
23069         true
23070 }
23071 run_test 300b "check ctime/mtime for striped dir"
23072
23073 test_300c() {
23074         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23075                 skip "skipped for lustre < 2.7.0"
23076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23077         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23078
23079         local file_count
23080
23081         mkdir_on_mdt0 $DIR/$tdir
23082         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23083                 error "set striped dir error"
23084
23085         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23086                 error "chown striped dir failed"
23087
23088         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23089                 error "create 5k files failed"
23090
23091         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23092
23093         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23094
23095         rm -rf $DIR/$tdir
23096 }
23097 run_test 300c "chown && check ls under striped directory"
23098
23099 test_300d() {
23100         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23101                 skip "skipped for lustre < 2.7.0"
23102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23103         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23104
23105         local stripe_count
23106         local file
23107
23108         mkdir -p $DIR/$tdir
23109         $LFS setstripe -c 2 $DIR/$tdir
23110
23111         #local striped directory
23112         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23113                 error "set striped dir error"
23114         #look at the directories for debug purposes
23115         ls -l $DIR/$tdir
23116         $LFS getdirstripe $DIR/$tdir
23117         ls -l $DIR/$tdir/striped_dir
23118         $LFS getdirstripe $DIR/$tdir/striped_dir
23119         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23120                 error "create 10 files failed"
23121
23122         #remote striped directory
23123         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23124                 error "set striped dir error"
23125         #look at the directories for debug purposes
23126         ls -l $DIR/$tdir
23127         $LFS getdirstripe $DIR/$tdir
23128         ls -l $DIR/$tdir/remote_striped_dir
23129         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23130         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23131                 error "create 10 files failed"
23132
23133         for file in $(find $DIR/$tdir); do
23134                 stripe_count=$($LFS getstripe -c $file)
23135                 [ $stripe_count -eq 2 ] ||
23136                         error "wrong stripe $stripe_count for $file"
23137         done
23138
23139         rm -rf $DIR/$tdir
23140 }
23141 run_test 300d "check default stripe under striped directory"
23142
23143 test_300e() {
23144         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23145                 skip "Need MDS version at least 2.7.55"
23146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23147         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23148
23149         local stripe_count
23150         local file
23151
23152         mkdir -p $DIR/$tdir
23153
23154         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23155                 error "set striped dir error"
23156
23157         touch $DIR/$tdir/striped_dir/a
23158         touch $DIR/$tdir/striped_dir/b
23159         touch $DIR/$tdir/striped_dir/c
23160
23161         mkdir $DIR/$tdir/striped_dir/dir_a
23162         mkdir $DIR/$tdir/striped_dir/dir_b
23163         mkdir $DIR/$tdir/striped_dir/dir_c
23164
23165         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23166                 error "set striped adir under striped dir error"
23167
23168         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23169                 error "set striped bdir under striped dir error"
23170
23171         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23172                 error "set striped cdir under striped dir error"
23173
23174         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23175                 error "rename dir under striped dir fails"
23176
23177         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23178                 error "rename dir under different stripes fails"
23179
23180         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23181                 error "rename file under striped dir should succeed"
23182
23183         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23184                 error "rename dir under striped dir should succeed"
23185
23186         rm -rf $DIR/$tdir
23187 }
23188 run_test 300e "check rename under striped directory"
23189
23190 test_300f() {
23191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23192         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23193         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23194                 skip "Need MDS version at least 2.7.55"
23195
23196         local stripe_count
23197         local file
23198
23199         rm -rf $DIR/$tdir
23200         mkdir -p $DIR/$tdir
23201
23202         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23203                 error "set striped dir error"
23204
23205         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23206                 error "set striped dir error"
23207
23208         touch $DIR/$tdir/striped_dir/a
23209         mkdir $DIR/$tdir/striped_dir/dir_a
23210         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23211                 error "create striped dir under striped dir fails"
23212
23213         touch $DIR/$tdir/striped_dir1/b
23214         mkdir $DIR/$tdir/striped_dir1/dir_b
23215         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23216                 error "create striped dir under striped dir fails"
23217
23218         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23219                 error "rename dir under different striped dir should fail"
23220
23221         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23222                 error "rename striped dir under diff striped dir should fail"
23223
23224         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23225                 error "rename file under diff striped dirs fails"
23226
23227         rm -rf $DIR/$tdir
23228 }
23229 run_test 300f "check rename cross striped directory"
23230
23231 test_300_check_default_striped_dir()
23232 {
23233         local dirname=$1
23234         local default_count=$2
23235         local default_index=$3
23236         local stripe_count
23237         local stripe_index
23238         local dir_stripe_index
23239         local dir
23240
23241         echo "checking $dirname $default_count $default_index"
23242         $LFS setdirstripe -D -c $default_count -i $default_index \
23243                                 -H all_char $DIR/$tdir/$dirname ||
23244                 error "set default stripe on striped dir error"
23245         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23246         [ $stripe_count -eq $default_count ] ||
23247                 error "expect $default_count get $stripe_count for $dirname"
23248
23249         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23250         [ $stripe_index -eq $default_index ] ||
23251                 error "expect $default_index get $stripe_index for $dirname"
23252
23253         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23254                                                 error "create dirs failed"
23255
23256         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23257         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23258         for dir in $(find $DIR/$tdir/$dirname/*); do
23259                 stripe_count=$($LFS getdirstripe -c $dir)
23260                 (( $stripe_count == $default_count )) ||
23261                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23262                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23263                 error "stripe count $default_count != $stripe_count for $dir"
23264
23265                 stripe_index=$($LFS getdirstripe -i $dir)
23266                 [ $default_index -eq -1 ] ||
23267                         [ $stripe_index -eq $default_index ] ||
23268                         error "$stripe_index != $default_index for $dir"
23269
23270                 #check default stripe
23271                 stripe_count=$($LFS getdirstripe -D -c $dir)
23272                 [ $stripe_count -eq $default_count ] ||
23273                 error "default count $default_count != $stripe_count for $dir"
23274
23275                 stripe_index=$($LFS getdirstripe -D -i $dir)
23276                 [ $stripe_index -eq $default_index ] ||
23277                 error "default index $default_index != $stripe_index for $dir"
23278         done
23279         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23280 }
23281
23282 test_300g() {
23283         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23284         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23285                 skip "Need MDS version at least 2.7.55"
23286
23287         local dir
23288         local stripe_count
23289         local stripe_index
23290
23291         mkdir_on_mdt0 $DIR/$tdir
23292         mkdir $DIR/$tdir/normal_dir
23293
23294         #Checking when client cache stripe index
23295         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23296         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23297                 error "create striped_dir failed"
23298
23299         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23300                 error "create dir0 fails"
23301         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23302         [ $stripe_index -eq 0 ] ||
23303                 error "dir0 expect index 0 got $stripe_index"
23304
23305         mkdir $DIR/$tdir/striped_dir/dir1 ||
23306                 error "create dir1 fails"
23307         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23308         [ $stripe_index -eq 1 ] ||
23309                 error "dir1 expect index 1 got $stripe_index"
23310
23311         #check default stripe count/stripe index
23312         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23313         test_300_check_default_striped_dir normal_dir 1 0
23314         test_300_check_default_striped_dir normal_dir -1 1
23315         test_300_check_default_striped_dir normal_dir 2 -1
23316
23317         #delete default stripe information
23318         echo "delete default stripeEA"
23319         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23320                 error "set default stripe on striped dir error"
23321
23322         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23323         for dir in $(find $DIR/$tdir/normal_dir/*); do
23324                 stripe_count=$($LFS getdirstripe -c $dir)
23325                 [ $stripe_count -eq 0 ] ||
23326                         error "expect 1 get $stripe_count for $dir"
23327         done
23328 }
23329 run_test 300g "check default striped directory for normal directory"
23330
23331 test_300h() {
23332         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23333         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23334                 skip "Need MDS version at least 2.7.55"
23335
23336         local dir
23337         local stripe_count
23338
23339         mkdir $DIR/$tdir
23340         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23341                 error "set striped dir error"
23342
23343         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23344         test_300_check_default_striped_dir striped_dir 1 0
23345         test_300_check_default_striped_dir striped_dir -1 1
23346         test_300_check_default_striped_dir striped_dir 2 -1
23347
23348         #delete default stripe information
23349         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23350                 error "set default stripe on striped dir error"
23351
23352         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23353         for dir in $(find $DIR/$tdir/striped_dir/*); do
23354                 stripe_count=$($LFS getdirstripe -c $dir)
23355                 [ $stripe_count -eq 0 ] ||
23356                         error "expect 1 get $stripe_count for $dir"
23357         done
23358 }
23359 run_test 300h "check default striped directory for striped directory"
23360
23361 test_300i() {
23362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23363         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23364         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23365                 skip "Need MDS version at least 2.7.55"
23366
23367         local stripe_count
23368         local file
23369
23370         mkdir $DIR/$tdir
23371
23372         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23373                 error "set striped dir error"
23374
23375         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23376                 error "create files under striped dir failed"
23377
23378         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23379                 error "set striped hashdir error"
23380
23381         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23382                 error "create dir0 under hash dir failed"
23383         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23384                 error "create dir1 under hash dir failed"
23385         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23386                 error "create dir2 under hash dir failed"
23387
23388         # unfortunately, we need to umount to clear dir layout cache for now
23389         # once we fully implement dir layout, we can drop this
23390         umount_client $MOUNT || error "umount failed"
23391         mount_client $MOUNT || error "mount failed"
23392
23393         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23394         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23395         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
23396
23397         #set the stripe to be unknown hash type
23398         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
23399         $LCTL set_param fail_loc=0x1901
23400         for ((i = 0; i < 10; i++)); do
23401                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23402                         error "stat f-$i failed"
23403                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23404         done
23405
23406         touch $DIR/$tdir/striped_dir/f0 &&
23407                 error "create under striped dir with unknown hash should fail"
23408
23409         $LCTL set_param fail_loc=0
23410
23411         umount_client $MOUNT || error "umount failed"
23412         mount_client $MOUNT || error "mount failed"
23413
23414         return 0
23415 }
23416 run_test 300i "client handle unknown hash type striped directory"
23417
23418 test_300j() {
23419         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23421         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23422                 skip "Need MDS version at least 2.7.55"
23423
23424         local stripe_count
23425         local file
23426
23427         mkdir $DIR/$tdir
23428
23429         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23430         $LCTL set_param fail_loc=0x1702
23431         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23432                 error "set striped dir error"
23433
23434         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23435                 error "create files under striped dir failed"
23436
23437         $LCTL set_param fail_loc=0
23438
23439         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23440
23441         return 0
23442 }
23443 run_test 300j "test large update record"
23444
23445 test_300k() {
23446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23447         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23448         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23449                 skip "Need MDS version at least 2.7.55"
23450
23451         # this test needs a huge transaction
23452         local kb
23453         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23454              osd*.$FSNAME-MDT0000.kbytestotal")
23455         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23456
23457         local stripe_count
23458         local file
23459
23460         mkdir $DIR/$tdir
23461
23462         #define OBD_FAIL_LARGE_STRIPE   0x1703
23463         $LCTL set_param fail_loc=0x1703
23464         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23465                 error "set striped dir error"
23466         $LCTL set_param fail_loc=0
23467
23468         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23469                 error "getstripeddir fails"
23470         rm -rf $DIR/$tdir/striped_dir ||
23471                 error "unlink striped dir fails"
23472
23473         return 0
23474 }
23475 run_test 300k "test large striped directory"
23476
23477 test_300l() {
23478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23479         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23480         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23481                 skip "Need MDS version at least 2.7.55"
23482
23483         local stripe_index
23484
23485         test_mkdir -p $DIR/$tdir/striped_dir
23486         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23487                         error "chown $RUNAS_ID failed"
23488         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23489                 error "set default striped dir failed"
23490
23491         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23492         $LCTL set_param fail_loc=0x80000158
23493         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23494
23495         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23496         [ $stripe_index -eq 1 ] ||
23497                 error "expect 1 get $stripe_index for $dir"
23498 }
23499 run_test 300l "non-root user to create dir under striped dir with stale layout"
23500
23501 test_300m() {
23502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23503         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23504         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23505                 skip "Need MDS version at least 2.7.55"
23506
23507         mkdir -p $DIR/$tdir/striped_dir
23508         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23509                 error "set default stripes dir error"
23510
23511         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23512
23513         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23514         [ $stripe_count -eq 0 ] ||
23515                         error "expect 0 get $stripe_count for a"
23516
23517         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23518                 error "set default stripes dir error"
23519
23520         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23521
23522         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23523         [ $stripe_count -eq 0 ] ||
23524                         error "expect 0 get $stripe_count for b"
23525
23526         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23527                 error "set default stripes dir error"
23528
23529         mkdir $DIR/$tdir/striped_dir/c &&
23530                 error "default stripe_index is invalid, mkdir c should fails"
23531
23532         rm -rf $DIR/$tdir || error "rmdir fails"
23533 }
23534 run_test 300m "setstriped directory on single MDT FS"
23535
23536 cleanup_300n() {
23537         local list=$(comma_list $(mdts_nodes))
23538
23539         trap 0
23540         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23541 }
23542
23543 test_300n() {
23544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23545         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23546         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23547                 skip "Need MDS version at least 2.7.55"
23548         remote_mds_nodsh && skip "remote MDS with nodsh"
23549
23550         local stripe_index
23551         local list=$(comma_list $(mdts_nodes))
23552
23553         trap cleanup_300n RETURN EXIT
23554         mkdir -p $DIR/$tdir
23555         chmod 777 $DIR/$tdir
23556         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23557                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23558                 error "create striped dir succeeds with gid=0"
23559
23560         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23561         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23562                 error "create striped dir fails with gid=-1"
23563
23564         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23565         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23566                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23567                 error "set default striped dir succeeds with gid=0"
23568
23569
23570         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23571         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23572                 error "set default striped dir fails with gid=-1"
23573
23574
23575         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23576         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23577                                         error "create test_dir fails"
23578         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23579                                         error "create test_dir1 fails"
23580         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23581                                         error "create test_dir2 fails"
23582         cleanup_300n
23583 }
23584 run_test 300n "non-root user to create dir under striped dir with default EA"
23585
23586 test_300o() {
23587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23588         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23589         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23590                 skip "Need MDS version at least 2.7.55"
23591
23592         local numfree1
23593         local numfree2
23594
23595         mkdir -p $DIR/$tdir
23596
23597         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23598         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23599         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23600                 skip "not enough free inodes $numfree1 $numfree2"
23601         fi
23602
23603         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23604         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23605         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23606                 skip "not enough free space $numfree1 $numfree2"
23607         fi
23608
23609         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23610                 error "setdirstripe fails"
23611
23612         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23613                 error "create dirs fails"
23614
23615         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23616         ls $DIR/$tdir/striped_dir > /dev/null ||
23617                 error "ls striped dir fails"
23618         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23619                 error "unlink big striped dir fails"
23620 }
23621 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23622
23623 test_300p() {
23624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23625         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23626         remote_mds_nodsh && skip "remote MDS with nodsh"
23627
23628         mkdir_on_mdt0 $DIR/$tdir
23629
23630         #define OBD_FAIL_OUT_ENOSPC     0x1704
23631         do_facet mds2 lctl set_param fail_loc=0x80001704
23632         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23633                  && error "create striped directory should fail"
23634
23635         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23636
23637         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23638         true
23639 }
23640 run_test 300p "create striped directory without space"
23641
23642 test_300q() {
23643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23644         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23645
23646         local fd=$(free_fd)
23647         local cmd="exec $fd<$tdir"
23648         cd $DIR
23649         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23650         eval $cmd
23651         cmd="exec $fd<&-"
23652         trap "eval $cmd" EXIT
23653         cd $tdir || error "cd $tdir fails"
23654         rmdir  ../$tdir || error "rmdir $tdir fails"
23655         mkdir local_dir && error "create dir succeeds"
23656         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23657         eval $cmd
23658         return 0
23659 }
23660 run_test 300q "create remote directory under orphan directory"
23661
23662 test_300r() {
23663         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23664                 skip "Need MDS version at least 2.7.55" && return
23665         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23666
23667         mkdir $DIR/$tdir
23668
23669         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23670                 error "set striped dir error"
23671
23672         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23673                 error "getstripeddir fails"
23674
23675         local stripe_count
23676         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23677                       awk '/lmv_stripe_count:/ { print $2 }')
23678
23679         [ $MDSCOUNT -ne $stripe_count ] &&
23680                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23681
23682         rm -rf $DIR/$tdir/striped_dir ||
23683                 error "unlink striped dir fails"
23684 }
23685 run_test 300r "test -1 striped directory"
23686
23687 test_300s_helper() {
23688         local count=$1
23689
23690         local stripe_dir=$DIR/$tdir/striped_dir.$count
23691
23692         $LFS mkdir -c $count $stripe_dir ||
23693                 error "lfs mkdir -c error"
23694
23695         $LFS getdirstripe $stripe_dir ||
23696                 error "lfs getdirstripe fails"
23697
23698         local stripe_count
23699         stripe_count=$($LFS getdirstripe $stripe_dir |
23700                       awk '/lmv_stripe_count:/ { print $2 }')
23701
23702         [ $count -ne $stripe_count ] &&
23703                 error_noexit "bad stripe count $stripe_count expected $count"
23704
23705         local dupe_stripes
23706         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23707                 awk '/0x/ {count[$1] += 1}; END {
23708                         for (idx in count) {
23709                                 if (count[idx]>1) {
23710                                         print "index " idx " count " count[idx]
23711                                 }
23712                         }
23713                 }')
23714
23715         if [[ -n "$dupe_stripes" ]] ; then
23716                 lfs getdirstripe $stripe_dir
23717                 error_noexit "Dupe MDT above: $dupe_stripes "
23718         fi
23719
23720         rm -rf $stripe_dir ||
23721                 error_noexit "unlink $stripe_dir fails"
23722 }
23723
23724 test_300s() {
23725         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23726                 skip "Need MDS version at least 2.7.55" && return
23727         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23728
23729         mkdir $DIR/$tdir
23730         for count in $(seq 2 $MDSCOUNT); do
23731                 test_300s_helper $count
23732         done
23733 }
23734 run_test 300s "test lfs mkdir -c without -i"
23735
23736 prepare_remote_file() {
23737         mkdir $DIR/$tdir/src_dir ||
23738                 error "create remote source failed"
23739
23740         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23741                  error "cp to remote source failed"
23742         touch $DIR/$tdir/src_dir/a
23743
23744         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23745                 error "create remote target dir failed"
23746
23747         touch $DIR/$tdir/tgt_dir/b
23748
23749         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23750                 error "rename dir cross MDT failed!"
23751
23752         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23753                 error "src_child still exists after rename"
23754
23755         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23756                 error "missing file(a) after rename"
23757
23758         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
23759                 error "diff after rename"
23760 }
23761
23762 test_310a() {
23763         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23764         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23765
23766         local remote_file=$DIR/$tdir/tgt_dir/b
23767
23768         mkdir -p $DIR/$tdir
23769
23770         prepare_remote_file || error "prepare remote file failed"
23771
23772         #open-unlink file
23773         $OPENUNLINK $remote_file $remote_file ||
23774                 error "openunlink $remote_file failed"
23775         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23776 }
23777 run_test 310a "open unlink remote file"
23778
23779 test_310b() {
23780         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23782
23783         local remote_file=$DIR/$tdir/tgt_dir/b
23784
23785         mkdir -p $DIR/$tdir
23786
23787         prepare_remote_file || error "prepare remote file failed"
23788
23789         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23790         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23791         $CHECKSTAT -t file $remote_file || error "check file failed"
23792 }
23793 run_test 310b "unlink remote file with multiple links while open"
23794
23795 test_310c() {
23796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23797         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23798
23799         local remote_file=$DIR/$tdir/tgt_dir/b
23800
23801         mkdir -p $DIR/$tdir
23802
23803         prepare_remote_file || error "prepare remote file failed"
23804
23805         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23806         multiop_bg_pause $remote_file O_uc ||
23807                         error "mulitop failed for remote file"
23808         MULTIPID=$!
23809         $MULTIOP $DIR/$tfile Ouc
23810         kill -USR1 $MULTIPID
23811         wait $MULTIPID
23812 }
23813 run_test 310c "open-unlink remote file with multiple links"
23814
23815 #LU-4825
23816 test_311() {
23817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23818         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23819         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23820                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23821         remote_mds_nodsh && skip "remote MDS with nodsh"
23822
23823         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23824         local mdts=$(comma_list $(mdts_nodes))
23825
23826         mkdir -p $DIR/$tdir
23827         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23828         createmany -o $DIR/$tdir/$tfile. 1000
23829
23830         # statfs data is not real time, let's just calculate it
23831         old_iused=$((old_iused + 1000))
23832
23833         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23834                         osp.*OST0000*MDT0000.create_count")
23835         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23836                                 osp.*OST0000*MDT0000.max_create_count")
23837         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23838
23839         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23840         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23841         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23842
23843         unlinkmany $DIR/$tdir/$tfile. 1000
23844
23845         do_nodes $mdts "$LCTL set_param -n \
23846                         osp.*OST0000*.max_create_count=$max_count"
23847         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23848                 do_nodes $mdts "$LCTL set_param -n \
23849                                 osp.*OST0000*.create_count=$count"
23850         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23851                         grep "=0" && error "create_count is zero"
23852
23853         local new_iused
23854         for i in $(seq 120); do
23855                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23856                 # system may be too busy to destroy all objs in time, use
23857                 # a somewhat small value to not fail autotest
23858                 [ $((old_iused - new_iused)) -gt 400 ] && break
23859                 sleep 1
23860         done
23861
23862         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
23863         [ $((old_iused - new_iused)) -gt 400 ] ||
23864                 error "objs not destroyed after unlink"
23865 }
23866 run_test 311 "disable OSP precreate, and unlink should destroy objs"
23867
23868 zfs_oid_to_objid()
23869 {
23870         local ost=$1
23871         local objid=$2
23872
23873         local vdevdir=$(dirname $(facet_vdevice $ost))
23874         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
23875         local zfs_zapid=$(do_facet $ost $cmd |
23876                           grep -w "/O/0/d$((objid%32))" -C 5 |
23877                           awk '/Object/{getline; print $1}')
23878         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
23879                           awk "/$objid = /"'{printf $3}')
23880
23881         echo $zfs_objid
23882 }
23883
23884 zfs_object_blksz() {
23885         local ost=$1
23886         local objid=$2
23887
23888         local vdevdir=$(dirname $(facet_vdevice $ost))
23889         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
23890         local blksz=$(do_facet $ost $cmd $objid |
23891                       awk '/dblk/{getline; printf $4}')
23892
23893         case "${blksz: -1}" in
23894                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
23895                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
23896                 *) ;;
23897         esac
23898
23899         echo $blksz
23900 }
23901
23902 test_312() { # LU-4856
23903         remote_ost_nodsh && skip "remote OST with nodsh"
23904         [ "$ost1_FSTYPE" = "zfs" ] ||
23905                 skip_env "the test only applies to zfs"
23906
23907         local max_blksz=$(do_facet ost1 \
23908                           $ZFS get -p recordsize $(facet_device ost1) |
23909                           awk '!/VALUE/{print $3}')
23910
23911         # to make life a little bit easier
23912         $LFS mkdir -c 1 -i 0 $DIR/$tdir
23913         $LFS setstripe -c 1 -i 0 $DIR/$tdir
23914
23915         local tf=$DIR/$tdir/$tfile
23916         touch $tf
23917         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23918
23919         # Get ZFS object id
23920         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23921         # block size change by sequential overwrite
23922         local bs
23923
23924         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
23925                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
23926
23927                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
23928                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
23929         done
23930         rm -f $tf
23931
23932         # block size change by sequential append write
23933         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
23934         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23935         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23936         local count
23937
23938         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
23939                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
23940                         oflag=sync conv=notrunc
23941
23942                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
23943                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
23944                         error "blksz error, actual $blksz, " \
23945                                 "expected: 2 * $count * $PAGE_SIZE"
23946         done
23947         rm -f $tf
23948
23949         # random write
23950         touch $tf
23951         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23952         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23953
23954         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
23955         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23956         [ $blksz -eq $PAGE_SIZE ] ||
23957                 error "blksz error: $blksz, expected: $PAGE_SIZE"
23958
23959         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
23960         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23961         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
23962
23963         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
23964         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23965         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
23966 }
23967 run_test 312 "make sure ZFS adjusts its block size by write pattern"
23968
23969 test_313() {
23970         remote_ost_nodsh && skip "remote OST with nodsh"
23971
23972         local file=$DIR/$tfile
23973
23974         rm -f $file
23975         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
23976
23977         # define OBD_FAIL_TGT_RCVD_EIO           0x720
23978         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23979         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
23980                 error "write should failed"
23981         do_facet ost1 "$LCTL set_param fail_loc=0"
23982         rm -f $file
23983 }
23984 run_test 313 "io should fail after last_rcvd update fail"
23985
23986 test_314() {
23987         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23988
23989         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
23990         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23991         rm -f $DIR/$tfile
23992         wait_delete_completed
23993         do_facet ost1 "$LCTL set_param fail_loc=0"
23994 }
23995 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
23996
23997 test_315() { # LU-618
23998         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
23999
24000         local file=$DIR/$tfile
24001         rm -f $file
24002
24003         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24004                 error "multiop file write failed"
24005         $MULTIOP $file oO_RDONLY:r4063232_c &
24006         PID=$!
24007
24008         sleep 2
24009
24010         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24011         kill -USR1 $PID
24012
24013         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24014         rm -f $file
24015 }
24016 run_test 315 "read should be accounted"
24017
24018 test_316() {
24019         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24020         large_xattr_enabled || skip_env "ea_inode feature disabled"
24021
24022         rm -rf $DIR/$tdir/d
24023         mkdir -p $DIR/$tdir/d
24024         chown nobody $DIR/$tdir/d
24025         touch $DIR/$tdir/d/file
24026
24027         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
24028 }
24029 run_test 316 "lfs mv"
24030
24031 test_317() {
24032         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24033                 skip "Need MDS version at least 2.11.53"
24034         if [ "$ost1_FSTYPE" == "zfs" ]; then
24035                 skip "LU-10370: no implementation for ZFS"
24036         fi
24037
24038         local trunc_sz
24039         local grant_blk_size
24040
24041         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24042                         awk '/grant_block_size:/ { print $2; exit; }')
24043         #
24044         # Create File of size 5M. Truncate it to below size's and verify
24045         # blocks count.
24046         #
24047         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24048                 error "Create file $DIR/$tfile failed"
24049         stack_trap "rm -f $DIR/$tfile" EXIT
24050
24051         for trunc_sz in 2097152 4097 4000 509 0; do
24052                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24053                         error "truncate $tfile to $trunc_sz failed"
24054                 local sz=$(stat --format=%s $DIR/$tfile)
24055                 local blk=$(stat --format=%b $DIR/$tfile)
24056                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24057                                      grant_blk_size) * 8))
24058
24059                 if [[ $blk -ne $trunc_blk ]]; then
24060                         $(which stat) $DIR/$tfile
24061                         error "Expected Block $trunc_blk got $blk for $tfile"
24062                 fi
24063
24064                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24065                         error "Expected Size $trunc_sz got $sz for $tfile"
24066         done
24067
24068         #
24069         # sparse file test
24070         # Create file with a hole and write actual 65536 bytes which aligned
24071         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24072         #
24073         local bs=65536
24074         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24075                 error "Create file : $DIR/$tfile"
24076
24077         #
24078         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24079         # blocks. The block count must drop to 8.
24080         #
24081         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - \
24082                 ((bs - grant_blk_size) + 1)))
24083         $TRUNCATE $DIR/$tfile $trunc_sz ||
24084                 error "truncate $tfile to $trunc_sz failed"
24085
24086         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24087         sz=$(stat --format=%s $DIR/$tfile)
24088         blk=$(stat --format=%b $DIR/$tfile)
24089
24090         if [[ $blk -ne $trunc_bsz ]]; then
24091                 $(which stat) $DIR/$tfile
24092                 error "Expected Block $trunc_bsz got $blk for $tfile"
24093         fi
24094
24095         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24096                 error "Expected Size $trunc_sz got $sz for $tfile"
24097 }
24098 run_test 317 "Verify blocks get correctly update after truncate"
24099
24100 test_318() {
24101         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24102         local old_max_active=$($LCTL get_param -n \
24103                             ${llite_name}.max_read_ahead_async_active \
24104                             2>/dev/null)
24105
24106         $LCTL set_param llite.*.max_read_ahead_async_active=256
24107         local max_active=$($LCTL get_param -n \
24108                            ${llite_name}.max_read_ahead_async_active \
24109                            2>/dev/null)
24110         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24111
24112         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24113                 error "set max_read_ahead_async_active should succeed"
24114
24115         $LCTL set_param llite.*.max_read_ahead_async_active=512
24116         max_active=$($LCTL get_param -n \
24117                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24118         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24119
24120         # restore @max_active
24121         [ $old_max_active -ne 0 ] && $LCTL set_param \
24122                 llite.*.max_read_ahead_async_active=$old_max_active
24123
24124         local old_threshold=$($LCTL get_param -n \
24125                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24126         local max_per_file_mb=$($LCTL get_param -n \
24127                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24128
24129         local invalid=$(($max_per_file_mb + 1))
24130         $LCTL set_param \
24131                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24132                         && error "set $invalid should fail"
24133
24134         local valid=$(($invalid - 1))
24135         $LCTL set_param \
24136                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24137                         error "set $valid should succeed"
24138         local threshold=$($LCTL get_param -n \
24139                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24140         [ $threshold -eq $valid ] || error \
24141                 "expect threshold $valid got $threshold"
24142         $LCTL set_param \
24143                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24144 }
24145 run_test 318 "Verify async readahead tunables"
24146
24147 test_319() {
24148         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
24149
24150         local before=$(date +%s)
24151         local evict
24152         local mdir=$DIR/$tdir
24153         local file=$mdir/xxx
24154
24155         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24156         touch $file
24157
24158 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24159         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24160         $LFS mv -m1 $file &
24161
24162         sleep 1
24163         dd if=$file of=/dev/null
24164         wait
24165         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24166           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24167
24168         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24169 }
24170 run_test 319 "lost lease lock on migrate error"
24171
24172 test_398a() { # LU-4198
24173         local ost1_imp=$(get_osc_import_name client ost1)
24174         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24175                          cut -d'.' -f2)
24176
24177         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24178         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24179
24180         # request a new lock on client
24181         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24182
24183         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24184         local lock_count=$($LCTL get_param -n \
24185                            ldlm.namespaces.$imp_name.lru_size)
24186         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24187
24188         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24189
24190         # no lock cached, should use lockless IO and not enqueue new lock
24191         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24192         lock_count=$($LCTL get_param -n \
24193                      ldlm.namespaces.$imp_name.lru_size)
24194         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24195 }
24196 run_test 398a "direct IO should cancel lock otherwise lockless"
24197
24198 test_398b() { # LU-4198
24199         which fio || skip_env "no fio installed"
24200         $LFS setstripe -c -1 $DIR/$tfile
24201
24202         local size=12
24203         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24204
24205         local njobs=4
24206         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
24207         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24208                 --numjobs=$njobs --fallocate=none \
24209                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24210                 --filename=$DIR/$tfile &
24211         bg_pid=$!
24212
24213         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
24214         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
24215                 --numjobs=$njobs --fallocate=none \
24216                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24217                 --filename=$DIR/$tfile || true
24218         wait $bg_pid
24219
24220         rm -f $DIR/$tfile
24221 }
24222 run_test 398b "DIO and buffer IO race"
24223
24224 test_398c() { # LU-4198
24225         local ost1_imp=$(get_osc_import_name client ost1)
24226         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24227                          cut -d'.' -f2)
24228
24229         which fio || skip_env "no fio installed"
24230
24231         saved_debug=$($LCTL get_param -n debug)
24232         $LCTL set_param debug=0
24233
24234         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24235         ((size /= 1024)) # by megabytes
24236         ((size /= 2)) # write half of the OST at most
24237         [ $size -gt 40 ] && size=40 #reduce test time anyway
24238
24239         $LFS setstripe -c 1 $DIR/$tfile
24240
24241         # it seems like ldiskfs reserves more space than necessary if the
24242         # writing blocks are not mapped, so it extends the file firstly
24243         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24244         cancel_lru_locks osc
24245
24246         # clear and verify rpc_stats later
24247         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24248
24249         local njobs=4
24250         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24251         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24252                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24253                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24254                 --filename=$DIR/$tfile
24255         [ $? -eq 0 ] || error "fio write error"
24256
24257         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24258                 error "Locks were requested while doing AIO"
24259
24260         # get the percentage of 1-page I/O
24261         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24262                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24263                 awk '{print $7}')
24264         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24265
24266         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24267         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24268                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24269                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24270                 --filename=$DIR/$tfile
24271         [ $? -eq 0 ] || error "fio mixed read write error"
24272
24273         echo "AIO with large block size ${size}M"
24274         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24275                 --numjobs=1 --fallocate=none --ioengine=libaio \
24276                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24277                 --filename=$DIR/$tfile
24278         [ $? -eq 0 ] || error "fio large block size failed"
24279
24280         rm -f $DIR/$tfile
24281         $LCTL set_param debug="$saved_debug"
24282 }
24283 run_test 398c "run fio to test AIO"
24284
24285 test_398d() { #  LU-13846
24286         which aiocp || skip_env "no aiocp installed"
24287         local aio_file=$DIR/$tfile.aio
24288
24289         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24290
24291         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24292         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24293         stack_trap "rm -f $DIR/$tfile $aio_file"
24294
24295         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24296
24297         # make sure we don't crash and fail properly
24298         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24299                 error "aio not aligned with PAGE SIZE should fail"
24300
24301         rm -f $DIR/$tfile $aio_file
24302 }
24303 run_test 398d "run aiocp to verify block size > stripe size"
24304
24305 test_398e() {
24306         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24307         touch $DIR/$tfile.new
24308         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24309 }
24310 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24311
24312 test_398f() { #  LU-14687
24313         which aiocp || skip_env "no aiocp installed"
24314         local aio_file=$DIR/$tfile.aio
24315
24316         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24317
24318         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24319         stack_trap "rm -f $DIR/$tfile $aio_file"
24320
24321         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24322         $LCTL set_param fail_loc=0x1418
24323         # make sure we don't crash and fail properly
24324         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24325                 error "aio with page allocation failure succeeded"
24326         $LCTL set_param fail_loc=0
24327         diff $DIR/$tfile $aio_file
24328         [[ $? != 0 ]] || error "no diff after failed aiocp"
24329 }
24330 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24331
24332 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24333 # stripe and i/o size must be > stripe size
24334 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24335 # single RPC in flight.  This test shows async DIO submission is working by
24336 # showing multiple RPCs in flight.
24337 test_398g() { #  LU-13798
24338         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24339
24340         # We need to do some i/o first to acquire enough grant to put our RPCs
24341         # in flight; otherwise a new connection may not have enough grant
24342         # available
24343         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24344                 error "parallel dio failed"
24345         stack_trap "rm -f $DIR/$tfile"
24346
24347         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24348         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24349         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24350         stack_trap "$LCTL set_param -n $pages_per_rpc"
24351
24352         # Recreate file so it's empty
24353         rm -f $DIR/$tfile
24354         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24355         #Pause rpc completion to guarantee we see multiple rpcs in flight
24356         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24357         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24358         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24359
24360         # Clear rpc stats
24361         $LCTL set_param osc.*.rpc_stats=c
24362
24363         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24364                 error "parallel dio failed"
24365         stack_trap "rm -f $DIR/$tfile"
24366
24367         $LCTL get_param osc.*-OST0000-*.rpc_stats
24368         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24369                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24370                 grep "8:" | awk '{print $8}')
24371         # We look at the "8 rpcs in flight" field, and verify A) it is present
24372         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24373         # as expected for an 8M DIO to a file with 1M stripes.
24374         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24375
24376         # Verify turning off parallel dio works as expected
24377         # Clear rpc stats
24378         $LCTL set_param osc.*.rpc_stats=c
24379         $LCTL set_param llite.*.parallel_dio=0
24380         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24381
24382         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24383                 error "dio with parallel dio disabled failed"
24384
24385         # Ideally, we would see only one RPC in flight here, but there is an
24386         # unavoidable race between i/o completion and RPC in flight counting,
24387         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24388         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24389         # So instead we just verify it's always < 8.
24390         $LCTL get_param osc.*-OST0000-*.rpc_stats
24391         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24392                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24393                 grep '^$' -B1 | grep . | awk '{print $1}')
24394         [ $ret != "8:" ] ||
24395                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24396 }
24397 run_test 398g "verify parallel dio async RPC submission"
24398
24399 test_398h() { #  LU-13798
24400         local dio_file=$DIR/$tfile.dio
24401
24402         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24403
24404         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24405         stack_trap "rm -f $DIR/$tfile $dio_file"
24406
24407         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24408                 error "parallel dio failed"
24409         diff $DIR/$tfile $dio_file
24410         [[ $? == 0 ]] || error "file diff after aiocp"
24411 }
24412 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24413
24414 test_398i() { #  LU-13798
24415         local dio_file=$DIR/$tfile.dio
24416
24417         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24418
24419         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24420         stack_trap "rm -f $DIR/$tfile $dio_file"
24421
24422         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24423         $LCTL set_param fail_loc=0x1418
24424         # make sure we don't crash and fail properly
24425         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24426                 error "parallel dio page allocation failure succeeded"
24427         diff $DIR/$tfile $dio_file
24428         [[ $? != 0 ]] || error "no diff after failed aiocp"
24429 }
24430 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24431
24432 test_398j() { #  LU-13798
24433         # Stripe size > RPC size but less than i/o size tests split across
24434         # stripes and RPCs for individual i/o op
24435         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24436
24437         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24438         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24439         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24440         stack_trap "$LCTL set_param -n $pages_per_rpc"
24441
24442         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24443                 error "parallel dio write failed"
24444         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24445
24446         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24447                 error "parallel dio read failed"
24448         diff $DIR/$tfile $DIR/$tfile.2
24449         [[ $? == 0 ]] || error "file diff after parallel dio read"
24450 }
24451 run_test 398j "test parallel dio where stripe size > rpc_size"
24452
24453 test_398k() { #  LU-13798
24454         wait_delete_completed
24455         wait_mds_ost_sync
24456
24457         # 4 stripe file; we will cause out of space on OST0
24458         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24459
24460         # Fill OST0 (if it's not too large)
24461         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24462                    head -n1)
24463         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24464                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24465         fi
24466         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24467         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24468                 error "dd should fill OST0"
24469         stack_trap "rm -f $DIR/$tfile.1"
24470
24471         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24472         err=$?
24473
24474         ls -la $DIR/$tfile
24475         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24476                 error "file is not 0 bytes in size"
24477
24478         # dd above should not succeed, but don't error until here so we can
24479         # get debug info above
24480         [[ $err != 0 ]] ||
24481                 error "parallel dio write with enospc succeeded"
24482         stack_trap "rm -f $DIR/$tfile"
24483 }
24484 run_test 398k "test enospc on first stripe"
24485
24486 test_398l() { #  LU-13798
24487         wait_delete_completed
24488         wait_mds_ost_sync
24489
24490         # 4 stripe file; we will cause out of space on OST0
24491         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24492         # happens on the second i/o chunk we issue
24493         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24494
24495         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24496         stack_trap "rm -f $DIR/$tfile"
24497
24498         # Fill OST0 (if it's not too large)
24499         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24500                    head -n1)
24501         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24502                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24503         fi
24504         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24505         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24506                 error "dd should fill OST0"
24507         stack_trap "rm -f $DIR/$tfile.1"
24508
24509         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24510         err=$?
24511         stack_trap "rm -f $DIR/$tfile.2"
24512
24513         # Check that short write completed as expected
24514         ls -la $DIR/$tfile.2
24515         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24516                 error "file is not 1M 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
24523         # Truncate source file to same length as output file and diff them
24524         $TRUNCATE $DIR/$tfile 1048576
24525         diff $DIR/$tfile $DIR/$tfile.2
24526         [[ $? == 0 ]] || error "data incorrect after short write"
24527 }
24528 run_test 398l "test enospc on intermediate stripe/RPC"
24529
24530 test_398m() { #  LU-13798
24531         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24532
24533         # Set up failure on OST0, the first stripe:
24534         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24535         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24536         # So this fail_val specifies OST0
24537         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24538         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24539
24540         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24541                 error "parallel dio write with failure on first stripe succeeded"
24542         stack_trap "rm -f $DIR/$tfile"
24543         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24544
24545         # Place data in file for read
24546         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24547                 error "parallel dio write failed"
24548
24549         # Fail read on OST0, first stripe
24550         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24551         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24552         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24553                 error "parallel dio read with error on first stripe succeeded"
24554         rm -f $DIR/$tfile.2
24555         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24556
24557         # Switch to testing on OST1, second stripe
24558         # Clear file contents, maintain striping
24559         echo > $DIR/$tfile
24560         # Set up failure on OST1, second stripe:
24561         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24562         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24563
24564         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24565                 error "parallel dio write with failure on first stripe succeeded"
24566         stack_trap "rm -f $DIR/$tfile"
24567         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24568
24569         # Place data in file for read
24570         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24571                 error "parallel dio write failed"
24572
24573         # Fail read on OST1, second stripe
24574         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24575         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24576         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24577                 error "parallel dio read with error on first stripe succeeded"
24578         rm -f $DIR/$tfile.2
24579         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24580 }
24581 run_test 398m "test RPC failures with parallel dio"
24582
24583 # Parallel submission of DIO should not cause problems for append, but it's
24584 # important to verify.
24585 test_398n() { #  LU-13798
24586         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24587
24588         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24589                 error "dd to create source file failed"
24590         stack_trap "rm -f $DIR/$tfile"
24591
24592         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24593                 error "parallel dio write with failure on second stripe succeeded"
24594         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24595         diff $DIR/$tfile $DIR/$tfile.1
24596         [[ $? == 0 ]] || error "data incorrect after append"
24597
24598 }
24599 run_test 398n "test append with parallel DIO"
24600
24601 test_fake_rw() {
24602         local read_write=$1
24603         if [ "$read_write" = "write" ]; then
24604                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24605         elif [ "$read_write" = "read" ]; then
24606                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24607         else
24608                 error "argument error"
24609         fi
24610
24611         # turn off debug for performance testing
24612         local saved_debug=$($LCTL get_param -n debug)
24613         $LCTL set_param debug=0
24614
24615         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24616
24617         # get ost1 size - $FSNAME-OST0000
24618         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24619         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
24620         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
24621
24622         if [ "$read_write" = "read" ]; then
24623                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
24624         fi
24625
24626         local start_time=$(date +%s.%N)
24627         $dd_cmd bs=1M count=$blocks oflag=sync ||
24628                 error "real dd $read_write error"
24629         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
24630
24631         if [ "$read_write" = "write" ]; then
24632                 rm -f $DIR/$tfile
24633         fi
24634
24635         # define OBD_FAIL_OST_FAKE_RW           0x238
24636         do_facet ost1 $LCTL set_param fail_loc=0x238
24637
24638         local start_time=$(date +%s.%N)
24639         $dd_cmd bs=1M count=$blocks oflag=sync ||
24640                 error "fake dd $read_write error"
24641         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
24642
24643         if [ "$read_write" = "write" ]; then
24644                 # verify file size
24645                 cancel_lru_locks osc
24646                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
24647                         error "$tfile size not $blocks MB"
24648         fi
24649         do_facet ost1 $LCTL set_param fail_loc=0
24650
24651         echo "fake $read_write $duration_fake vs. normal $read_write" \
24652                 "$duration in seconds"
24653         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
24654                 error_not_in_vm "fake write is slower"
24655
24656         $LCTL set_param -n debug="$saved_debug"
24657         rm -f $DIR/$tfile
24658 }
24659 test_399a() { # LU-7655 for OST fake write
24660         remote_ost_nodsh && skip "remote OST with nodsh"
24661
24662         test_fake_rw write
24663 }
24664 run_test 399a "fake write should not be slower than normal write"
24665
24666 test_399b() { # LU-8726 for OST fake read
24667         remote_ost_nodsh && skip "remote OST with nodsh"
24668         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
24669                 skip_env "ldiskfs only test"
24670         fi
24671
24672         test_fake_rw read
24673 }
24674 run_test 399b "fake read should not be slower than normal read"
24675
24676 test_400a() { # LU-1606, was conf-sanity test_74
24677         if ! which $CC > /dev/null 2>&1; then
24678                 skip_env "$CC is not installed"
24679         fi
24680
24681         local extra_flags=''
24682         local out=$TMP/$tfile
24683         local prefix=/usr/include/lustre
24684         local prog
24685
24686         # Oleg removes c files in his test rig so test if any c files exist
24687         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24688                 skip_env "Needed c test files are missing"
24689
24690         if ! [[ -d $prefix ]]; then
24691                 # Assume we're running in tree and fixup the include path.
24692                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24693                 extra_flags+=" -L$LUSTRE/utils/.lib"
24694         fi
24695
24696         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24697                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24698                         error "client api broken"
24699         done
24700         rm -f $out
24701 }
24702 run_test 400a "Lustre client api program can compile and link"
24703
24704 test_400b() { # LU-1606, LU-5011
24705         local header
24706         local out=$TMP/$tfile
24707         local prefix=/usr/include/linux/lustre
24708
24709         # We use a hard coded prefix so that this test will not fail
24710         # when run in tree. There are headers in lustre/include/lustre/
24711         # that are not packaged (like lustre_idl.h) and have more
24712         # complicated include dependencies (like config.h and lnet/types.h).
24713         # Since this test about correct packaging we just skip them when
24714         # they don't exist (see below) rather than try to fixup cppflags.
24715
24716         if ! which $CC > /dev/null 2>&1; then
24717                 skip_env "$CC is not installed"
24718         fi
24719
24720         for header in $prefix/*.h; do
24721                 if ! [[ -f "$header" ]]; then
24722                         continue
24723                 fi
24724
24725                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24726                         continue # lustre_ioctl.h is internal header
24727                 fi
24728
24729                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24730                         error "cannot compile '$header'"
24731         done
24732         rm -f $out
24733 }
24734 run_test 400b "packaged headers can be compiled"
24735
24736 test_401a() { #LU-7437
24737         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
24738         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
24739
24740         #count the number of parameters by "list_param -R"
24741         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
24742         #count the number of parameters by listing proc files
24743         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
24744         echo "proc_dirs='$proc_dirs'"
24745         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
24746         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
24747                       sort -u | wc -l)
24748
24749         [ $params -eq $procs ] ||
24750                 error "found $params parameters vs. $procs proc files"
24751
24752         # test the list_param -D option only returns directories
24753         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
24754         #count the number of parameters by listing proc directories
24755         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
24756                 sort -u | wc -l)
24757
24758         [ $params -eq $procs ] ||
24759                 error "found $params parameters vs. $procs proc files"
24760 }
24761 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
24762
24763 test_401b() {
24764         # jobid_var may not allow arbitrary values, so use jobid_name
24765         # if available
24766         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24767                 local testname=jobid_name tmp='testing%p'
24768         else
24769                 local testname=jobid_var tmp=testing
24770         fi
24771
24772         local save=$($LCTL get_param -n $testname)
24773
24774         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
24775                 error "no error returned when setting bad parameters"
24776
24777         local jobid_new=$($LCTL get_param -n foe $testname baz)
24778         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
24779
24780         $LCTL set_param -n fog=bam $testname=$save bat=fog
24781         local jobid_old=$($LCTL get_param -n foe $testname bag)
24782         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
24783 }
24784 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
24785
24786 test_401c() {
24787         # jobid_var may not allow arbitrary values, so use jobid_name
24788         # if available
24789         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24790                 local testname=jobid_name
24791         else
24792                 local testname=jobid_var
24793         fi
24794
24795         local jobid_var_old=$($LCTL get_param -n $testname)
24796         local jobid_var_new
24797
24798         $LCTL set_param $testname= &&
24799                 error "no error returned for 'set_param a='"
24800
24801         jobid_var_new=$($LCTL get_param -n $testname)
24802         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24803                 error "$testname was changed by setting without value"
24804
24805         $LCTL set_param $testname &&
24806                 error "no error returned for 'set_param a'"
24807
24808         jobid_var_new=$($LCTL get_param -n $testname)
24809         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24810                 error "$testname was changed by setting without value"
24811 }
24812 run_test 401c "Verify 'lctl set_param' without value fails in either format."
24813
24814 test_401d() {
24815         # jobid_var may not allow arbitrary values, so use jobid_name
24816         # if available
24817         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24818                 local testname=jobid_name new_value='foo=bar%p'
24819         else
24820                 local testname=jobid_var new_valuie=foo=bar
24821         fi
24822
24823         local jobid_var_old=$($LCTL get_param -n $testname)
24824         local jobid_var_new
24825
24826         $LCTL set_param $testname=$new_value ||
24827                 error "'set_param a=b' did not accept a value containing '='"
24828
24829         jobid_var_new=$($LCTL get_param -n $testname)
24830         [[ "$jobid_var_new" == "$new_value" ]] ||
24831                 error "'set_param a=b' failed on a value containing '='"
24832
24833         # Reset the $testname to test the other format
24834         $LCTL set_param $testname=$jobid_var_old
24835         jobid_var_new=$($LCTL get_param -n $testname)
24836         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24837                 error "failed to reset $testname"
24838
24839         $LCTL set_param $testname $new_value ||
24840                 error "'set_param a b' did not accept a value containing '='"
24841
24842         jobid_var_new=$($LCTL get_param -n $testname)
24843         [[ "$jobid_var_new" == "$new_value" ]] ||
24844                 error "'set_param a b' failed on a value containing '='"
24845
24846         $LCTL set_param $testname $jobid_var_old
24847         jobid_var_new=$($LCTL get_param -n $testname)
24848         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24849                 error "failed to reset $testname"
24850 }
24851 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
24852
24853 test_401e() { # LU-14779
24854         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
24855                 error "lctl list_param MGC* failed"
24856         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
24857         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
24858                 error "lctl get_param lru_size failed"
24859 }
24860 run_test 401e "verify 'lctl get_param' works with NID in parameter"
24861
24862 test_402() {
24863         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
24864         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
24865                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
24866         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
24867                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
24868                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
24869         remote_mds_nodsh && skip "remote MDS with nodsh"
24870
24871         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
24872 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
24873         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
24874         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
24875                 echo "Touch failed - OK"
24876 }
24877 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
24878
24879 test_403() {
24880         local file1=$DIR/$tfile.1
24881         local file2=$DIR/$tfile.2
24882         local tfile=$TMP/$tfile
24883
24884         rm -f $file1 $file2 $tfile
24885
24886         touch $file1
24887         ln $file1 $file2
24888
24889         # 30 sec OBD_TIMEOUT in ll_getattr()
24890         # right before populating st_nlink
24891         $LCTL set_param fail_loc=0x80001409
24892         stat -c %h $file1 > $tfile &
24893
24894         # create an alias, drop all locks and reclaim the dentry
24895         < $file2
24896         cancel_lru_locks mdc
24897         cancel_lru_locks osc
24898         sysctl -w vm.drop_caches=2
24899
24900         wait
24901
24902         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
24903
24904         rm -f $tfile $file1 $file2
24905 }
24906 run_test 403 "i_nlink should not drop to zero due to aliasing"
24907
24908 test_404() { # LU-6601
24909         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
24910                 skip "Need server version newer than 2.8.52"
24911         remote_mds_nodsh && skip "remote MDS with nodsh"
24912
24913         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
24914                 awk '/osp .*-osc-MDT/ { print $4}')
24915
24916         local osp
24917         for osp in $mosps; do
24918                 echo "Deactivate: " $osp
24919                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
24920                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24921                         awk -vp=$osp '$4 == p { print $2 }')
24922                 [ $stat = IN ] || {
24923                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24924                         error "deactivate error"
24925                 }
24926                 echo "Activate: " $osp
24927                 do_facet $SINGLEMDS $LCTL --device %$osp activate
24928                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24929                         awk -vp=$osp '$4 == p { print $2 }')
24930                 [ $stat = UP ] || {
24931                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24932                         error "activate error"
24933                 }
24934         done
24935 }
24936 run_test 404 "validate manual {de}activated works properly for OSPs"
24937
24938 test_405() {
24939         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24940         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
24941                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
24942                         skip "Layout swap lock is not supported"
24943
24944         check_swap_layouts_support
24945         check_swap_layout_no_dom $DIR
24946
24947         test_mkdir $DIR/$tdir
24948         swap_lock_test -d $DIR/$tdir ||
24949                 error "One layout swap locked test failed"
24950 }
24951 run_test 405 "Various layout swap lock tests"
24952
24953 test_406() {
24954         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24955         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
24956         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
24957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24958         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
24959                 skip "Need MDS version at least 2.8.50"
24960
24961         local def_stripe_size=$($LFS getstripe -S $MOUNT)
24962         local test_pool=$TESTNAME
24963
24964         pool_add $test_pool || error "pool_add failed"
24965         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
24966                 error "pool_add_targets failed"
24967
24968         save_layout_restore_at_exit $MOUNT
24969
24970         # parent set default stripe count only, child will stripe from both
24971         # parent and fs default
24972         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
24973                 error "setstripe $MOUNT failed"
24974         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
24975         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
24976         for i in $(seq 10); do
24977                 local f=$DIR/$tdir/$tfile.$i
24978                 touch $f || error "touch failed"
24979                 local count=$($LFS getstripe -c $f)
24980                 [ $count -eq $OSTCOUNT ] ||
24981                         error "$f stripe count $count != $OSTCOUNT"
24982                 local offset=$($LFS getstripe -i $f)
24983                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
24984                 local size=$($LFS getstripe -S $f)
24985                 [ $size -eq $((def_stripe_size * 2)) ] ||
24986                         error "$f stripe size $size != $((def_stripe_size * 2))"
24987                 local pool=$($LFS getstripe -p $f)
24988                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
24989         done
24990
24991         # change fs default striping, delete parent default striping, now child
24992         # will stripe from new fs default striping only
24993         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
24994                 error "change $MOUNT default stripe failed"
24995         $LFS setstripe -c 0 $DIR/$tdir ||
24996                 error "delete $tdir default stripe failed"
24997         for i in $(seq 11 20); do
24998                 local f=$DIR/$tdir/$tfile.$i
24999                 touch $f || error "touch $f failed"
25000                 local count=$($LFS getstripe -c $f)
25001                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25002                 local offset=$($LFS getstripe -i $f)
25003                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25004                 local size=$($LFS getstripe -S $f)
25005                 [ $size -eq $def_stripe_size ] ||
25006                         error "$f stripe size $size != $def_stripe_size"
25007                 local pool=$($LFS getstripe -p $f)
25008                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25009         done
25010
25011         unlinkmany $DIR/$tdir/$tfile. 1 20
25012
25013         local f=$DIR/$tdir/$tfile
25014         pool_remove_all_targets $test_pool $f
25015         pool_remove $test_pool $f
25016 }
25017 run_test 406 "DNE support fs default striping"
25018
25019 test_407() {
25020         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25021         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25022                 skip "Need MDS version at least 2.8.55"
25023         remote_mds_nodsh && skip "remote MDS with nodsh"
25024
25025         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25026                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25027         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25028                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25029         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25030
25031         #define OBD_FAIL_DT_TXN_STOP    0x2019
25032         for idx in $(seq $MDSCOUNT); do
25033                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25034         done
25035         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25036         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25037                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25038         true
25039 }
25040 run_test 407 "transaction fail should cause operation fail"
25041
25042 test_408() {
25043         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25044
25045         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25046         lctl set_param fail_loc=0x8000040a
25047         # let ll_prepare_partial_page() fail
25048         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25049
25050         rm -f $DIR/$tfile
25051
25052         # create at least 100 unused inodes so that
25053         # shrink_icache_memory(0) should not return 0
25054         touch $DIR/$tfile-{0..100}
25055         rm -f $DIR/$tfile-{0..100}
25056         sync
25057
25058         echo 2 > /proc/sys/vm/drop_caches
25059 }
25060 run_test 408 "drop_caches should not hang due to page leaks"
25061
25062 test_409()
25063 {
25064         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25065
25066         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25067         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25068         touch $DIR/$tdir/guard || error "(2) Fail to create"
25069
25070         local PREFIX=$(str_repeat 'A' 128)
25071         echo "Create 1K hard links start at $(date)"
25072         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25073                 error "(3) Fail to hard link"
25074
25075         echo "Links count should be right although linkEA overflow"
25076         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25077         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25078         [ $linkcount -eq 1001 ] ||
25079                 error "(5) Unexpected hard links count: $linkcount"
25080
25081         echo "List all links start at $(date)"
25082         ls -l $DIR/$tdir/foo > /dev/null ||
25083                 error "(6) Fail to list $DIR/$tdir/foo"
25084
25085         echo "Unlink hard links start at $(date)"
25086         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25087                 error "(7) Fail to unlink"
25088         echo "Unlink hard links finished at $(date)"
25089 }
25090 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25091
25092 test_410()
25093 {
25094         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25095                 skip "Need client version at least 2.9.59"
25096         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25097                 skip "Need MODULES build"
25098
25099         # Create a file, and stat it from the kernel
25100         local testfile=$DIR/$tfile
25101         touch $testfile
25102
25103         local run_id=$RANDOM
25104         local my_ino=$(stat --format "%i" $testfile)
25105
25106         # Try to insert the module. This will always fail as the
25107         # module is designed to not be inserted.
25108         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25109             &> /dev/null
25110
25111         # Anything but success is a test failure
25112         dmesg | grep -q \
25113             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25114             error "no inode match"
25115 }
25116 run_test 410 "Test inode number returned from kernel thread"
25117
25118 cleanup_test411_cgroup() {
25119         trap 0
25120         rmdir "$1"
25121 }
25122
25123 test_411() {
25124         local cg_basedir=/sys/fs/cgroup/memory
25125         # LU-9966
25126         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25127                 skip "no setup for cgroup"
25128
25129         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25130                 error "test file creation failed"
25131         cancel_lru_locks osc
25132
25133         # Create a very small memory cgroup to force a slab allocation error
25134         local cgdir=$cg_basedir/osc_slab_alloc
25135         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25136         trap "cleanup_test411_cgroup $cgdir" EXIT
25137         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25138         echo 1M > $cgdir/memory.limit_in_bytes
25139
25140         # Should not LBUG, just be killed by oom-killer
25141         # dd will return 0 even allocation failure in some environment.
25142         # So don't check return value
25143         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25144         cleanup_test411_cgroup $cgdir
25145
25146         return 0
25147 }
25148 run_test 411 "Slab allocation error with cgroup does not LBUG"
25149
25150 test_412() {
25151         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25152         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25153                 skip "Need server version at least 2.10.55"
25154
25155         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25156                 error "mkdir failed"
25157         $LFS getdirstripe $DIR/$tdir
25158         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25159         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25160                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25161         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25162         [ $stripe_count -eq 2 ] ||
25163                 error "expect 2 get $stripe_count"
25164
25165         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25166
25167         local index
25168         local index2
25169
25170         # subdirs should be on the same MDT as parent
25171         for i in $(seq 0 $((MDSCOUNT - 1))); do
25172                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25173                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25174                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25175                 (( index == i )) || error "mdt$i/sub on MDT$index"
25176         done
25177
25178         # stripe offset -1, ditto
25179         for i in {1..10}; do
25180                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25181                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25182                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25183                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25184                 (( index == index2 )) ||
25185                         error "qos$i on MDT$index, sub on MDT$index2"
25186         done
25187
25188         local testdir=$DIR/$tdir/inherit
25189
25190         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25191         # inherit 2 levels
25192         for i in 1 2; do
25193                 testdir=$testdir/s$i
25194                 mkdir $testdir || error "mkdir $testdir failed"
25195                 index=$($LFS getstripe -m $testdir)
25196                 (( index == 1 )) ||
25197                         error "$testdir on MDT$index"
25198         done
25199
25200         # not inherit any more
25201         testdir=$testdir/s3
25202         mkdir $testdir || error "mkdir $testdir failed"
25203         getfattr -d -m dmv $testdir | grep dmv &&
25204                 error "default LMV set on $testdir" || true
25205 }
25206 run_test 412 "mkdir on specific MDTs"
25207
25208 generate_uneven_mdts() {
25209         local threshold=$1
25210         local lmv_qos_maxage
25211         local lod_qos_maxage
25212         local ffree
25213         local bavail
25214         local max
25215         local min
25216         local max_index
25217         local min_index
25218         local tmp
25219         local i
25220
25221         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25222         $LCTL set_param lmv.*.qos_maxage=1
25223         stack_trap "$LCTL set_param \
25224                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25225         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25226                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25227         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25228                 lod.*.mdt_qos_maxage=1
25229         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25230                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25231
25232         echo
25233         echo "Check for uneven MDTs: "
25234
25235         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25236         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25237         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25238
25239         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25240         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25241         max_index=0
25242         min_index=0
25243         for ((i = 1; i < ${#ffree[@]}; i++)); do
25244                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25245                 if [ $tmp -gt $max ]; then
25246                         max=$tmp
25247                         max_index=$i
25248                 fi
25249                 if [ $tmp -lt $min ]; then
25250                         min=$tmp
25251                         min_index=$i
25252                 fi
25253         done
25254
25255         (( ${ffree[min_index]} > 0 )) ||
25256                 skip "no free files in MDT$min_index"
25257         (( ${ffree[min_index]} < 10000000 )) ||
25258                 skip "too many free files in MDT$min_index"
25259
25260         # Check if we need to generate uneven MDTs
25261         local diff=$(((max - min) * 100 / min))
25262         local testdir=$DIR/$tdir-fillmdt
25263         local start
25264
25265         mkdir -p $testdir
25266
25267         i=0
25268         while (( diff < threshold )); do
25269                 # generate uneven MDTs, create till $threshold% diff
25270                 echo -n "weight diff=$diff% must be > $threshold% ..."
25271                 echo "Fill MDT$min_index with 1000 files: loop $i"
25272                 testdir=$DIR/$tdir-fillmdt/$i
25273                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
25274                         error "mkdir $testdir failed"
25275                 $LFS setstripe -E 1M -L mdt $testdir ||
25276                         error "setstripe $testdir failed"
25277                 start=$SECONDS
25278                 for F in f.{0..999}; do
25279                         dd if=/dev/zero of=$testdir/$F bs=64K count=1 > \
25280                                 /dev/null 2>&1 || error "dd $F failed"
25281                 done
25282
25283                 # wait for QOS to update
25284                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25285
25286                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25287                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25288                 max=$(((${ffree[max_index]} >> 8) * \
25289                         (${bavail[max_index]} * bsize >> 16)))
25290                 min=$(((${ffree[min_index]} >> 8) * \
25291                         (${bavail[min_index]} * bsize >> 16)))
25292                 diff=$(((max - min) * 100 / min))
25293                 i=$((i + 1))
25294         done
25295
25296         echo "MDT filesfree available: ${ffree[@]}"
25297         echo "MDT blocks available: ${bavail[@]}"
25298         echo "weight diff=$diff%"
25299 }
25300
25301 test_qos_mkdir() {
25302         local mkdir_cmd=$1
25303         local stripe_count=$2
25304         local mdts=$(comma_list $(mdts_nodes))
25305
25306         local testdir
25307         local lmv_qos_prio_free
25308         local lmv_qos_threshold_rr
25309         local lmv_qos_maxage
25310         local lod_qos_prio_free
25311         local lod_qos_threshold_rr
25312         local lod_qos_maxage
25313         local count
25314         local i
25315
25316         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25317         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25318         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25319                 head -n1)
25320         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25321         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25322         stack_trap "$LCTL set_param \
25323                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25324         stack_trap "$LCTL set_param \
25325                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25326         stack_trap "$LCTL set_param \
25327                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25328
25329         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25330                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25331         lod_qos_prio_free=${lod_qos_prio_free%%%}
25332         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25333                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25334         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25335         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25336                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25337         stack_trap "do_nodes $mdts $LCTL set_param \
25338                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25339         stack_trap "do_nodes $mdts $LCTL set_param \
25340                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25341         stack_trap "do_nodes $mdts $LCTL set_param \
25342                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25343
25344         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25345         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25346
25347         testdir=$DIR/$tdir-s$stripe_count/rr
25348
25349         local stripe_index=$($LFS getstripe -m $testdir)
25350         local test_mkdir_rr=true
25351
25352         getfattr -d -m dmv -e hex $testdir | grep dmv
25353         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25354                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25355                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25356                         test_mkdir_rr=false
25357         fi
25358
25359         echo
25360         $test_mkdir_rr &&
25361                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25362                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25363
25364         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25365         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25366                 eval $mkdir_cmd $testdir/subdir$i ||
25367                         error "$mkdir_cmd subdir$i failed"
25368         done
25369
25370         for (( i = 0; i < $MDSCOUNT; i++ )); do
25371                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25372                 echo "$count directories created on MDT$i"
25373                 if $test_mkdir_rr; then
25374                         (( $count == 100 )) ||
25375                                 error "subdirs are not evenly distributed"
25376                 elif (( $i == $stripe_index )); then
25377                         (( $count == 100 * MDSCOUNT )) ||
25378                                 error "$count subdirs created on MDT$i"
25379                 else
25380                         (( $count == 0 )) ||
25381                                 error "$count subdirs created on MDT$i"
25382                 fi
25383
25384                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25385                         count=$($LFS getdirstripe $testdir/* |
25386                                 grep -c -P "^\s+$i\t")
25387                         echo "$count stripes created on MDT$i"
25388                         # deviation should < 5% of average
25389                         (( $count >= 95 * stripe_count &&
25390                            $count <= 105 * stripe_count)) ||
25391                                 error "stripes are not evenly distributed"
25392                 fi
25393         done
25394
25395         echo
25396         echo "Check for uneven MDTs: "
25397
25398         local ffree
25399         local bavail
25400         local max
25401         local min
25402         local max_index
25403         local min_index
25404         local tmp
25405
25406         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25407         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25408         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25409
25410         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25411         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25412         max_index=0
25413         min_index=0
25414         for ((i = 1; i < ${#ffree[@]}; i++)); do
25415                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25416                 if [ $tmp -gt $max ]; then
25417                         max=$tmp
25418                         max_index=$i
25419                 fi
25420                 if [ $tmp -lt $min ]; then
25421                         min=$tmp
25422                         min_index=$i
25423                 fi
25424         done
25425
25426         (( ${ffree[min_index]} > 0 )) ||
25427                 skip "no free files in MDT$min_index"
25428         (( ${ffree[min_index]} < 10000000 )) ||
25429                 skip "too many free files in MDT$min_index"
25430
25431         echo "MDT filesfree available: ${ffree[@]}"
25432         echo "MDT blocks available: ${bavail[@]}"
25433         echo "weight diff=$(((max - min) * 100 / min))%"
25434         echo
25435         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25436
25437         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25438         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25439         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25440         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25441         # decrease statfs age, so that it can be updated in time
25442         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25443         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25444
25445         sleep 1
25446
25447         testdir=$DIR/$tdir-s$stripe_count/qos
25448         local num=200
25449
25450         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25451         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25452                 eval $mkdir_cmd $testdir/subdir$i ||
25453                         error "$mkdir_cmd subdir$i failed"
25454         done
25455
25456         max=0
25457         for (( i = 0; i < $MDSCOUNT; i++ )); do
25458                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25459                 (( count > max )) && max=$count
25460                 echo "$count directories created on MDT$i"
25461         done
25462
25463         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25464
25465         # D-value should > 10% of averge
25466         (( max - min > num / 10 )) ||
25467                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25468
25469         # ditto for stripes
25470         if (( stripe_count > 1 )); then
25471                 max=0
25472                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25473                         count=$($LFS getdirstripe $testdir/* |
25474                                 grep -c -P "^\s+$i\t")
25475                         (( count > max )) && max=$count
25476                         echo "$count stripes created on MDT$i"
25477                 done
25478
25479                 min=$($LFS getdirstripe $testdir/* |
25480                         grep -c -P "^\s+$min_index\t")
25481                 (( max - min > num * stripe_count / 10 )) ||
25482                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25483         fi
25484 }
25485
25486 most_full_mdt() {
25487         local ffree
25488         local bavail
25489         local bsize
25490         local min
25491         local min_index
25492         local tmp
25493
25494         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25495         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25496         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25497
25498         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25499         min_index=0
25500         for ((i = 1; i < ${#ffree[@]}; i++)); do
25501                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25502                 (( tmp < min )) && min=$tmp && min_index=$i
25503         done
25504
25505         echo -n $min_index
25506 }
25507
25508 test_413a() {
25509         [ $MDSCOUNT -lt 2 ] &&
25510                 skip "We need at least 2 MDTs for this test"
25511
25512         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25513                 skip "Need server version at least 2.12.52"
25514
25515         local stripe_count
25516
25517         generate_uneven_mdts 100
25518         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25519                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25520                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25521                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25522                         error "mkdir failed"
25523                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25524         done
25525 }
25526 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25527
25528 test_413b() {
25529         [ $MDSCOUNT -lt 2 ] &&
25530                 skip "We need at least 2 MDTs for this test"
25531
25532         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25533                 skip "Need server version at least 2.12.52"
25534
25535         local testdir
25536         local stripe_count
25537
25538         generate_uneven_mdts 100
25539         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25540                 testdir=$DIR/$tdir-s$stripe_count
25541                 mkdir $testdir || error "mkdir $testdir failed"
25542                 mkdir $testdir/rr || error "mkdir rr failed"
25543                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25544                         error "mkdir qos failed"
25545                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25546                         $testdir/rr || error "setdirstripe rr failed"
25547                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25548                         error "setdirstripe failed"
25549                 test_qos_mkdir "mkdir" $stripe_count
25550         done
25551 }
25552 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25553
25554 test_413c() {
25555         (( $MDSCOUNT >= 2 )) ||
25556                 skip "We need at least 2 MDTs for this test"
25557
25558         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25559                 skip "Need server version at least 2.14.51"
25560
25561         local testdir
25562         local inherit
25563         local inherit_rr
25564
25565         testdir=$DIR/${tdir}-s1
25566         mkdir $testdir || error "mkdir $testdir failed"
25567         mkdir $testdir/rr || error "mkdir rr failed"
25568         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25569         # default max_inherit is -1, default max_inherit_rr is 0
25570         $LFS setdirstripe -D -c 1 $testdir/rr ||
25571                 error "setdirstripe rr failed"
25572         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25573                 error "setdirstripe qos failed"
25574         test_qos_mkdir "mkdir" 1
25575
25576         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25577         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25578         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25579         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25580         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25581
25582         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25583         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25584         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25585         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25586         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25587         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25588         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25589                 error "level2 shouldn't have default LMV" || true
25590 }
25591 run_test 413c "mkdir with default LMV max inherit rr"
25592
25593 test_413d() {
25594         (( MDSCOUNT >= 2 )) ||
25595                 skip "We need at least 2 MDTs for this test"
25596
25597         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25598                 skip "Need server version at least 2.14.51"
25599
25600         local lmv_qos_threshold_rr
25601
25602         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25603                 head -n1)
25604         stack_trap "$LCTL set_param \
25605                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
25606
25607         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25608         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25609         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
25610                 error "$tdir shouldn't have default LMV"
25611         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
25612                 error "mkdir sub failed"
25613
25614         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
25615
25616         (( count == 100 )) || error "$count subdirs on MDT0"
25617 }
25618 run_test 413d "inherit ROOT default LMV"
25619
25620 test_413e() {
25621         (( MDSCOUNT >= 2 )) ||
25622                 skip "We need at least 2 MDTs for this test"
25623         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25624                 skip "Need server version at least 2.14.55"
25625
25626         local testdir=$DIR/$tdir
25627         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
25628         local max_inherit
25629         local sub_max_inherit
25630
25631         mkdir -p $testdir || error "failed to create $testdir"
25632
25633         # set default max-inherit to -1 if stripe count is 0 or 1
25634         $LFS setdirstripe -D -c 1 $testdir ||
25635                 error "failed to set default LMV"
25636         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25637         (( max_inherit == -1 )) ||
25638                 error "wrong max_inherit value $max_inherit"
25639
25640         # set default max_inherit to a fixed value if stripe count is not 0 or 1
25641         $LFS setdirstripe -D -c -1 $testdir ||
25642                 error "failed to set default LMV"
25643         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25644         (( max_inherit > 0 )) ||
25645                 error "wrong max_inherit value $max_inherit"
25646
25647         # and the subdir will decrease the max_inherit by 1
25648         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
25649         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
25650         (( sub_max_inherit == max_inherit - 1)) ||
25651                 error "wrong max-inherit of subdir $sub_max_inherit"
25652
25653         # check specified --max-inherit and warning message
25654         stack_trap "rm -f $tmpfile"
25655         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
25656                 error "failed to set default LMV"
25657         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25658         (( max_inherit == -1 )) ||
25659                 error "wrong max_inherit value $max_inherit"
25660
25661         # check the warning messages
25662         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
25663                 error "failed to detect warning string"
25664         fi
25665 }
25666 run_test 413e "check default max-inherit value"
25667
25668 test_413z() {
25669         local pids=""
25670         local subdir
25671         local pid
25672
25673         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
25674                 unlinkmany $subdir/f. 1000 &
25675                 pids="$pids $!"
25676         done
25677
25678         for pid in $pids; do
25679                 wait $pid
25680         done
25681 }
25682 run_test 413z "413 test cleanup"
25683
25684 test_414() {
25685 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
25686         $LCTL set_param fail_loc=0x80000521
25687         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25688         rm -f $DIR/$tfile
25689 }
25690 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
25691
25692 test_415() {
25693         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25694         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25695                 skip "Need server version at least 2.11.52"
25696
25697         # LU-11102
25698         local total
25699         local setattr_pid
25700         local start_time
25701         local end_time
25702         local duration
25703
25704         total=500
25705         # this test may be slow on ZFS
25706         [ "$mds1_FSTYPE" == "zfs" ] && total=100
25707
25708         # though this test is designed for striped directory, let's test normal
25709         # directory too since lock is always saved as CoS lock.
25710         test_mkdir $DIR/$tdir || error "mkdir $tdir"
25711         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
25712
25713         (
25714                 while true; do
25715                         touch $DIR/$tdir
25716                 done
25717         ) &
25718         setattr_pid=$!
25719
25720         start_time=$(date +%s)
25721         for i in $(seq $total); do
25722                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
25723                         > /dev/null
25724         done
25725         end_time=$(date +%s)
25726         duration=$((end_time - start_time))
25727
25728         kill -9 $setattr_pid
25729
25730         echo "rename $total files took $duration sec"
25731         [ $duration -lt 100 ] || error "rename took $duration sec"
25732 }
25733 run_test 415 "lock revoke is not missing"
25734
25735 test_416() {
25736         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25737                 skip "Need server version at least 2.11.55"
25738
25739         # define OBD_FAIL_OSD_TXN_START    0x19a
25740         do_facet mds1 lctl set_param fail_loc=0x19a
25741
25742         lfs mkdir -c $MDSCOUNT $DIR/$tdir
25743
25744         true
25745 }
25746 run_test 416 "transaction start failure won't cause system hung"
25747
25748 cleanup_417() {
25749         trap 0
25750         do_nodes $(comma_list $(mdts_nodes)) \
25751                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
25752         do_nodes $(comma_list $(mdts_nodes)) \
25753                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
25754         do_nodes $(comma_list $(mdts_nodes)) \
25755                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
25756 }
25757
25758 test_417() {
25759         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25760         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
25761                 skip "Need MDS version at least 2.11.56"
25762
25763         trap cleanup_417 RETURN EXIT
25764
25765         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
25766         do_nodes $(comma_list $(mdts_nodes)) \
25767                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
25768         $LFS migrate -m 0 $DIR/$tdir.1 &&
25769                 error "migrate dir $tdir.1 should fail"
25770
25771         do_nodes $(comma_list $(mdts_nodes)) \
25772                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
25773         $LFS mkdir -i 1 $DIR/$tdir.2 &&
25774                 error "create remote dir $tdir.2 should fail"
25775
25776         do_nodes $(comma_list $(mdts_nodes)) \
25777                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
25778         $LFS mkdir -c 2 $DIR/$tdir.3 &&
25779                 error "create striped dir $tdir.3 should fail"
25780         true
25781 }
25782 run_test 417 "disable remote dir, striped dir and dir migration"
25783
25784 # Checks that the outputs of df [-i] and lfs df [-i] match
25785 #
25786 # usage: check_lfs_df <blocks | inodes> <mountpoint>
25787 check_lfs_df() {
25788         local dir=$2
25789         local inodes
25790         local df_out
25791         local lfs_df_out
25792         local count
25793         local passed=false
25794
25795         # blocks or inodes
25796         [ "$1" == "blocks" ] && inodes= || inodes="-i"
25797
25798         for count in {1..100}; do
25799                 do_nodes "$CLIENTS" \
25800                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25801                 sync; sleep 0.2
25802
25803                 # read the lines of interest
25804                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
25805                         error "df $inodes $dir | tail -n +2 failed"
25806                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
25807                         error "lfs df $inodes $dir | grep summary: failed"
25808
25809                 # skip first substrings of each output as they are different
25810                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
25811                 # compare the two outputs
25812                 passed=true
25813                 #  skip "available" on MDT until LU-13997 is fixed.
25814                 #for i in {1..5}; do
25815                 for i in 1 2 4 5; do
25816                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
25817                 done
25818                 $passed && break
25819         done
25820
25821         if ! $passed; then
25822                 df -P $inodes $dir
25823                 echo
25824                 lfs df $inodes $dir
25825                 error "df and lfs df $1 output mismatch: "      \
25826                       "df ${inodes}: ${df_out[*]}, "            \
25827                       "lfs df ${inodes}: ${lfs_df_out[*]}"
25828         fi
25829 }
25830
25831 test_418() {
25832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25833
25834         local dir=$DIR/$tdir
25835         local numfiles=$((RANDOM % 4096 + 2))
25836         local numblocks=$((RANDOM % 256 + 1))
25837
25838         wait_delete_completed
25839         test_mkdir $dir
25840
25841         # check block output
25842         check_lfs_df blocks $dir
25843         # check inode output
25844         check_lfs_df inodes $dir
25845
25846         # create a single file and retest
25847         echo "Creating a single file and testing"
25848         createmany -o $dir/$tfile- 1 &>/dev/null ||
25849                 error "creating 1 file in $dir failed"
25850         check_lfs_df blocks $dir
25851         check_lfs_df inodes $dir
25852
25853         # create a random number of files
25854         echo "Creating $((numfiles - 1)) files and testing"
25855         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
25856                 error "creating $((numfiles - 1)) files in $dir failed"
25857
25858         # write a random number of blocks to the first test file
25859         echo "Writing $numblocks 4K blocks and testing"
25860         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
25861                 count=$numblocks &>/dev/null ||
25862                 error "dd to $dir/${tfile}-0 failed"
25863
25864         # retest
25865         check_lfs_df blocks $dir
25866         check_lfs_df inodes $dir
25867
25868         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
25869                 error "unlinking $numfiles files in $dir failed"
25870 }
25871 run_test 418 "df and lfs df outputs match"
25872
25873 test_419()
25874 {
25875         local dir=$DIR/$tdir
25876
25877         mkdir -p $dir
25878         touch $dir/file
25879
25880         cancel_lru_locks mdc
25881
25882         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
25883         $LCTL set_param fail_loc=0x1410
25884         cat $dir/file
25885         $LCTL set_param fail_loc=0
25886         rm -rf $dir
25887 }
25888 run_test 419 "Verify open file by name doesn't crash kernel"
25889
25890 test_420()
25891 {
25892         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
25893                 skip "Need MDS version at least 2.12.53"
25894
25895         local SAVE_UMASK=$(umask)
25896         local dir=$DIR/$tdir
25897         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
25898
25899         mkdir -p $dir
25900         umask 0000
25901         mkdir -m03777 $dir/testdir
25902         ls -dn $dir/testdir
25903         # Need to remove trailing '.' when SELinux is enabled
25904         local dirperms=$(ls -dn $dir/testdir |
25905                          awk '{ sub(/\.$/, "", $1); print $1}')
25906         [ $dirperms == "drwxrwsrwt" ] ||
25907                 error "incorrect perms on $dir/testdir"
25908
25909         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
25910                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
25911         ls -n $dir/testdir/testfile
25912         local fileperms=$(ls -n $dir/testdir/testfile |
25913                           awk '{ sub(/\.$/, "", $1); print $1}')
25914         [ $fileperms == "-rwxr-xr-x" ] ||
25915                 error "incorrect perms on $dir/testdir/testfile"
25916
25917         umask $SAVE_UMASK
25918 }
25919 run_test 420 "clear SGID bit on non-directories for non-members"
25920
25921 test_421a() {
25922         local cnt
25923         local fid1
25924         local fid2
25925
25926         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25927                 skip "Need MDS version at least 2.12.54"
25928
25929         test_mkdir $DIR/$tdir
25930         createmany -o $DIR/$tdir/f 3
25931         cnt=$(ls -1 $DIR/$tdir | wc -l)
25932         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25933
25934         fid1=$(lfs path2fid $DIR/$tdir/f1)
25935         fid2=$(lfs path2fid $DIR/$tdir/f2)
25936         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
25937
25938         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
25939         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
25940
25941         cnt=$(ls -1 $DIR/$tdir | wc -l)
25942         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25943
25944         rm -f $DIR/$tdir/f3 || error "can't remove f3"
25945         createmany -o $DIR/$tdir/f 3
25946         cnt=$(ls -1 $DIR/$tdir | wc -l)
25947         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25948
25949         fid1=$(lfs path2fid $DIR/$tdir/f1)
25950         fid2=$(lfs path2fid $DIR/$tdir/f2)
25951         echo "remove using fsname $FSNAME"
25952         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
25953
25954         cnt=$(ls -1 $DIR/$tdir | wc -l)
25955         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25956 }
25957 run_test 421a "simple rm by fid"
25958
25959 test_421b() {
25960         local cnt
25961         local FID1
25962         local FID2
25963
25964         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25965                 skip "Need MDS version at least 2.12.54"
25966
25967         test_mkdir $DIR/$tdir
25968         createmany -o $DIR/$tdir/f 3
25969         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
25970         MULTIPID=$!
25971
25972         FID1=$(lfs path2fid $DIR/$tdir/f1)
25973         FID2=$(lfs path2fid $DIR/$tdir/f2)
25974         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
25975
25976         kill -USR1 $MULTIPID
25977         wait
25978
25979         cnt=$(ls $DIR/$tdir | wc -l)
25980         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
25981 }
25982 run_test 421b "rm by fid on open file"
25983
25984 test_421c() {
25985         local cnt
25986         local FIDS
25987
25988         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25989                 skip "Need MDS version at least 2.12.54"
25990
25991         test_mkdir $DIR/$tdir
25992         createmany -o $DIR/$tdir/f 3
25993         touch $DIR/$tdir/$tfile
25994         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
25995         cnt=$(ls -1 $DIR/$tdir | wc -l)
25996         [ $cnt != 184 ] && error "unexpected #files: $cnt"
25997
25998         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
25999         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26000
26001         cnt=$(ls $DIR/$tdir | wc -l)
26002         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26003 }
26004 run_test 421c "rm by fid against hardlinked files"
26005
26006 test_421d() {
26007         local cnt
26008         local FIDS
26009
26010         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26011                 skip "Need MDS version at least 2.12.54"
26012
26013         test_mkdir $DIR/$tdir
26014         createmany -o $DIR/$tdir/f 4097
26015         cnt=$(ls -1 $DIR/$tdir | wc -l)
26016         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26017
26018         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26019         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26020
26021         cnt=$(ls $DIR/$tdir | wc -l)
26022         rm -rf $DIR/$tdir
26023         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26024 }
26025 run_test 421d "rmfid en masse"
26026
26027 test_421e() {
26028         local cnt
26029         local FID
26030
26031         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26032         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26033                 skip "Need MDS version at least 2.12.54"
26034
26035         mkdir -p $DIR/$tdir
26036         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26037         createmany -o $DIR/$tdir/striped_dir/f 512
26038         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26039         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26040
26041         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26042                 sed "s/[/][^:]*://g")
26043         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26044
26045         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26046         rm -rf $DIR/$tdir
26047         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26048 }
26049 run_test 421e "rmfid in DNE"
26050
26051 test_421f() {
26052         local cnt
26053         local FID
26054
26055         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26056                 skip "Need MDS version at least 2.12.54"
26057
26058         test_mkdir $DIR/$tdir
26059         touch $DIR/$tdir/f
26060         cnt=$(ls -1 $DIR/$tdir | wc -l)
26061         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26062
26063         FID=$(lfs path2fid $DIR/$tdir/f)
26064         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26065         # rmfid should fail
26066         cnt=$(ls -1 $DIR/$tdir | wc -l)
26067         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26068
26069         chmod a+rw $DIR/$tdir
26070         ls -la $DIR/$tdir
26071         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26072         # rmfid should fail
26073         cnt=$(ls -1 $DIR/$tdir | wc -l)
26074         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26075
26076         rm -f $DIR/$tdir/f
26077         $RUNAS touch $DIR/$tdir/f
26078         FID=$(lfs path2fid $DIR/$tdir/f)
26079         echo "rmfid as root"
26080         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26081         cnt=$(ls -1 $DIR/$tdir | wc -l)
26082         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26083
26084         rm -f $DIR/$tdir/f
26085         $RUNAS touch $DIR/$tdir/f
26086         cnt=$(ls -1 $DIR/$tdir | wc -l)
26087         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26088         FID=$(lfs path2fid $DIR/$tdir/f)
26089         # rmfid w/o user_fid2path mount option should fail
26090         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26091         cnt=$(ls -1 $DIR/$tdir | wc -l)
26092         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26093
26094         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26095         stack_trap "rmdir $tmpdir"
26096         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26097                 error "failed to mount client'"
26098         stack_trap "umount_client $tmpdir"
26099
26100         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26101         # rmfid should succeed
26102         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26103         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26104
26105         # rmfid shouldn't allow to remove files due to dir's permission
26106         chmod a+rwx $tmpdir/$tdir
26107         touch $tmpdir/$tdir/f
26108         ls -la $tmpdir/$tdir
26109         FID=$(lfs path2fid $tmpdir/$tdir/f)
26110         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26111         return 0
26112 }
26113 run_test 421f "rmfid checks permissions"
26114
26115 test_421g() {
26116         local cnt
26117         local FIDS
26118
26119         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26120         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26121                 skip "Need MDS version at least 2.12.54"
26122
26123         mkdir -p $DIR/$tdir
26124         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26125         createmany -o $DIR/$tdir/striped_dir/f 512
26126         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26127         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26128
26129         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26130                 sed "s/[/][^:]*://g")
26131
26132         rm -f $DIR/$tdir/striped_dir/f1*
26133         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26134         removed=$((512 - cnt))
26135
26136         # few files have been just removed, so we expect
26137         # rmfid to fail on their fids
26138         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26139         [ $removed != $errors ] && error "$errors != $removed"
26140
26141         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26142         rm -rf $DIR/$tdir
26143         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26144 }
26145 run_test 421g "rmfid to return errors properly"
26146
26147 test_422() {
26148         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26149         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26150         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26151         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26152         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26153
26154         local amc=$(at_max_get client)
26155         local amo=$(at_max_get mds1)
26156         local timeout=`lctl get_param -n timeout`
26157
26158         at_max_set 0 client
26159         at_max_set 0 mds1
26160
26161 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26162         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26163                         fail_val=$(((2*timeout + 10)*1000))
26164         touch $DIR/$tdir/d3/file &
26165         sleep 2
26166 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26167         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26168                         fail_val=$((2*timeout + 5))
26169         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26170         local pid=$!
26171         sleep 1
26172         kill -9 $pid
26173         sleep $((2 * timeout))
26174         echo kill $pid
26175         kill -9 $pid
26176         lctl mark touch
26177         touch $DIR/$tdir/d2/file3
26178         touch $DIR/$tdir/d2/file4
26179         touch $DIR/$tdir/d2/file5
26180
26181         wait
26182         at_max_set $amc client
26183         at_max_set $amo mds1
26184
26185         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26186         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26187                 error "Watchdog is always throttled"
26188 }
26189 run_test 422 "kill a process with RPC in progress"
26190
26191 stat_test() {
26192     df -h $MOUNT &
26193     df -h $MOUNT &
26194     df -h $MOUNT &
26195     df -h $MOUNT &
26196     df -h $MOUNT &
26197     df -h $MOUNT &
26198 }
26199
26200 test_423() {
26201     local _stats
26202     # ensure statfs cache is expired
26203     sleep 2;
26204
26205     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26206     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26207
26208     return 0
26209 }
26210 run_test 423 "statfs should return a right data"
26211
26212 test_424() {
26213 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26214         $LCTL set_param fail_loc=0x80000522
26215         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26216         rm -f $DIR/$tfile
26217 }
26218 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26219
26220 test_425() {
26221         test_mkdir -c -1 $DIR/$tdir
26222         $LFS setstripe -c -1 $DIR/$tdir
26223
26224         lru_resize_disable "" 100
26225         stack_trap "lru_resize_enable" EXIT
26226
26227         sleep 5
26228
26229         for i in $(seq $((MDSCOUNT * 125))); do
26230                 local t=$DIR/$tdir/$tfile_$i
26231
26232                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26233                         error_noexit "Create file $t"
26234         done
26235         stack_trap "rm -rf $DIR/$tdir" EXIT
26236
26237         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26238                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26239                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26240
26241                 [ $lock_count -le $lru_size ] ||
26242                         error "osc lock count $lock_count > lru size $lru_size"
26243         done
26244
26245         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26246                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26247                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26248
26249                 [ $lock_count -le $lru_size ] ||
26250                         error "mdc lock count $lock_count > lru size $lru_size"
26251         done
26252 }
26253 run_test 425 "lock count should not exceed lru size"
26254
26255 test_426() {
26256         splice-test -r $DIR/$tfile
26257         splice-test -rd $DIR/$tfile
26258         splice-test $DIR/$tfile
26259         splice-test -d $DIR/$tfile
26260 }
26261 run_test 426 "splice test on Lustre"
26262
26263 test_427() {
26264         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26265         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26266                 skip "Need MDS version at least 2.12.4"
26267         local log
26268
26269         mkdir $DIR/$tdir
26270         mkdir $DIR/$tdir/1
26271         mkdir $DIR/$tdir/2
26272         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26273         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26274
26275         $LFS getdirstripe $DIR/$tdir/1/dir
26276
26277         #first setfattr for creating updatelog
26278         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26279
26280 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26281         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26282         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26283         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26284
26285         sleep 2
26286         fail mds2
26287         wait_recovery_complete mds2 $((2*TIMEOUT))
26288
26289         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26290         echo $log | grep "get update log failed" &&
26291                 error "update log corruption is detected" || true
26292 }
26293 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26294
26295 test_428() {
26296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26297         local cache_limit=$CACHE_MAX
26298
26299         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26300         $LCTL set_param -n llite.*.max_cached_mb=64
26301
26302         mkdir $DIR/$tdir
26303         $LFS setstripe -c 1 $DIR/$tdir
26304         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26305         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26306         #test write
26307         for f in $(seq 4); do
26308                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26309         done
26310         wait
26311
26312         cancel_lru_locks osc
26313         # Test read
26314         for f in $(seq 4); do
26315                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26316         done
26317         wait
26318 }
26319 run_test 428 "large block size IO should not hang"
26320
26321 test_429() { # LU-7915 / LU-10948
26322         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26323         local testfile=$DIR/$tfile
26324         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26325         local new_flag=1
26326         local first_rpc
26327         local second_rpc
26328         local third_rpc
26329
26330         $LCTL get_param $ll_opencache_threshold_count ||
26331                 skip "client does not have opencache parameter"
26332
26333         set_opencache $new_flag
26334         stack_trap "restore_opencache"
26335         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26336                 error "enable opencache failed"
26337         touch $testfile
26338         # drop MDC DLM locks
26339         cancel_lru_locks mdc
26340         # clear MDC RPC stats counters
26341         $LCTL set_param $mdc_rpcstats=clear
26342
26343         # According to the current implementation, we need to run 3 times
26344         # open & close file to verify if opencache is enabled correctly.
26345         # 1st, RPCs are sent for lookup/open and open handle is released on
26346         #      close finally.
26347         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26348         #      so open handle won't be released thereafter.
26349         # 3rd, No RPC is sent out.
26350         $MULTIOP $testfile oc || error "multiop failed"
26351         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26352         echo "1st: $first_rpc RPCs in flight"
26353
26354         $MULTIOP $testfile oc || error "multiop failed"
26355         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26356         echo "2nd: $second_rpc RPCs in flight"
26357
26358         $MULTIOP $testfile oc || error "multiop failed"
26359         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26360         echo "3rd: $third_rpc RPCs in flight"
26361
26362         #verify no MDC RPC is sent
26363         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26364 }
26365 run_test 429 "verify if opencache flag on client side does work"
26366
26367 lseek_test_430() {
26368         local offset
26369         local file=$1
26370
26371         # data at [200K, 400K)
26372         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26373                 error "256K->512K dd fails"
26374         # data at [2M, 3M)
26375         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26376                 error "2M->3M dd fails"
26377         # data at [4M, 5M)
26378         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26379                 error "4M->5M dd fails"
26380         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26381         # start at first component hole #1
26382         printf "Seeking hole from 1000 ... "
26383         offset=$(lseek_test -l 1000 $file)
26384         echo $offset
26385         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26386         printf "Seeking data from 1000 ... "
26387         offset=$(lseek_test -d 1000 $file)
26388         echo $offset
26389         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26390
26391         # start at first component data block
26392         printf "Seeking hole from 300000 ... "
26393         offset=$(lseek_test -l 300000 $file)
26394         echo $offset
26395         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26396         printf "Seeking data from 300000 ... "
26397         offset=$(lseek_test -d 300000 $file)
26398         echo $offset
26399         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26400
26401         # start at the first component but beyond end of object size
26402         printf "Seeking hole from 1000000 ... "
26403         offset=$(lseek_test -l 1000000 $file)
26404         echo $offset
26405         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26406         printf "Seeking data from 1000000 ... "
26407         offset=$(lseek_test -d 1000000 $file)
26408         echo $offset
26409         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26410
26411         # start at second component stripe 2 (empty file)
26412         printf "Seeking hole from 1500000 ... "
26413         offset=$(lseek_test -l 1500000 $file)
26414         echo $offset
26415         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26416         printf "Seeking data from 1500000 ... "
26417         offset=$(lseek_test -d 1500000 $file)
26418         echo $offset
26419         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26420
26421         # start at second component stripe 1 (all data)
26422         printf "Seeking hole from 3000000 ... "
26423         offset=$(lseek_test -l 3000000 $file)
26424         echo $offset
26425         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26426         printf "Seeking data from 3000000 ... "
26427         offset=$(lseek_test -d 3000000 $file)
26428         echo $offset
26429         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26430
26431         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26432                 error "2nd dd fails"
26433         echo "Add data block at 640K...1280K"
26434
26435         # start at before new data block, in hole
26436         printf "Seeking hole from 600000 ... "
26437         offset=$(lseek_test -l 600000 $file)
26438         echo $offset
26439         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26440         printf "Seeking data from 600000 ... "
26441         offset=$(lseek_test -d 600000 $file)
26442         echo $offset
26443         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26444
26445         # start at the first component new data block
26446         printf "Seeking hole from 1000000 ... "
26447         offset=$(lseek_test -l 1000000 $file)
26448         echo $offset
26449         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26450         printf "Seeking data from 1000000 ... "
26451         offset=$(lseek_test -d 1000000 $file)
26452         echo $offset
26453         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26454
26455         # start at second component stripe 2, new data
26456         printf "Seeking hole from 1200000 ... "
26457         offset=$(lseek_test -l 1200000 $file)
26458         echo $offset
26459         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26460         printf "Seeking data from 1200000 ... "
26461         offset=$(lseek_test -d 1200000 $file)
26462         echo $offset
26463         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
26464
26465         # start beyond file end
26466         printf "Using offset > filesize ... "
26467         lseek_test -l 4000000 $file && error "lseek should fail"
26468         printf "Using offset > filesize ... "
26469         lseek_test -d 4000000 $file && error "lseek should fail"
26470
26471         printf "Done\n\n"
26472 }
26473
26474 test_430a() {
26475         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
26476                 skip "MDT does not support SEEK_HOLE"
26477
26478         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26479                 skip "OST does not support SEEK_HOLE"
26480
26481         local file=$DIR/$tdir/$tfile
26482
26483         mkdir -p $DIR/$tdir
26484
26485         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
26486         # OST stripe #1 will have continuous data at [1M, 3M)
26487         # OST stripe #2 is empty
26488         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
26489         lseek_test_430 $file
26490         rm $file
26491         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
26492         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
26493         lseek_test_430 $file
26494         rm $file
26495         $LFS setstripe -c2 -S 512K $file
26496         echo "Two stripes, stripe size 512K"
26497         lseek_test_430 $file
26498         rm $file
26499         # FLR with stale mirror
26500         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
26501                        -N -c2 -S 1M $file
26502         echo "Mirrored file:"
26503         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
26504         echo "Plain 2 stripes 1M"
26505         lseek_test_430 $file
26506         rm $file
26507 }
26508 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
26509
26510 test_430b() {
26511         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26512                 skip "OST does not support SEEK_HOLE"
26513
26514         local offset
26515         local file=$DIR/$tdir/$tfile
26516
26517         mkdir -p $DIR/$tdir
26518         # Empty layout lseek should fail
26519         $MCREATE $file
26520         # seek from 0
26521         printf "Seeking hole from 0 ... "
26522         lseek_test -l 0 $file && error "lseek should fail"
26523         printf "Seeking data from 0 ... "
26524         lseek_test -d 0 $file && error "lseek should fail"
26525         rm $file
26526
26527         # 1M-hole file
26528         $LFS setstripe -E 1M -c2 -E eof $file
26529         $TRUNCATE $file 1048576
26530         printf "Seeking hole from 1000000 ... "
26531         offset=$(lseek_test -l 1000000 $file)
26532         echo $offset
26533         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26534         printf "Seeking data from 1000000 ... "
26535         lseek_test -d 1000000 $file && error "lseek should fail"
26536         rm $file
26537
26538         # full component followed by non-inited one
26539         $LFS setstripe -E 1M -c2 -E eof $file
26540         dd if=/dev/urandom of=$file bs=1M count=1
26541         printf "Seeking hole from 1000000 ... "
26542         offset=$(lseek_test -l 1000000 $file)
26543         echo $offset
26544         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26545         printf "Seeking hole from 1048576 ... "
26546         lseek_test -l 1048576 $file && error "lseek should fail"
26547         # init second component and truncate back
26548         echo "123" >> $file
26549         $TRUNCATE $file 1048576
26550         printf "Seeking hole from 1000000 ... "
26551         offset=$(lseek_test -l 1000000 $file)
26552         echo $offset
26553         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26554         printf "Seeking hole from 1048576 ... "
26555         lseek_test -l 1048576 $file && error "lseek should fail"
26556         # boundary checks for big values
26557         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
26558         offset=$(lseek_test -d 0 $file.10g)
26559         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
26560         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
26561         offset=$(lseek_test -d 0 $file.100g)
26562         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
26563         return 0
26564 }
26565 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
26566
26567 test_430c() {
26568         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26569                 skip "OST does not support SEEK_HOLE"
26570
26571         local file=$DIR/$tdir/$tfile
26572         local start
26573
26574         mkdir -p $DIR/$tdir
26575         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
26576
26577         # cp version 8.33+ prefers lseek over fiemap
26578         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
26579                 start=$SECONDS
26580                 time cp $file /dev/null
26581                 (( SECONDS - start < 5 )) ||
26582                         error "cp: too long runtime $((SECONDS - start))"
26583
26584         fi
26585         # tar version 1.29+ supports SEEK_HOLE/DATA
26586         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
26587                 start=$SECONDS
26588                 time tar cS $file - | cat > /dev/null
26589                 (( SECONDS - start < 5 )) ||
26590                         error "tar: too long runtime $((SECONDS - start))"
26591         fi
26592 }
26593 run_test 430c "lseek: external tools check"
26594
26595 test_431() { # LU-14187
26596         local file=$DIR/$tdir/$tfile
26597
26598         mkdir -p $DIR/$tdir
26599         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
26600         dd if=/dev/urandom of=$file bs=4k count=1
26601         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
26602         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
26603         #define OBD_FAIL_OST_RESTART_IO 0x251
26604         do_facet ost1 "$LCTL set_param fail_loc=0x251"
26605         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
26606         cp $file $file.0
26607         cancel_lru_locks
26608         sync_all_data
26609         echo 3 > /proc/sys/vm/drop_caches
26610         diff  $file $file.0 || error "data diff"
26611 }
26612 run_test 431 "Restart transaction for IO"
26613
26614 cleanup_test_432() {
26615         do_facet mgs $LCTL nodemap_activate 0
26616         wait_nm_sync active
26617 }
26618
26619 test_432() {
26620         local tmpdir=$TMP/dir432
26621
26622         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
26623                 skip "Need MDS version at least 2.14.52"
26624
26625         stack_trap cleanup_test_432 EXIT
26626         mkdir $DIR/$tdir
26627         mkdir $tmpdir
26628
26629         do_facet mgs $LCTL nodemap_activate 1
26630         wait_nm_sync active
26631         do_facet mgs $LCTL nodemap_modify --name default \
26632                 --property admin --value 1
26633         do_facet mgs $LCTL nodemap_modify --name default \
26634                 --property trusted --value 1
26635         cancel_lru_locks mdc
26636         wait_nm_sync default admin_nodemap
26637         wait_nm_sync default trusted_nodemap
26638
26639         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
26640                grep -ci "Operation not permitted") -ne 0 ]; then
26641                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
26642         fi
26643 }
26644 run_test 432 "mv dir from outside Lustre"
26645
26646 prep_801() {
26647         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26648         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26649                 skip "Need server version at least 2.9.55"
26650
26651         start_full_debug_logging
26652 }
26653
26654 post_801() {
26655         stop_full_debug_logging
26656 }
26657
26658 barrier_stat() {
26659         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26660                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26661                            awk '/The barrier for/ { print $7 }')
26662                 echo $st
26663         else
26664                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
26665                 echo \'$st\'
26666         fi
26667 }
26668
26669 barrier_expired() {
26670         local expired
26671
26672         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26673                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26674                           awk '/will be expired/ { print $7 }')
26675         else
26676                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
26677         fi
26678
26679         echo $expired
26680 }
26681
26682 test_801a() {
26683         prep_801
26684
26685         echo "Start barrier_freeze at: $(date)"
26686         #define OBD_FAIL_BARRIER_DELAY          0x2202
26687         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26688         # Do not reduce barrier time - See LU-11873
26689         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
26690
26691         sleep 2
26692         local b_status=$(barrier_stat)
26693         echo "Got barrier status at: $(date)"
26694         [ "$b_status" = "'freezing_p1'" ] ||
26695                 error "(1) unexpected barrier status $b_status"
26696
26697         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26698         wait
26699         b_status=$(barrier_stat)
26700         [ "$b_status" = "'frozen'" ] ||
26701                 error "(2) unexpected barrier status $b_status"
26702
26703         local expired=$(barrier_expired)
26704         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
26705         sleep $((expired + 3))
26706
26707         b_status=$(barrier_stat)
26708         [ "$b_status" = "'expired'" ] ||
26709                 error "(3) unexpected barrier status $b_status"
26710
26711         # Do not reduce barrier time - See LU-11873
26712         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
26713                 error "(4) fail to freeze barrier"
26714
26715         b_status=$(barrier_stat)
26716         [ "$b_status" = "'frozen'" ] ||
26717                 error "(5) unexpected barrier status $b_status"
26718
26719         echo "Start barrier_thaw at: $(date)"
26720         #define OBD_FAIL_BARRIER_DELAY          0x2202
26721         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26722         do_facet mgs $LCTL barrier_thaw $FSNAME &
26723
26724         sleep 2
26725         b_status=$(barrier_stat)
26726         echo "Got barrier status at: $(date)"
26727         [ "$b_status" = "'thawing'" ] ||
26728                 error "(6) unexpected barrier status $b_status"
26729
26730         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26731         wait
26732         b_status=$(barrier_stat)
26733         [ "$b_status" = "'thawed'" ] ||
26734                 error "(7) unexpected barrier status $b_status"
26735
26736         #define OBD_FAIL_BARRIER_FAILURE        0x2203
26737         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
26738         do_facet mgs $LCTL barrier_freeze $FSNAME
26739
26740         b_status=$(barrier_stat)
26741         [ "$b_status" = "'failed'" ] ||
26742                 error "(8) unexpected barrier status $b_status"
26743
26744         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
26745         do_facet mgs $LCTL barrier_thaw $FSNAME
26746
26747         post_801
26748 }
26749 run_test 801a "write barrier user interfaces and stat machine"
26750
26751 test_801b() {
26752         prep_801
26753
26754         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26755         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
26756         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
26757         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
26758         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
26759
26760         cancel_lru_locks mdc
26761
26762         # 180 seconds should be long enough
26763         do_facet mgs $LCTL barrier_freeze $FSNAME 180
26764
26765         local b_status=$(barrier_stat)
26766         [ "$b_status" = "'frozen'" ] ||
26767                 error "(6) unexpected barrier status $b_status"
26768
26769         mkdir $DIR/$tdir/d0/d10 &
26770         mkdir_pid=$!
26771
26772         touch $DIR/$tdir/d1/f13 &
26773         touch_pid=$!
26774
26775         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
26776         ln_pid=$!
26777
26778         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
26779         mv_pid=$!
26780
26781         rm -f $DIR/$tdir/d4/f12 &
26782         rm_pid=$!
26783
26784         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
26785
26786         # To guarantee taht the 'stat' is not blocked
26787         b_status=$(barrier_stat)
26788         [ "$b_status" = "'frozen'" ] ||
26789                 error "(8) unexpected barrier status $b_status"
26790
26791         # let above commands to run at background
26792         sleep 5
26793
26794         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
26795         ps -p $touch_pid || error "(10) touch should be blocked"
26796         ps -p $ln_pid || error "(11) link should be blocked"
26797         ps -p $mv_pid || error "(12) rename should be blocked"
26798         ps -p $rm_pid || error "(13) unlink should be blocked"
26799
26800         b_status=$(barrier_stat)
26801         [ "$b_status" = "'frozen'" ] ||
26802                 error "(14) unexpected barrier status $b_status"
26803
26804         do_facet mgs $LCTL barrier_thaw $FSNAME
26805         b_status=$(barrier_stat)
26806         [ "$b_status" = "'thawed'" ] ||
26807                 error "(15) unexpected barrier status $b_status"
26808
26809         wait $mkdir_pid || error "(16) mkdir should succeed"
26810         wait $touch_pid || error "(17) touch should succeed"
26811         wait $ln_pid || error "(18) link should succeed"
26812         wait $mv_pid || error "(19) rename should succeed"
26813         wait $rm_pid || error "(20) unlink should succeed"
26814
26815         post_801
26816 }
26817 run_test 801b "modification will be blocked by write barrier"
26818
26819 test_801c() {
26820         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26821
26822         prep_801
26823
26824         stop mds2 || error "(1) Fail to stop mds2"
26825
26826         do_facet mgs $LCTL barrier_freeze $FSNAME 30
26827
26828         local b_status=$(barrier_stat)
26829         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
26830                 do_facet mgs $LCTL barrier_thaw $FSNAME
26831                 error "(2) unexpected barrier status $b_status"
26832         }
26833
26834         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26835                 error "(3) Fail to rescan barrier bitmap"
26836
26837         # Do not reduce barrier time - See LU-11873
26838         do_facet mgs $LCTL barrier_freeze $FSNAME 20
26839
26840         b_status=$(barrier_stat)
26841         [ "$b_status" = "'frozen'" ] ||
26842                 error "(4) 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 "(5) unexpected barrier status $b_status"
26848
26849         local devname=$(mdsdevname 2)
26850
26851         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
26852
26853         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26854                 error "(7) Fail to rescan barrier bitmap"
26855
26856         post_801
26857 }
26858 run_test 801c "rescan barrier bitmap"
26859
26860 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
26861 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
26862 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
26863 saved_MOUNT_OPTS=$MOUNT_OPTS
26864
26865 cleanup_802a() {
26866         trap 0
26867
26868         stopall
26869         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
26870         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
26871         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
26872         MOUNT_OPTS=$saved_MOUNT_OPTS
26873         setupall
26874 }
26875
26876 test_802a() {
26877         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
26878         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26879         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26880                 skip "Need server version at least 2.9.55"
26881
26882         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
26883
26884         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26885
26886         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26887                 error "(2) Fail to copy"
26888
26889         trap cleanup_802a EXIT
26890
26891         # sync by force before remount as readonly
26892         sync; sync_all_data; sleep 3; sync_all_data
26893
26894         stopall
26895
26896         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
26897         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
26898         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
26899
26900         echo "Mount the server as read only"
26901         setupall server_only || error "(3) Fail to start servers"
26902
26903         echo "Mount client without ro should fail"
26904         mount_client $MOUNT &&
26905                 error "(4) Mount client without 'ro' should fail"
26906
26907         echo "Mount client with ro should succeed"
26908         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
26909         mount_client $MOUNT ||
26910                 error "(5) Mount client with 'ro' should succeed"
26911
26912         echo "Modify should be refused"
26913         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26914
26915         echo "Read should be allowed"
26916         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26917                 error "(7) Read should succeed under ro mode"
26918
26919         cleanup_802a
26920 }
26921 run_test 802a "simulate readonly device"
26922
26923 test_802b() {
26924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26925         remote_mds_nodsh && skip "remote MDS with nodsh"
26926
26927         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
26928                 skip "readonly option not available"
26929
26930         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
26931
26932         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26933                 error "(2) Fail to copy"
26934
26935         # write back all cached data before setting MDT to readonly
26936         cancel_lru_locks
26937         sync_all_data
26938
26939         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
26940         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
26941
26942         echo "Modify should be refused"
26943         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26944
26945         echo "Read should be allowed"
26946         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26947                 error "(7) Read should succeed under ro mode"
26948
26949         # disable readonly
26950         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
26951 }
26952 run_test 802b "be able to set MDTs to readonly"
26953
26954 test_803a() {
26955         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26956         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26957                 skip "MDS needs to be newer than 2.10.54"
26958
26959         mkdir_on_mdt0 $DIR/$tdir
26960         # Create some objects on all MDTs to trigger related logs objects
26961         for idx in $(seq $MDSCOUNT); do
26962                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
26963                         $DIR/$tdir/dir${idx} ||
26964                         error "Fail to create $DIR/$tdir/dir${idx}"
26965         done
26966
26967         sync; sleep 3
26968         wait_delete_completed # ensure old test cleanups are finished
26969         echo "before create:"
26970         $LFS df -i $MOUNT
26971         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26972
26973         for i in {1..10}; do
26974                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
26975                         error "Fail to create $DIR/$tdir/foo$i"
26976         done
26977
26978         sync; sleep 3
26979         echo "after create:"
26980         $LFS df -i $MOUNT
26981         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26982
26983         # allow for an llog to be cleaned up during the test
26984         [ $after_used -ge $((before_used + 10 - 1)) ] ||
26985                 error "before ($before_used) + 10 > after ($after_used)"
26986
26987         for i in {1..10}; do
26988                 rm -rf $DIR/$tdir/foo$i ||
26989                         error "Fail to remove $DIR/$tdir/foo$i"
26990         done
26991
26992         sleep 3 # avoid MDT return cached statfs
26993         wait_delete_completed
26994         echo "after unlink:"
26995         $LFS df -i $MOUNT
26996         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26997
26998         # allow for an llog to be created during the test
26999         [ $after_used -le $((before_used + 1)) ] ||
27000                 error "after ($after_used) > before ($before_used) + 1"
27001 }
27002 run_test 803a "verify agent object for remote object"
27003
27004 test_803b() {
27005         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27006         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27007                 skip "MDS needs to be newer than 2.13.56"
27008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27009
27010         for i in $(seq 0 $((MDSCOUNT - 1))); do
27011                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27012         done
27013
27014         local before=0
27015         local after=0
27016
27017         local tmp
27018
27019         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27020         for i in $(seq 0 $((MDSCOUNT - 1))); do
27021                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27022                         awk '/getattr/ { print $2 }')
27023                 before=$((before + tmp))
27024         done
27025         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27026         for i in $(seq 0 $((MDSCOUNT - 1))); do
27027                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27028                         awk '/getattr/ { print $2 }')
27029                 after=$((after + tmp))
27030         done
27031
27032         [ $before -eq $after ] || error "getattr count $before != $after"
27033 }
27034 run_test 803b "remote object can getattr from cache"
27035
27036 test_804() {
27037         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27038         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27039                 skip "MDS needs to be newer than 2.10.54"
27040         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27041
27042         mkdir -p $DIR/$tdir
27043         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27044                 error "Fail to create $DIR/$tdir/dir0"
27045
27046         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27047         local dev=$(mdsdevname 2)
27048
27049         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27050                 grep ${fid} || error "NOT found agent entry for dir0"
27051
27052         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27053                 error "Fail to create $DIR/$tdir/dir1"
27054
27055         touch $DIR/$tdir/dir1/foo0 ||
27056                 error "Fail to create $DIR/$tdir/dir1/foo0"
27057         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27058         local rc=0
27059
27060         for idx in $(seq $MDSCOUNT); do
27061                 dev=$(mdsdevname $idx)
27062                 do_facet mds${idx} \
27063                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27064                         grep ${fid} && rc=$idx
27065         done
27066
27067         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27068                 error "Fail to rename foo0 to foo1"
27069         if [ $rc -eq 0 ]; then
27070                 for idx in $(seq $MDSCOUNT); do
27071                         dev=$(mdsdevname $idx)
27072                         do_facet mds${idx} \
27073                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27074                         grep ${fid} && rc=$idx
27075                 done
27076         fi
27077
27078         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27079                 error "Fail to rename foo1 to foo2"
27080         if [ $rc -eq 0 ]; then
27081                 for idx in $(seq $MDSCOUNT); do
27082                         dev=$(mdsdevname $idx)
27083                         do_facet mds${idx} \
27084                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27085                         grep ${fid} && rc=$idx
27086                 done
27087         fi
27088
27089         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27090
27091         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27092                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27093         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27094                 error "Fail to rename foo2 to foo0"
27095         unlink $DIR/$tdir/dir1/foo0 ||
27096                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27097         rm -rf $DIR/$tdir/dir0 ||
27098                 error "Fail to rm $DIR/$tdir/dir0"
27099
27100         for idx in $(seq $MDSCOUNT); do
27101                 dev=$(mdsdevname $idx)
27102                 rc=0
27103
27104                 stop mds${idx}
27105                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27106                         rc=$?
27107                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27108                         error "mount mds$idx failed"
27109                 df $MOUNT > /dev/null 2>&1
27110
27111                 # e2fsck should not return error
27112                 [ $rc -eq 0 ] ||
27113                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27114         done
27115 }
27116 run_test 804 "verify agent entry for remote entry"
27117
27118 cleanup_805() {
27119         do_facet $SINGLEMDS zfs set quota=$old $fsset
27120         unlinkmany $DIR/$tdir/f- 1000000
27121         trap 0
27122 }
27123
27124 test_805() {
27125         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
27126         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
27127         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
27128                 skip "netfree not implemented before 0.7"
27129         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
27130                 skip "Need MDS version at least 2.10.57"
27131
27132         local fsset
27133         local freekb
27134         local usedkb
27135         local old
27136         local quota
27137         local pref="osd-zfs.$FSNAME-MDT0000."
27138
27139         # limit available space on MDS dataset to meet nospace issue
27140         # quickly. then ZFS 0.7.2 can use reserved space if asked
27141         # properly (using netfree flag in osd_declare_destroy()
27142         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
27143         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
27144                 gawk '{print $3}')
27145         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
27146         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
27147         let "usedkb=usedkb-freekb"
27148         let "freekb=freekb/2"
27149         if let "freekb > 5000"; then
27150                 let "freekb=5000"
27151         fi
27152         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
27153         trap cleanup_805 EXIT
27154         mkdir_on_mdt0 $DIR/$tdir
27155         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
27156                 error "Can't set PFL layout"
27157         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27158         rm -rf $DIR/$tdir || error "not able to remove"
27159         do_facet $SINGLEMDS zfs set quota=$old $fsset
27160         trap 0
27161 }
27162 run_test 805 "ZFS can remove from full fs"
27163
27164 # Size-on-MDS test
27165 check_lsom_data()
27166 {
27167         local file=$1
27168         local expect=$(stat -c %s $file)
27169
27170         check_lsom_size $1 $expect
27171
27172         local blocks=$($LFS getsom -b $file)
27173         expect=$(stat -c %b $file)
27174         [[ $blocks == $expect ]] ||
27175                 error "$file expected blocks: $expect, got: $blocks"
27176 }
27177
27178 check_lsom_size()
27179 {
27180         local size
27181         local expect=$2
27182
27183         cancel_lru_locks mdc
27184
27185         size=$($LFS getsom -s $1)
27186         [[ $size == $expect ]] ||
27187                 error "$file expected size: $expect, got: $size"
27188 }
27189
27190 test_806() {
27191         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27192                 skip "Need MDS version at least 2.11.52"
27193
27194         local bs=1048576
27195
27196         touch $DIR/$tfile || error "touch $tfile failed"
27197
27198         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27199         save_lustre_params client "llite.*.xattr_cache" > $save
27200         lctl set_param llite.*.xattr_cache=0
27201         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27202
27203         # single-threaded write
27204         echo "Test SOM for single-threaded write"
27205         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27206                 error "write $tfile failed"
27207         check_lsom_size $DIR/$tfile $bs
27208
27209         local num=32
27210         local size=$(($num * $bs))
27211         local offset=0
27212         local i
27213
27214         echo "Test SOM for single client multi-threaded($num) write"
27215         $TRUNCATE $DIR/$tfile 0
27216         for ((i = 0; i < $num; i++)); do
27217                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27218                 local pids[$i]=$!
27219                 offset=$((offset + $bs))
27220         done
27221         for (( i=0; i < $num; i++ )); do
27222                 wait ${pids[$i]}
27223         done
27224         check_lsom_size $DIR/$tfile $size
27225
27226         $TRUNCATE $DIR/$tfile 0
27227         for ((i = 0; i < $num; i++)); do
27228                 offset=$((offset - $bs))
27229                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27230                 local pids[$i]=$!
27231         done
27232         for (( i=0; i < $num; i++ )); do
27233                 wait ${pids[$i]}
27234         done
27235         check_lsom_size $DIR/$tfile $size
27236
27237         # multi-client writes
27238         num=$(get_node_count ${CLIENTS//,/ })
27239         size=$(($num * $bs))
27240         offset=0
27241         i=0
27242
27243         echo "Test SOM for multi-client ($num) writes"
27244         $TRUNCATE $DIR/$tfile 0
27245         for client in ${CLIENTS//,/ }; do
27246                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27247                 local pids[$i]=$!
27248                 i=$((i + 1))
27249                 offset=$((offset + $bs))
27250         done
27251         for (( i=0; i < $num; i++ )); do
27252                 wait ${pids[$i]}
27253         done
27254         check_lsom_size $DIR/$tfile $offset
27255
27256         i=0
27257         $TRUNCATE $DIR/$tfile 0
27258         for client in ${CLIENTS//,/ }; do
27259                 offset=$((offset - $bs))
27260                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27261                 local pids[$i]=$!
27262                 i=$((i + 1))
27263         done
27264         for (( i=0; i < $num; i++ )); do
27265                 wait ${pids[$i]}
27266         done
27267         check_lsom_size $DIR/$tfile $size
27268
27269         # verify truncate
27270         echo "Test SOM for truncate"
27271         $TRUNCATE $DIR/$tfile 1048576
27272         check_lsom_size $DIR/$tfile 1048576
27273         $TRUNCATE $DIR/$tfile 1234
27274         check_lsom_size $DIR/$tfile 1234
27275
27276         # verify SOM blocks count
27277         echo "Verify SOM block count"
27278         $TRUNCATE $DIR/$tfile 0
27279         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27280                 error "failed to write file $tfile"
27281         check_lsom_data $DIR/$tfile
27282 }
27283 run_test 806 "Verify Lazy Size on MDS"
27284
27285 test_807() {
27286         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27287         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27288                 skip "Need MDS version at least 2.11.52"
27289
27290         # Registration step
27291         changelog_register || error "changelog_register failed"
27292         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27293         changelog_users $SINGLEMDS | grep -q $cl_user ||
27294                 error "User $cl_user not found in changelog_users"
27295
27296         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27297         save_lustre_params client "llite.*.xattr_cache" > $save
27298         lctl set_param llite.*.xattr_cache=0
27299         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27300
27301         rm -rf $DIR/$tdir || error "rm $tdir failed"
27302         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27303         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27304         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27305         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27306                 error "truncate $tdir/trunc failed"
27307
27308         local bs=1048576
27309         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27310                 error "write $tfile failed"
27311
27312         # multi-client wirtes
27313         local num=$(get_node_count ${CLIENTS//,/ })
27314         local offset=0
27315         local i=0
27316
27317         echo "Test SOM for multi-client ($num) writes"
27318         touch $DIR/$tfile || error "touch $tfile failed"
27319         $TRUNCATE $DIR/$tfile 0
27320         for client in ${CLIENTS//,/ }; do
27321                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27322                 local pids[$i]=$!
27323                 i=$((i + 1))
27324                 offset=$((offset + $bs))
27325         done
27326         for (( i=0; i < $num; i++ )); do
27327                 wait ${pids[$i]}
27328         done
27329
27330         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27331         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27332         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27333         check_lsom_data $DIR/$tdir/trunc
27334         check_lsom_data $DIR/$tdir/single_dd
27335         check_lsom_data $DIR/$tfile
27336
27337         rm -rf $DIR/$tdir
27338         # Deregistration step
27339         changelog_deregister || error "changelog_deregister failed"
27340 }
27341 run_test 807 "verify LSOM syncing tool"
27342
27343 check_som_nologged()
27344 {
27345         local lines=$($LFS changelog $FSNAME-MDT0000 |
27346                 grep 'x=trusted.som' | wc -l)
27347         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27348 }
27349
27350 test_808() {
27351         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27352                 skip "Need MDS version at least 2.11.55"
27353
27354         # Registration step
27355         changelog_register || error "changelog_register failed"
27356
27357         touch $DIR/$tfile || error "touch $tfile failed"
27358         check_som_nologged
27359
27360         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27361                 error "write $tfile failed"
27362         check_som_nologged
27363
27364         $TRUNCATE $DIR/$tfile 1234
27365         check_som_nologged
27366
27367         $TRUNCATE $DIR/$tfile 1048576
27368         check_som_nologged
27369
27370         # Deregistration step
27371         changelog_deregister || error "changelog_deregister failed"
27372 }
27373 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27374
27375 check_som_nodata()
27376 {
27377         $LFS getsom $1
27378         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27379 }
27380
27381 test_809() {
27382         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27383                 skip "Need MDS version at least 2.11.56"
27384
27385         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27386                 error "failed to create DoM-only file $DIR/$tfile"
27387         touch $DIR/$tfile || error "touch $tfile failed"
27388         check_som_nodata $DIR/$tfile
27389
27390         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27391                 error "write $tfile failed"
27392         check_som_nodata $DIR/$tfile
27393
27394         $TRUNCATE $DIR/$tfile 1234
27395         check_som_nodata $DIR/$tfile
27396
27397         $TRUNCATE $DIR/$tfile 4097
27398         check_som_nodata $DIR/$file
27399 }
27400 run_test 809 "Verify no SOM xattr store for DoM-only files"
27401
27402 test_810() {
27403         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27404         $GSS && skip_env "could not run with gss"
27405         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27406                 skip "OST < 2.12.58 doesn't align checksum"
27407
27408         set_checksums 1
27409         stack_trap "set_checksums $ORIG_CSUM" EXIT
27410         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27411
27412         local csum
27413         local before
27414         local after
27415         for csum in $CKSUM_TYPES; do
27416                 #define OBD_FAIL_OSC_NO_GRANT   0x411
27417                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
27418                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
27419                         eval set -- $i
27420                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
27421                         before=$(md5sum $DIR/$tfile)
27422                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
27423                         after=$(md5sum $DIR/$tfile)
27424                         [ "$before" == "$after" ] ||
27425                                 error "$csum: $before != $after bs=$1 seek=$2"
27426                 done
27427         done
27428 }
27429 run_test 810 "partial page writes on ZFS (LU-11663)"
27430
27431 test_812a() {
27432         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27433                 skip "OST < 2.12.51 doesn't support this fail_loc"
27434
27435         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27436         # ensure ost1 is connected
27437         stat $DIR/$tfile >/dev/null || error "can't stat"
27438         wait_osc_import_state client ost1 FULL
27439         # no locks, no reqs to let the connection idle
27440         cancel_lru_locks osc
27441
27442         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27443 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27444         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27445         wait_osc_import_state client ost1 CONNECTING
27446         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27447
27448         stat $DIR/$tfile >/dev/null || error "can't stat file"
27449 }
27450 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
27451
27452 test_812b() { # LU-12378
27453         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27454                 skip "OST < 2.12.51 doesn't support this fail_loc"
27455
27456         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
27457         # ensure ost1 is connected
27458         stat $DIR/$tfile >/dev/null || error "can't stat"
27459         wait_osc_import_state client ost1 FULL
27460         # no locks, no reqs to let the connection idle
27461         cancel_lru_locks osc
27462
27463         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27464 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27465         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27466         wait_osc_import_state client ost1 CONNECTING
27467         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27468
27469         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
27470         wait_osc_import_state client ost1 IDLE
27471 }
27472 run_test 812b "do not drop no resend request for idle connect"
27473
27474 test_812c() {
27475         local old
27476
27477         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
27478
27479         $LFS setstripe -c 1 -o 0 $DIR/$tfile
27480         $LFS getstripe $DIR/$tfile
27481         $LCTL set_param osc.*.idle_timeout=10
27482         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
27483         # ensure ost1 is connected
27484         stat $DIR/$tfile >/dev/null || error "can't stat"
27485         wait_osc_import_state client ost1 FULL
27486         # no locks, no reqs to let the connection idle
27487         cancel_lru_locks osc
27488
27489 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
27490         $LCTL set_param fail_loc=0x80000533
27491         sleep 15
27492         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
27493 }
27494 run_test 812c "idle import vs lock enqueue race"
27495
27496 test_813() {
27497         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
27498         [ -z "$file_heat_sav" ] && skip "no file heat support"
27499
27500         local readsample
27501         local writesample
27502         local readbyte
27503         local writebyte
27504         local readsample1
27505         local writesample1
27506         local readbyte1
27507         local writebyte1
27508
27509         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
27510         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
27511
27512         $LCTL set_param -n llite.*.file_heat=1
27513         echo "Turn on file heat"
27514         echo "Period second: $period_second, Decay percentage: $decay_pct"
27515
27516         echo "QQQQ" > $DIR/$tfile
27517         echo "QQQQ" > $DIR/$tfile
27518         echo "QQQQ" > $DIR/$tfile
27519         cat $DIR/$tfile > /dev/null
27520         cat $DIR/$tfile > /dev/null
27521         cat $DIR/$tfile > /dev/null
27522         cat $DIR/$tfile > /dev/null
27523
27524         local out=$($LFS heat_get $DIR/$tfile)
27525
27526         $LFS heat_get $DIR/$tfile
27527         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27528         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27529         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27530         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27531
27532         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
27533         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
27534         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
27535         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
27536
27537         sleep $((period_second + 3))
27538         echo "Sleep $((period_second + 3)) seconds..."
27539         # The recursion formula to calculate the heat of the file f is as
27540         # follow:
27541         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
27542         # Where Hi is the heat value in the period between time points i*I and
27543         # (i+1)*I; Ci is the access count in the period; the symbol P refers
27544         # to the weight of Ci.
27545         out=$($LFS heat_get $DIR/$tfile)
27546         $LFS heat_get $DIR/$tfile
27547         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27548         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27549         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27550         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27551
27552         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
27553                 error "read sample ($readsample) is wrong"
27554         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
27555                 error "write sample ($writesample) is wrong"
27556         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
27557                 error "read bytes ($readbyte) is wrong"
27558         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
27559                 error "write bytes ($writebyte) is wrong"
27560
27561         echo "QQQQ" > $DIR/$tfile
27562         echo "QQQQ" > $DIR/$tfile
27563         echo "QQQQ" > $DIR/$tfile
27564         cat $DIR/$tfile > /dev/null
27565         cat $DIR/$tfile > /dev/null
27566         cat $DIR/$tfile > /dev/null
27567         cat $DIR/$tfile > /dev/null
27568
27569         sleep $((period_second + 3))
27570         echo "Sleep $((period_second + 3)) seconds..."
27571
27572         out=$($LFS heat_get $DIR/$tfile)
27573         $LFS heat_get $DIR/$tfile
27574         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27575         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27576         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27577         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27578
27579         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
27580                 4 * $decay_pct) / 100") -eq 1 ] ||
27581                 error "read sample ($readsample1) is wrong"
27582         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
27583                 3 * $decay_pct) / 100") -eq 1 ] ||
27584                 error "write sample ($writesample1) is wrong"
27585         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
27586                 20 * $decay_pct) / 100") -eq 1 ] ||
27587                 error "read bytes ($readbyte1) is wrong"
27588         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
27589                 15 * $decay_pct) / 100") -eq 1 ] ||
27590                 error "write bytes ($writebyte1) is wrong"
27591
27592         echo "Turn off file heat for the file $DIR/$tfile"
27593         $LFS heat_set -o $DIR/$tfile
27594
27595         echo "QQQQ" > $DIR/$tfile
27596         echo "QQQQ" > $DIR/$tfile
27597         echo "QQQQ" > $DIR/$tfile
27598         cat $DIR/$tfile > /dev/null
27599         cat $DIR/$tfile > /dev/null
27600         cat $DIR/$tfile > /dev/null
27601         cat $DIR/$tfile > /dev/null
27602
27603         out=$($LFS heat_get $DIR/$tfile)
27604         $LFS heat_get $DIR/$tfile
27605         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27606         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27607         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27608         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27609
27610         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27611         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27612         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27613         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27614
27615         echo "Trun on file heat for the file $DIR/$tfile"
27616         $LFS heat_set -O $DIR/$tfile
27617
27618         echo "QQQQ" > $DIR/$tfile
27619         echo "QQQQ" > $DIR/$tfile
27620         echo "QQQQ" > $DIR/$tfile
27621         cat $DIR/$tfile > /dev/null
27622         cat $DIR/$tfile > /dev/null
27623         cat $DIR/$tfile > /dev/null
27624         cat $DIR/$tfile > /dev/null
27625
27626         out=$($LFS heat_get $DIR/$tfile)
27627         $LFS heat_get $DIR/$tfile
27628         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27629         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27630         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27631         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27632
27633         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
27634         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
27635         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
27636         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
27637
27638         $LFS heat_set -c $DIR/$tfile
27639         $LCTL set_param -n llite.*.file_heat=0
27640         echo "Turn off file heat support for the Lustre filesystem"
27641
27642         echo "QQQQ" > $DIR/$tfile
27643         echo "QQQQ" > $DIR/$tfile
27644         echo "QQQQ" > $DIR/$tfile
27645         cat $DIR/$tfile > /dev/null
27646         cat $DIR/$tfile > /dev/null
27647         cat $DIR/$tfile > /dev/null
27648         cat $DIR/$tfile > /dev/null
27649
27650         out=$($LFS heat_get $DIR/$tfile)
27651         $LFS heat_get $DIR/$tfile
27652         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27653         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27654         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27655         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27656
27657         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27658         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27659         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27660         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27661
27662         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
27663         rm -f $DIR/$tfile
27664 }
27665 run_test 813 "File heat verfication"
27666
27667 test_814()
27668 {
27669         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
27670         echo -n y >> $DIR/$tfile
27671         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
27672         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
27673 }
27674 run_test 814 "sparse cp works as expected (LU-12361)"
27675
27676 test_815()
27677 {
27678         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
27679         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
27680 }
27681 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
27682
27683 test_816() {
27684         local ost1_imp=$(get_osc_import_name client ost1)
27685         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27686                          cut -d'.' -f2)
27687
27688         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27689         # ensure ost1 is connected
27690
27691         stat $DIR/$tfile >/dev/null || error "can't stat"
27692         wait_osc_import_state client ost1 FULL
27693         # no locks, no reqs to let the connection idle
27694         cancel_lru_locks osc
27695         lru_resize_disable osc
27696         local before
27697         local now
27698         before=$($LCTL get_param -n \
27699                  ldlm.namespaces.$imp_name.lru_size)
27700
27701         wait_osc_import_state client ost1 IDLE
27702         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
27703         now=$($LCTL get_param -n \
27704               ldlm.namespaces.$imp_name.lru_size)
27705         [ $before == $now ] || error "lru_size changed $before != $now"
27706 }
27707 run_test 816 "do not reset lru_resize on idle reconnect"
27708
27709 cleanup_817() {
27710         umount $tmpdir
27711         exportfs -u localhost:$DIR/nfsexp
27712         rm -rf $DIR/nfsexp
27713 }
27714
27715 test_817() {
27716         systemctl restart nfs-server.service || skip "failed to restart nfsd"
27717
27718         mkdir -p $DIR/nfsexp
27719         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
27720                 error "failed to export nfs"
27721
27722         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
27723         stack_trap cleanup_817 EXIT
27724
27725         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
27726                 error "failed to mount nfs to $tmpdir"
27727
27728         cp /bin/true $tmpdir
27729         $DIR/nfsexp/true || error "failed to execute 'true' command"
27730 }
27731 run_test 817 "nfsd won't cache write lock for exec file"
27732
27733 test_818() {
27734         test_mkdir -i0 -c1 $DIR/$tdir
27735         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
27736         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
27737         stop $SINGLEMDS
27738
27739         # restore osp-syn threads
27740         stack_trap "fail $SINGLEMDS"
27741
27742         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
27743         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
27744         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
27745                 error "start $SINGLEMDS failed"
27746         rm -rf $DIR/$tdir
27747
27748         local testid=$(echo $TESTNAME | tr '_' ' ')
27749
27750         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
27751                 grep "run LFSCK" || error "run LFSCK is not suggested"
27752 }
27753 run_test 818 "unlink with failed llog"
27754
27755 test_819a() {
27756         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27757         cancel_lru_locks osc
27758         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27759         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27760         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
27761         rm -f $TDIR/$tfile
27762 }
27763 run_test 819a "too big niobuf in read"
27764
27765 test_819b() {
27766         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27767         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27768         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27769         cancel_lru_locks osc
27770         sleep 1
27771         rm -f $TDIR/$tfile
27772 }
27773 run_test 819b "too big niobuf in write"
27774
27775
27776 function test_820_start_ost() {
27777         sleep 5
27778
27779         for num in $(seq $OSTCOUNT); do
27780                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
27781         done
27782 }
27783
27784 test_820() {
27785         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27786
27787         mkdir $DIR/$tdir
27788         umount_client $MOUNT || error "umount failed"
27789         for num in $(seq $OSTCOUNT); do
27790                 stop ost$num
27791         done
27792
27793         # mount client with no active OSTs
27794         # so that the client can't initialize max LOV EA size
27795         # from OSC notifications
27796         mount_client $MOUNT || error "mount failed"
27797         # delay OST starting to keep this 0 max EA size for a while
27798         test_820_start_ost &
27799
27800         # create a directory on MDS2
27801         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
27802                 error "Failed to create directory"
27803         # open intent should update default EA size
27804         # see mdc_update_max_ea_from_body()
27805         # notice this is the very first RPC to MDS2
27806         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
27807         ret=$?
27808         echo $out
27809         # With SSK, this situation can lead to -EPERM being returned.
27810         # In that case, simply retry.
27811         if [ $ret -ne 0 ] && $SHARED_KEY; then
27812                 if echo "$out" | grep -q "not permitted"; then
27813                         cp /etc/services $DIR/$tdir/mds2
27814                         ret=$?
27815                 fi
27816         fi
27817         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
27818 }
27819 run_test 820 "update max EA from open intent"
27820
27821 test_822() {
27822         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27823
27824         save_lustre_params mds1 \
27825                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27826         do_facet $SINGLEMDS "$LCTL set_param -n \
27827                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
27828         do_facet $SINGLEMDS "$LCTL set_param -n \
27829                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
27830
27831         # wait for statfs update to clear OS_STATFS_NOPRECREATE
27832         local maxage=$(do_facet mds1 $LCTL get_param -n \
27833                        osp.$FSNAME-OST0000*MDT0000.maxage)
27834         sleep $((maxage + 1))
27835
27836         #define OBD_FAIL_NET_ERROR_RPC          0x532
27837         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
27838
27839         stack_trap "restore_lustre_params < $p; rm $p"
27840
27841         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
27842                       osp.$FSNAME-OST0000*MDT0000.create_count")
27843         for i in $(seq 1 $count); do
27844                 touch $DIR/$tfile.${i} || error "touch failed"
27845         done
27846 }
27847 run_test 822 "test precreate failure"
27848
27849 test_823() {
27850         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27851         local OST_MAX_PRECREATE=20000
27852
27853         save_lustre_params mds1 \
27854                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27855         do_facet $SINGLEMDS "$LCTL set_param -n \
27856                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
27857         do_facet $SINGLEMDS "$LCTL set_param -n \
27858                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
27859
27860         stack_trap "restore_lustre_params < $p; rm $p"
27861
27862         do_facet $SINGLEMDS "$LCTL set_param -n \
27863                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
27864
27865         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27866                       osp.$FSNAME-OST0000*MDT0000.create_count")
27867         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27868                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
27869         local expect_count=$(((($max/2)/256) * 256))
27870
27871         log "setting create_count to 100200:"
27872         log " -result- count: $count with max: $max, expecting: $expect_count"
27873
27874         [[ $count -eq expect_count ]] ||
27875                 error "Create count not set to max precreate."
27876 }
27877 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
27878
27879 test_831() {
27880         local sync_changes=$(do_facet $SINGLEMDS \
27881                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
27882
27883         [ "$sync_changes" -gt 100 ] &&
27884                 skip "Sync changes $sync_changes > 100 already"
27885
27886         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27887
27888         $LFS mkdir -i 0 $DIR/$tdir
27889         $LFS setstripe -c 1 -i 0 $DIR/$tdir
27890
27891         save_lustre_params mds1 \
27892                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
27893         save_lustre_params mds1 \
27894                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
27895
27896         do_facet mds1 "$LCTL set_param -n \
27897                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
27898                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
27899         stack_trap "restore_lustre_params < $p" EXIT
27900
27901         createmany -o $DIR/$tdir/f- 1000
27902         unlinkmany $DIR/$tdir/f- 1000 &
27903         local UNLINK_PID=$!
27904
27905         while sleep 1; do
27906                 sync_changes=$(do_facet mds1 \
27907                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
27908                 # the check in the code is racy, fail the test
27909                 # if the value above the limit by 10.
27910                 [ $sync_changes -gt 110 ] && {
27911                         kill -2 $UNLINK_PID
27912                         wait
27913                         error "osp changes throttling failed, $sync_changes>110"
27914                 }
27915                 kill -0 $UNLINK_PID 2> /dev/null || break
27916         done
27917         wait
27918 }
27919 run_test 831 "throttling unlink/setattr queuing on OSP"
27920
27921 #
27922 # tests that do cleanup/setup should be run at the end
27923 #
27924
27925 test_900() {
27926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27927         local ls
27928
27929         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
27930         $LCTL set_param fail_loc=0x903
27931
27932         cancel_lru_locks MGC
27933
27934         FAIL_ON_ERROR=true cleanup
27935         FAIL_ON_ERROR=true setup
27936 }
27937 run_test 900 "umount should not race with any mgc requeue thread"
27938
27939 # LUS-6253/LU-11185
27940 test_901() {
27941         local oldc
27942         local newc
27943         local olds
27944         local news
27945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27946
27947         # some get_param have a bug to handle dot in param name
27948         cancel_lru_locks MGC
27949         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27950         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27951         umount_client $MOUNT || error "umount failed"
27952         mount_client $MOUNT || error "mount failed"
27953         cancel_lru_locks MGC
27954         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27955         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27956
27957         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
27958         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
27959
27960         return 0
27961 }
27962 run_test 901 "don't leak a mgc lock on client umount"
27963
27964 # LU-13377
27965 test_902() {
27966         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
27967                 skip "client does not have LU-13377 fix"
27968         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
27969         $LCTL set_param fail_loc=0x1415
27970         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27971         cancel_lru_locks osc
27972         rm -f $DIR/$tfile
27973 }
27974 run_test 902 "test short write doesn't hang lustre"
27975
27976 # LU-14711
27977 test_903() {
27978         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
27979         echo "blah" > $DIR/${tfile}-2
27980         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
27981         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
27982         $LCTL set_param fail_loc=0x417 fail_val=20
27983
27984         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
27985         sleep 1 # To start the destroy
27986         wait_destroy_complete 150 || error "Destroy taking too long"
27987         cat $DIR/$tfile > /dev/null || error "Evicted"
27988 }
27989 run_test 903 "Test long page discard does not cause evictions"
27990
27991 test_904() {
27992         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
27993         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
27994                 grep -q project || skip "skip project quota not supported"
27995
27996         local testfile="$DIR/$tdir/$tfile"
27997         local xattr="trusted.projid"
27998         local projid
27999
28000         mkdir -p $DIR/$tdir
28001         touch $testfile
28002         #should be hidden when projid is 0
28003         $LFS project -p 0 $testfile ||
28004                 error "set $testfile project id failed"
28005         getfattr -m - $testfile | grep $xattr &&
28006                 error "do not show trusted.projid with project ID 0"
28007
28008         #still can getxattr explicitly
28009         projid=$(getfattr -n $xattr $testfile |
28010                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28011         [ $projid == "0" ] ||
28012                 error "projid expected 0 not $projid"
28013
28014         #set the projid via setxattr
28015         setfattr -n $xattr -v "1000" $testfile ||
28016                 error "setattr failed with $?"
28017         projid=($($LFS project $testfile))
28018         [ ${projid[0]} == "1000" ] ||
28019                 error "projid expected 1000 not $projid"
28020
28021         #check the new projid via getxattr
28022         $LFS project -p 1001 $testfile ||
28023                 error "set $testfile project id failed"
28024         projid=$(getfattr -n $xattr $testfile |
28025                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28026         [ $projid == "1001" ] ||
28027                 error "projid expected 1001 not $projid"
28028
28029         #try to set invalid projid
28030         setfattr -n $xattr -v "4294967295" $testfile &&
28031                 error "set invalid projid should fail"
28032
28033         #remove the xattr means setting projid to 0
28034         setfattr -x $xattr $testfile ||
28035                 error "setfattr failed with $?"
28036         projid=($($LFS project $testfile))
28037         [ ${projid[0]} == "0" ] ||
28038                 error "projid expected 0 not $projid"
28039
28040         #should be hidden when parent has inherit flag and same projid
28041         $LFS project -srp 1002 $DIR/$tdir ||
28042                 error "set $tdir project id failed"
28043         getfattr -m - $testfile | grep $xattr &&
28044                 error "do not show trusted.projid with inherit flag"
28045
28046         #still can getxattr explicitly
28047         projid=$(getfattr -n $xattr $testfile |
28048                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28049         [ $projid == "1002" ] ||
28050                 error "projid expected 1002 not $projid"
28051 }
28052 run_test 904 "virtual project ID xattr"
28053
28054 complete $SECONDS
28055 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28056 check_and_cleanup_lustre
28057 if [ "$I_MOUNTED" != "yes" ]; then
28058         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28059 fi
28060 exit_status