Whamcloud - gitweb
LU-14651 llite: extend inode methods with user namespace arg
[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_25a() {
1504         echo '== symlink sanity ============================================='
1505
1506         test_mkdir $DIR/d25
1507         ln -s d25 $DIR/s25
1508         touch $DIR/s25/foo ||
1509                 error "File creation in symlinked directory failed"
1510 }
1511 run_test 25a "create file in symlinked directory ==============="
1512
1513 test_25b() {
1514         [ ! -d $DIR/d25 ] && test_25a
1515         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1516 }
1517 run_test 25b "lookup file in symlinked directory ==============="
1518
1519 test_26a() {
1520         test_mkdir $DIR/d26
1521         test_mkdir $DIR/d26/d26-2
1522         ln -s d26/d26-2 $DIR/s26
1523         touch $DIR/s26/foo || error "File creation failed"
1524 }
1525 run_test 26a "multiple component symlink ======================="
1526
1527 test_26b() {
1528         test_mkdir -p $DIR/$tdir/d26-2
1529         ln -s $tdir/d26-2/foo $DIR/s26-2
1530         touch $DIR/s26-2 || error "File creation failed"
1531 }
1532 run_test 26b "multiple component symlink at end of lookup ======"
1533
1534 test_26c() {
1535         test_mkdir $DIR/d26.2
1536         touch $DIR/d26.2/foo
1537         ln -s d26.2 $DIR/s26.2-1
1538         ln -s s26.2-1 $DIR/s26.2-2
1539         ln -s s26.2-2 $DIR/s26.2-3
1540         chmod 0666 $DIR/s26.2-3/foo
1541 }
1542 run_test 26c "chain of symlinks"
1543
1544 # recursive symlinks (bug 439)
1545 test_26d() {
1546         ln -s d26-3/foo $DIR/d26-3
1547 }
1548 run_test 26d "create multiple component recursive symlink"
1549
1550 test_26e() {
1551         [ ! -h $DIR/d26-3 ] && test_26d
1552         rm $DIR/d26-3
1553 }
1554 run_test 26e "unlink multiple component recursive symlink"
1555
1556 # recursive symlinks (bug 7022)
1557 test_26f() {
1558         test_mkdir $DIR/$tdir
1559         test_mkdir $DIR/$tdir/$tfile
1560         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1561         test_mkdir -p lndir/bar1
1562         test_mkdir $DIR/$tdir/$tfile/$tfile
1563         cd $tfile                || error "cd $tfile failed"
1564         ln -s .. dotdot          || error "ln dotdot failed"
1565         ln -s dotdot/lndir lndir || error "ln lndir failed"
1566         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1567         output=`ls $tfile/$tfile/lndir/bar1`
1568         [ "$output" = bar1 ] && error "unexpected output"
1569         rm -r $tfile             || error "rm $tfile failed"
1570         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1571 }
1572 run_test 26f "rm -r of a directory which has recursive symlink"
1573
1574 test_27a() {
1575         test_mkdir $DIR/$tdir
1576         $LFS getstripe $DIR/$tdir
1577         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1578         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1579         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1580 }
1581 run_test 27a "one stripe file"
1582
1583 test_27b() {
1584         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1585
1586         test_mkdir $DIR/$tdir
1587         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1588         $LFS getstripe -c $DIR/$tdir/$tfile
1589         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1590                 error "two-stripe file doesn't have two stripes"
1591
1592         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1593 }
1594 run_test 27b "create and write to two stripe file"
1595
1596 # 27c family tests specific striping, setstripe -o
1597 test_27ca() {
1598         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1599         test_mkdir -p $DIR/$tdir
1600         local osts="1"
1601
1602         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1603         $LFS getstripe -i $DIR/$tdir/$tfile
1604         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1605                 error "stripe not on specified OST"
1606
1607         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1608 }
1609 run_test 27ca "one stripe on specified OST"
1610
1611 test_27cb() {
1612         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1613         test_mkdir -p $DIR/$tdir
1614         local osts="1,0"
1615         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1616         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1617         echo "$getstripe"
1618
1619         # Strip getstripe output to a space separated list of OSTs
1620         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1621                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1622         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1623                 error "stripes not on specified OSTs"
1624
1625         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1626 }
1627 run_test 27cb "two stripes on specified OSTs"
1628
1629 test_27cc() {
1630         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1631         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1632                 skip "server does not support overstriping"
1633
1634         test_mkdir -p $DIR/$tdir
1635         local osts="0,0"
1636         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1637         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1638         echo "$getstripe"
1639
1640         # Strip getstripe output to a space separated list of OSTs
1641         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1642                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1643         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1644                 error "stripes not on specified OSTs"
1645
1646         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1647 }
1648 run_test 27cc "two stripes on the same OST"
1649
1650 test_27cd() {
1651         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1652         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1653                 skip "server does not support overstriping"
1654         test_mkdir -p $DIR/$tdir
1655         local osts="0,1,1,0"
1656         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1657         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1658         echo "$getstripe"
1659
1660         # Strip getstripe output to a space separated list of OSTs
1661         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1662                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1663         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1664                 error "stripes not on specified OSTs"
1665
1666         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1667 }
1668 run_test 27cd "four stripes on two OSTs"
1669
1670 test_27ce() {
1671         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1672                 skip_env "too many osts, skipping"
1673         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1674                 skip "server does not support overstriping"
1675         # We do one more stripe than we have OSTs
1676         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1677                 skip_env "ea_inode feature disabled"
1678
1679         test_mkdir -p $DIR/$tdir
1680         local osts=""
1681         for i in $(seq 0 $OSTCOUNT);
1682         do
1683                 osts=$osts"0"
1684                 if [ $i -ne $OSTCOUNT ]; then
1685                         osts=$osts","
1686                 fi
1687         done
1688         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1689         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1690         echo "$getstripe"
1691
1692         # Strip getstripe output to a space separated list of OSTs
1693         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1694                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1695         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1696                 error "stripes not on specified OSTs"
1697
1698         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1699 }
1700 run_test 27ce "more stripes than OSTs with -o"
1701
1702 test_27cf() {
1703         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1704         local pid=0
1705
1706         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1707         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1708         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1709         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1710                 error "failed to set $osp_proc=0"
1711
1712         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1713         pid=$!
1714         sleep 1
1715         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1716         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1717                 error "failed to set $osp_proc=1"
1718         wait $pid
1719         [[ $pid -ne 0 ]] ||
1720                 error "should return error due to $osp_proc=0"
1721 }
1722 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1723
1724 test_27d() {
1725         test_mkdir $DIR/$tdir
1726         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1727                 error "setstripe failed"
1728         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1729         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1730 }
1731 run_test 27d "create file with default settings"
1732
1733 test_27e() {
1734         # LU-5839 adds check for existed layout before setting it
1735         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1736                 skip "Need MDS version at least 2.7.56"
1737
1738         test_mkdir $DIR/$tdir
1739         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1740         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1741         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1742 }
1743 run_test 27e "setstripe existing file (should return error)"
1744
1745 test_27f() {
1746         test_mkdir $DIR/$tdir
1747         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1748                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1749         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1750                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1751         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1752         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1753 }
1754 run_test 27f "setstripe with bad stripe size (should return error)"
1755
1756 test_27g() {
1757         test_mkdir $DIR/$tdir
1758         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1759         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1760                 error "$DIR/$tdir/$tfile has object"
1761 }
1762 run_test 27g "$LFS getstripe with no objects"
1763
1764 test_27ga() {
1765         test_mkdir $DIR/$tdir
1766         touch $DIR/$tdir/$tfile || error "touch failed"
1767         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1768         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1769         local rc=$?
1770         (( rc == 2 )) || error "getstripe did not return ENOENT"
1771 }
1772 run_test 27ga "$LFS getstripe with missing file (should return error)"
1773
1774 test_27i() {
1775         test_mkdir $DIR/$tdir
1776         touch $DIR/$tdir/$tfile || error "touch failed"
1777         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1778                 error "missing objects"
1779 }
1780 run_test 27i "$LFS getstripe with some objects"
1781
1782 test_27j() {
1783         test_mkdir $DIR/$tdir
1784         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1785                 error "setstripe failed" || true
1786 }
1787 run_test 27j "setstripe with bad stripe offset (should return error)"
1788
1789 test_27k() { # bug 2844
1790         test_mkdir $DIR/$tdir
1791         local file=$DIR/$tdir/$tfile
1792         local ll_max_blksize=$((4 * 1024 * 1024))
1793         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1794         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1795         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1796         dd if=/dev/zero of=$file bs=4k count=1
1797         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1798         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1799 }
1800 run_test 27k "limit i_blksize for broken user apps"
1801
1802 test_27l() {
1803         mcreate $DIR/$tfile || error "creating file"
1804         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1805                 error "setstripe should have failed" || true
1806 }
1807 run_test 27l "check setstripe permissions (should return error)"
1808
1809 test_27m() {
1810         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1811
1812         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1813                 skip_env "multiple clients -- skipping"
1814
1815         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1816                    head -n1)
1817         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1818                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1819         fi
1820         stack_trap simple_cleanup_common
1821         test_mkdir $DIR/$tdir
1822         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1823         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1824                 error "dd should fill OST0"
1825         i=2
1826         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1827                 i=$((i + 1))
1828                 [ $i -gt 256 ] && break
1829         done
1830         i=$((i + 1))
1831         touch $DIR/$tdir/$tfile.$i
1832         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1833             awk '{print $1}'| grep -w "0") ] &&
1834                 error "OST0 was full but new created file still use it"
1835         i=$((i + 1))
1836         touch $DIR/$tdir/$tfile.$i
1837         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1838             awk '{print $1}'| grep -w "0") ] &&
1839                 error "OST0 was full but new created file still use it" || true
1840 }
1841 run_test 27m "create file while OST0 was full"
1842
1843 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1844 # if the OST isn't full anymore.
1845 reset_enospc() {
1846         local ostidx=${1:-""}
1847         local delay
1848         local ready
1849         local get_prealloc
1850
1851         local list=$(comma_list $(osts_nodes))
1852         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1853
1854         do_nodes $list lctl set_param fail_loc=0
1855         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1856         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1857                 awk '{print $1 * 2;exit;}')
1858         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1859                         grep -v \"^0$\""
1860         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1861 }
1862
1863 test_27n() {
1864         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1866         remote_mds_nodsh && skip "remote MDS with nodsh"
1867         remote_ost_nodsh && skip "remote OST with nodsh"
1868
1869         reset_enospc
1870         rm -f $DIR/$tdir/$tfile
1871         exhaust_precreations 0 0x80000215
1872         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1873         touch $DIR/$tdir/$tfile || error "touch failed"
1874         $LFS getstripe $DIR/$tdir/$tfile
1875         reset_enospc
1876 }
1877 run_test 27n "create file with some full OSTs"
1878
1879 test_27o() {
1880         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1882         remote_mds_nodsh && skip "remote MDS with nodsh"
1883         remote_ost_nodsh && skip "remote OST with nodsh"
1884
1885         reset_enospc
1886         rm -f $DIR/$tdir/$tfile
1887         exhaust_all_precreations 0x215
1888
1889         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1890
1891         reset_enospc
1892         rm -rf $DIR/$tdir/*
1893 }
1894 run_test 27o "create file with all full OSTs (should error)"
1895
1896 function create_and_checktime() {
1897         local fname=$1
1898         local loops=$2
1899         local i
1900
1901         for ((i=0; i < $loops; i++)); do
1902                 local start=$SECONDS
1903                 multiop $fname-$i Oc
1904                 ((SECONDS-start < TIMEOUT)) ||
1905                         error "creation took " $((SECONDS-$start)) && return 1
1906         done
1907 }
1908
1909 test_27oo() {
1910         local mdts=$(comma_list $(mdts_nodes))
1911
1912         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1913                 skip "Need MDS version at least 2.13.57"
1914
1915         local f0=$DIR/${tfile}-0
1916         local f1=$DIR/${tfile}-1
1917
1918         wait_delete_completed
1919
1920         # refill precreated objects
1921         $LFS setstripe -i0 -c1 $f0
1922
1923         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1924         # force QoS allocation policy
1925         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1926         stack_trap "do_nodes $mdts $LCTL set_param \
1927                 lov.*.qos_threshold_rr=$saved" EXIT
1928         sleep_maxage
1929
1930         # one OST is unavailable, but still have few objects preallocated
1931         stop ost1
1932         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1933                 rm -rf $f1 $DIR/$tdir*" EXIT
1934
1935         for ((i=0; i < 7; i++)); do
1936                 mkdir $DIR/$tdir$i || error "can't create dir"
1937                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1938                         error "can't set striping"
1939         done
1940         for ((i=0; i < 7; i++)); do
1941                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1942         done
1943         wait
1944 }
1945 run_test 27oo "don't let few threads to reserve too many objects"
1946
1947 test_27p() {
1948         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1950         remote_mds_nodsh && skip "remote MDS with nodsh"
1951         remote_ost_nodsh && skip "remote OST with nodsh"
1952
1953         reset_enospc
1954         rm -f $DIR/$tdir/$tfile
1955         test_mkdir $DIR/$tdir
1956
1957         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1958         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1959         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1960
1961         exhaust_precreations 0 0x80000215
1962         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1963         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1964         $LFS getstripe $DIR/$tdir/$tfile
1965
1966         reset_enospc
1967 }
1968 run_test 27p "append to a truncated file with some full OSTs"
1969
1970 test_27q() {
1971         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1973         remote_mds_nodsh && skip "remote MDS with nodsh"
1974         remote_ost_nodsh && skip "remote OST with nodsh"
1975
1976         reset_enospc
1977         rm -f $DIR/$tdir/$tfile
1978
1979         mkdir_on_mdt0 $DIR/$tdir
1980         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1981         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1982                 error "truncate $DIR/$tdir/$tfile failed"
1983         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1984
1985         exhaust_all_precreations 0x215
1986
1987         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1988         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1989
1990         reset_enospc
1991 }
1992 run_test 27q "append to truncated file with all OSTs full (should error)"
1993
1994 test_27r() {
1995         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1997         remote_mds_nodsh && skip "remote MDS with nodsh"
1998         remote_ost_nodsh && skip "remote OST with nodsh"
1999
2000         reset_enospc
2001         rm -f $DIR/$tdir/$tfile
2002         exhaust_precreations 0 0x80000215
2003
2004         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2005
2006         reset_enospc
2007 }
2008 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2009
2010 test_27s() { # bug 10725
2011         test_mkdir $DIR/$tdir
2012         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2013         local stripe_count=0
2014         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2015         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2016                 error "stripe width >= 2^32 succeeded" || true
2017
2018 }
2019 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2020
2021 test_27t() { # bug 10864
2022         WDIR=$(pwd)
2023         WLFS=$(which lfs)
2024         cd $DIR
2025         touch $tfile
2026         $WLFS getstripe $tfile
2027         cd $WDIR
2028 }
2029 run_test 27t "check that utils parse path correctly"
2030
2031 test_27u() { # bug 4900
2032         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2033         remote_mds_nodsh && skip "remote MDS with nodsh"
2034
2035         local index
2036         local list=$(comma_list $(mdts_nodes))
2037
2038 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2039         do_nodes $list $LCTL set_param fail_loc=0x139
2040         test_mkdir -p $DIR/$tdir
2041         stack_trap "simple_cleanup_common 1000"
2042         createmany -o $DIR/$tdir/$tfile 1000
2043         do_nodes $list $LCTL set_param fail_loc=0
2044
2045         TLOG=$TMP/$tfile.getstripe
2046         $LFS getstripe $DIR/$tdir > $TLOG
2047         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2048         [[ $OBJS -gt 0 ]] &&
2049                 error "$OBJS objects created on OST-0. See $TLOG" ||
2050                 rm -f $TLOG
2051 }
2052 run_test 27u "skip object creation on OSC w/o objects"
2053
2054 test_27v() { # bug 4900
2055         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2057         remote_mds_nodsh && skip "remote MDS with nodsh"
2058         remote_ost_nodsh && skip "remote OST with nodsh"
2059
2060         exhaust_all_precreations 0x215
2061         reset_enospc
2062
2063         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2064
2065         touch $DIR/$tdir/$tfile
2066         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2067         # all except ost1
2068         for (( i=1; i < OSTCOUNT; i++ )); do
2069                 do_facet ost$i lctl set_param fail_loc=0x705
2070         done
2071         local START=`date +%s`
2072         createmany -o $DIR/$tdir/$tfile 32
2073
2074         local FINISH=`date +%s`
2075         local TIMEOUT=`lctl get_param -n timeout`
2076         local PROCESS=$((FINISH - START))
2077         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2078                error "$FINISH - $START >= $TIMEOUT / 2"
2079         sleep $((TIMEOUT / 2 - PROCESS))
2080         reset_enospc
2081 }
2082 run_test 27v "skip object creation on slow OST"
2083
2084 test_27w() { # bug 10997
2085         test_mkdir $DIR/$tdir
2086         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2087         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2088                 error "stripe size $size != 65536" || true
2089         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2090                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2091 }
2092 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2093
2094 test_27wa() {
2095         [[ $OSTCOUNT -lt 2 ]] &&
2096                 skip_env "skipping multiple stripe count/offset test"
2097
2098         test_mkdir $DIR/$tdir
2099         for i in $(seq 1 $OSTCOUNT); do
2100                 offset=$((i - 1))
2101                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2102                         error "setstripe -c $i -i $offset failed"
2103                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2104                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2105                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2106                 [ $index -ne $offset ] &&
2107                         error "stripe offset $index != $offset" || true
2108         done
2109 }
2110 run_test 27wa "check $LFS setstripe -c -i options"
2111
2112 test_27x() {
2113         remote_ost_nodsh && skip "remote OST with nodsh"
2114         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2116
2117         OFFSET=$(($OSTCOUNT - 1))
2118         OSTIDX=0
2119         local OST=$(ostname_from_index $OSTIDX)
2120
2121         test_mkdir $DIR/$tdir
2122         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2123         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2124         sleep_maxage
2125         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2126         for i in $(seq 0 $OFFSET); do
2127                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2128                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2129                 error "OST0 was degraded but new created file still use it"
2130         done
2131         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2132 }
2133 run_test 27x "create files while OST0 is degraded"
2134
2135 test_27y() {
2136         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2137         remote_mds_nodsh && skip "remote MDS with nodsh"
2138         remote_ost_nodsh && skip "remote OST with nodsh"
2139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2140
2141         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2142         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2143                 osp.$mdtosc.prealloc_last_id)
2144         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2145                 osp.$mdtosc.prealloc_next_id)
2146         local fcount=$((last_id - next_id))
2147         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2148         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2149
2150         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2151                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2152         local OST_DEACTIVE_IDX=-1
2153         local OSC
2154         local OSTIDX
2155         local OST
2156
2157         for OSC in $MDS_OSCS; do
2158                 OST=$(osc_to_ost $OSC)
2159                 OSTIDX=$(index_from_ostuuid $OST)
2160                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2161                         OST_DEACTIVE_IDX=$OSTIDX
2162                 fi
2163                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2164                         echo $OSC "is Deactivated:"
2165                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2166                 fi
2167         done
2168
2169         OSTIDX=$(index_from_ostuuid $OST)
2170         test_mkdir $DIR/$tdir
2171         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2172
2173         for OSC in $MDS_OSCS; do
2174                 OST=$(osc_to_ost $OSC)
2175                 OSTIDX=$(index_from_ostuuid $OST)
2176                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2177                         echo $OST "is degraded:"
2178                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2179                                                 obdfilter.$OST.degraded=1
2180                 fi
2181         done
2182
2183         sleep_maxage
2184         createmany -o $DIR/$tdir/$tfile $fcount
2185
2186         for OSC in $MDS_OSCS; do
2187                 OST=$(osc_to_ost $OSC)
2188                 OSTIDX=$(index_from_ostuuid $OST)
2189                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2190                         echo $OST "is recovered from degraded:"
2191                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2192                                                 obdfilter.$OST.degraded=0
2193                 else
2194                         do_facet $SINGLEMDS lctl --device %$OSC activate
2195                 fi
2196         done
2197
2198         # all osp devices get activated, hence -1 stripe count restored
2199         local stripe_count=0
2200
2201         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2202         # devices get activated.
2203         sleep_maxage
2204         $LFS setstripe -c -1 $DIR/$tfile
2205         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2206         rm -f $DIR/$tfile
2207         [ $stripe_count -ne $OSTCOUNT ] &&
2208                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2209         return 0
2210 }
2211 run_test 27y "create files while OST0 is degraded and the rest inactive"
2212
2213 check_seq_oid()
2214 {
2215         log "check file $1"
2216
2217         lmm_count=$($LFS getstripe -c $1)
2218         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2219         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2220
2221         local old_ifs="$IFS"
2222         IFS=$'[:]'
2223         fid=($($LFS path2fid $1))
2224         IFS="$old_ifs"
2225
2226         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2227         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2228
2229         # compare lmm_seq and lu_fid->f_seq
2230         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2231         # compare lmm_object_id and lu_fid->oid
2232         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2233
2234         # check the trusted.fid attribute of the OST objects of the file
2235         local have_obdidx=false
2236         local stripe_nr=0
2237         $LFS getstripe $1 | while read obdidx oid hex seq; do
2238                 # skip lines up to and including "obdidx"
2239                 [ -z "$obdidx" ] && break
2240                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2241                 $have_obdidx || continue
2242
2243                 local ost=$((obdidx + 1))
2244                 local dev=$(ostdevname $ost)
2245                 local oid_hex
2246
2247                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2248
2249                 seq=$(echo $seq | sed -e "s/^0x//g")
2250                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2251                         oid_hex=$(echo $oid)
2252                 else
2253                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2254                 fi
2255                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2256
2257                 local ff=""
2258                 #
2259                 # Don't unmount/remount the OSTs if we don't need to do that.
2260                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2261                 # update too, until that use mount/ll_decode_filter_fid/mount.
2262                 # Re-enable when debugfs will understand new filter_fid.
2263                 #
2264                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2265                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2266                                 $dev 2>/dev/null" | grep "parent=")
2267                 fi
2268                 if [ -z "$ff" ]; then
2269                         stop ost$ost
2270                         mount_fstype ost$ost
2271                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2272                                 $(facet_mntpt ost$ost)/$obj_file)
2273                         unmount_fstype ost$ost
2274                         start ost$ost $dev $OST_MOUNT_OPTS
2275                         clients_up
2276                 fi
2277
2278                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2279
2280                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2281
2282                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2283                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2284                 #
2285                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2286                 #       stripe_size=1048576 component_id=1 component_start=0 \
2287                 #       component_end=33554432
2288                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2289                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2290                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2291                 local ff_pstripe
2292                 if grep -q 'stripe=' <<<$ff; then
2293                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2294                 else
2295                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2296                         # into f_ver in this case.  See comment on ff_parent.
2297                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2298                 fi
2299
2300                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2301                 [ $ff_pseq = $lmm_seq ] ||
2302                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2303                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2304                 [ $ff_poid = $lmm_oid ] ||
2305                         error "FF parent OID $ff_poid != $lmm_oid"
2306                 (($ff_pstripe == $stripe_nr)) ||
2307                         error "FF stripe $ff_pstripe != $stripe_nr"
2308
2309                 stripe_nr=$((stripe_nr + 1))
2310                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2311                         continue
2312                 if grep -q 'stripe_count=' <<<$ff; then
2313                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2314                                             -e 's/ .*//' <<<$ff)
2315                         [ $lmm_count = $ff_scnt ] ||
2316                                 error "FF stripe count $lmm_count != $ff_scnt"
2317                 fi
2318         done
2319 }
2320
2321 test_27z() {
2322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2323         remote_ost_nodsh && skip "remote OST with nodsh"
2324
2325         test_mkdir $DIR/$tdir
2326         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2327                 { error "setstripe -c -1 failed"; return 1; }
2328         # We need to send a write to every object to get parent FID info set.
2329         # This _should_ also work for setattr, but does not currently.
2330         # touch $DIR/$tdir/$tfile-1 ||
2331         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2332                 { error "dd $tfile-1 failed"; return 2; }
2333         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2334                 { error "setstripe -c -1 failed"; return 3; }
2335         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2336                 { error "dd $tfile-2 failed"; return 4; }
2337
2338         # make sure write RPCs have been sent to OSTs
2339         sync; sleep 5; sync
2340
2341         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2342         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2343 }
2344 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2345
2346 test_27A() { # b=19102
2347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2348
2349         save_layout_restore_at_exit $MOUNT
2350         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2351         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2352                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2353         local default_size=$($LFS getstripe -S $MOUNT)
2354         local default_offset=$($LFS getstripe -i $MOUNT)
2355         local dsize=$(do_facet $SINGLEMDS \
2356                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2357         [ $default_size -eq $dsize ] ||
2358                 error "stripe size $default_size != $dsize"
2359         [ $default_offset -eq -1 ] ||
2360                 error "stripe offset $default_offset != -1"
2361 }
2362 run_test 27A "check filesystem-wide default LOV EA values"
2363
2364 test_27B() { # LU-2523
2365         test_mkdir $DIR/$tdir
2366         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2367         touch $DIR/$tdir/f0
2368         # open f1 with O_LOV_DELAY_CREATE
2369         # rename f0 onto f1
2370         # call setstripe ioctl on open file descriptor for f1
2371         # close
2372         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2373                 $DIR/$tdir/f0
2374
2375         rm -f $DIR/$tdir/f1
2376         # open f1 with O_LOV_DELAY_CREATE
2377         # unlink f1
2378         # call setstripe ioctl on open file descriptor for f1
2379         # close
2380         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2381
2382         # Allow multiop to fail in imitation of NFS's busted semantics.
2383         true
2384 }
2385 run_test 27B "call setstripe on open unlinked file/rename victim"
2386
2387 # 27C family tests full striping and overstriping
2388 test_27Ca() { #LU-2871
2389         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2390
2391         declare -a ost_idx
2392         local index
2393         local found
2394         local i
2395         local j
2396
2397         test_mkdir $DIR/$tdir
2398         cd $DIR/$tdir
2399         for i in $(seq 0 $((OSTCOUNT - 1))); do
2400                 # set stripe across all OSTs starting from OST$i
2401                 $LFS setstripe -i $i -c -1 $tfile$i
2402                 # get striping information
2403                 ost_idx=($($LFS getstripe $tfile$i |
2404                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2405                 echo ${ost_idx[@]}
2406
2407                 # check the layout
2408                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2409                         error "${#ost_idx[@]} != $OSTCOUNT"
2410
2411                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2412                         found=0
2413                         for j in $(echo ${ost_idx[@]}); do
2414                                 if [ $index -eq $j ]; then
2415                                         found=1
2416                                         break
2417                                 fi
2418                         done
2419                         [ $found = 1 ] ||
2420                                 error "Can not find $index in ${ost_idx[@]}"
2421                 done
2422         done
2423 }
2424 run_test 27Ca "check full striping across all OSTs"
2425
2426 test_27Cb() {
2427         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2428                 skip "server does not support overstriping"
2429         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2430                 skip_env "too many osts, skipping"
2431
2432         test_mkdir -p $DIR/$tdir
2433         local setcount=$(($OSTCOUNT * 2))
2434         [ $setcount -lt 160 ] || large_xattr_enabled ||
2435                 skip_env "ea_inode feature disabled"
2436
2437         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2438                 error "setstripe failed"
2439
2440         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2441         [ $count -eq $setcount ] ||
2442                 error "stripe count $count, should be $setcount"
2443
2444         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2445                 error "overstriped should be set in pattern"
2446
2447         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2448                 error "dd failed"
2449 }
2450 run_test 27Cb "more stripes than OSTs with -C"
2451
2452 test_27Cc() {
2453         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2454                 skip "server does not support overstriping"
2455         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2456
2457         test_mkdir -p $DIR/$tdir
2458         local setcount=$(($OSTCOUNT - 1))
2459
2460         [ $setcount -lt 160 ] || large_xattr_enabled ||
2461                 skip_env "ea_inode feature disabled"
2462
2463         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2464                 error "setstripe failed"
2465
2466         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2467         [ $count -eq $setcount ] ||
2468                 error "stripe count $count, should be $setcount"
2469
2470         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2471                 error "overstriped should not be set in pattern"
2472
2473         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2474                 error "dd failed"
2475 }
2476 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2477
2478 test_27Cd() {
2479         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2480                 skip "server does not support overstriping"
2481         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2482         large_xattr_enabled || skip_env "ea_inode feature disabled"
2483
2484         test_mkdir -p $DIR/$tdir
2485         local setcount=$LOV_MAX_STRIPE_COUNT
2486
2487         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2488                 error "setstripe failed"
2489
2490         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2491         [ $count -eq $setcount ] ||
2492                 error "stripe count $count, should be $setcount"
2493
2494         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2495                 error "overstriped should be set in pattern"
2496
2497         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2498                 error "dd failed"
2499
2500         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2501 }
2502 run_test 27Cd "test maximum stripe count"
2503
2504 test_27Ce() {
2505         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2506                 skip "server does not support overstriping"
2507         test_mkdir -p $DIR/$tdir
2508
2509         pool_add $TESTNAME || error "Pool creation failed"
2510         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2511
2512         local setcount=8
2513
2514         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2515                 error "setstripe failed"
2516
2517         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2518         [ $count -eq $setcount ] ||
2519                 error "stripe count $count, should be $setcount"
2520
2521         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2522                 error "overstriped should be set in pattern"
2523
2524         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2525                 error "dd failed"
2526
2527         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2528 }
2529 run_test 27Ce "test pool with overstriping"
2530
2531 test_27Cf() {
2532         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2533                 skip "server does not support overstriping"
2534         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2535                 skip_env "too many osts, skipping"
2536
2537         test_mkdir -p $DIR/$tdir
2538
2539         local setcount=$(($OSTCOUNT * 2))
2540         [ $setcount -lt 160 ] || large_xattr_enabled ||
2541                 skip_env "ea_inode feature disabled"
2542
2543         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2544                 error "setstripe failed"
2545
2546         echo 1 > $DIR/$tdir/$tfile
2547
2548         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2549         [ $count -eq $setcount ] ||
2550                 error "stripe count $count, should be $setcount"
2551
2552         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2553                 error "overstriped should be set in pattern"
2554
2555         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2556                 error "dd failed"
2557
2558         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2559 }
2560 run_test 27Cf "test default inheritance with overstriping"
2561
2562 test_27D() {
2563         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2564         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2565         remote_mds_nodsh && skip "remote MDS with nodsh"
2566
2567         local POOL=${POOL:-testpool}
2568         local first_ost=0
2569         local last_ost=$(($OSTCOUNT - 1))
2570         local ost_step=1
2571         local ost_list=$(seq $first_ost $ost_step $last_ost)
2572         local ost_range="$first_ost $last_ost $ost_step"
2573
2574         test_mkdir $DIR/$tdir
2575         pool_add $POOL || error "pool_add failed"
2576         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2577
2578         local skip27D
2579         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2580                 skip27D+="-s 29"
2581         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2582                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2583                         skip27D+=" -s 30,31"
2584         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2585           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2586                 skip27D+=" -s 32,33"
2587         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2588                 skip27D+=" -s 34"
2589         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2590                 error "llapi_layout_test failed"
2591
2592         destroy_test_pools || error "destroy test pools failed"
2593 }
2594 run_test 27D "validate llapi_layout API"
2595
2596 # Verify that default_easize is increased from its initial value after
2597 # accessing a widely striped file.
2598 test_27E() {
2599         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2600         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2601                 skip "client does not have LU-3338 fix"
2602
2603         # 72 bytes is the minimum space required to store striping
2604         # information for a file striped across one OST:
2605         # (sizeof(struct lov_user_md_v3) +
2606         #  sizeof(struct lov_user_ost_data_v1))
2607         local min_easize=72
2608         $LCTL set_param -n llite.*.default_easize $min_easize ||
2609                 error "lctl set_param failed"
2610         local easize=$($LCTL get_param -n llite.*.default_easize)
2611
2612         [ $easize -eq $min_easize ] ||
2613                 error "failed to set default_easize"
2614
2615         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2616                 error "setstripe failed"
2617         # In order to ensure stat() call actually talks to MDS we need to
2618         # do something drastic to this file to shake off all lock, e.g.
2619         # rename it (kills lookup lock forcing cache cleaning)
2620         mv $DIR/$tfile $DIR/${tfile}-1
2621         ls -l $DIR/${tfile}-1
2622         rm $DIR/${tfile}-1
2623
2624         easize=$($LCTL get_param -n llite.*.default_easize)
2625
2626         [ $easize -gt $min_easize ] ||
2627                 error "default_easize not updated"
2628 }
2629 run_test 27E "check that default extended attribute size properly increases"
2630
2631 test_27F() { # LU-5346/LU-7975
2632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2633         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2634         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2635                 skip "Need MDS version at least 2.8.51"
2636         remote_ost_nodsh && skip "remote OST with nodsh"
2637
2638         test_mkdir $DIR/$tdir
2639         rm -f $DIR/$tdir/f0
2640         $LFS setstripe -c 2 $DIR/$tdir
2641
2642         # stop all OSTs to reproduce situation for LU-7975 ticket
2643         for num in $(seq $OSTCOUNT); do
2644                 stop ost$num
2645         done
2646
2647         # open/create f0 with O_LOV_DELAY_CREATE
2648         # truncate f0 to a non-0 size
2649         # close
2650         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2651
2652         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2653         # open/write it again to force delayed layout creation
2654         cat /etc/hosts > $DIR/$tdir/f0 &
2655         catpid=$!
2656
2657         # restart OSTs
2658         for num in $(seq $OSTCOUNT); do
2659                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2660                         error "ost$num failed to start"
2661         done
2662
2663         wait $catpid || error "cat failed"
2664
2665         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2666         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2667                 error "wrong stripecount"
2668
2669 }
2670 run_test 27F "Client resend delayed layout creation with non-zero size"
2671
2672 test_27G() { #LU-10629
2673         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2674                 skip "Need MDS version at least 2.11.51"
2675         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2676         remote_mds_nodsh && skip "remote MDS with nodsh"
2677         local POOL=${POOL:-testpool}
2678         local ostrange="0 0 1"
2679
2680         test_mkdir $DIR/$tdir
2681         touch $DIR/$tdir/$tfile.nopool
2682         pool_add $POOL || error "pool_add failed"
2683         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2684         $LFS setstripe -p $POOL $DIR/$tdir
2685
2686         local pool=$($LFS getstripe -p $DIR/$tdir)
2687
2688         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2689         touch $DIR/$tdir/$tfile.default
2690         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2691         $LFS find $DIR/$tdir -type f --pool $POOL
2692         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2693         [[ "$found" == "2" ]] ||
2694                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2695
2696         $LFS setstripe -d $DIR/$tdir
2697
2698         pool=$($LFS getstripe -p -d $DIR/$tdir)
2699
2700         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2701 }
2702 run_test 27G "Clear OST pool from stripe"
2703
2704 test_27H() {
2705         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2706                 skip "Need MDS version newer than 2.11.54"
2707         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2708         test_mkdir $DIR/$tdir
2709         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2710         touch $DIR/$tdir/$tfile
2711         $LFS getstripe -c $DIR/$tdir/$tfile
2712         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2713                 error "two-stripe file doesn't have two stripes"
2714
2715         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2716         $LFS getstripe -y $DIR/$tdir/$tfile
2717         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2718              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2719                 error "expected l_ost_idx: [02]$ not matched"
2720
2721         # make sure ost list has been cleared
2722         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2723         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2724                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2725         touch $DIR/$tdir/f3
2726         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2727 }
2728 run_test 27H "Set specific OSTs stripe"
2729
2730 test_27I() {
2731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2732         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2733         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2734                 skip "Need MDS version newer than 2.12.52"
2735         local pool=$TESTNAME
2736         local ostrange="1 1 1"
2737
2738         save_layout_restore_at_exit $MOUNT
2739         $LFS setstripe -c 2 -i 0 $MOUNT
2740         pool_add $pool || error "pool_add failed"
2741         pool_add_targets $pool $ostrange ||
2742                 error "pool_add_targets failed"
2743         test_mkdir $DIR/$tdir
2744         $LFS setstripe -p $pool $DIR/$tdir
2745         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2746         $LFS getstripe $DIR/$tdir/$tfile
2747 }
2748 run_test 27I "check that root dir striping does not break parent dir one"
2749
2750 test_27J() {
2751         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2752                 skip "Need MDS version newer than 2.12.51"
2753
2754         test_mkdir $DIR/$tdir
2755         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2756         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2757
2758         # create foreign file (raw way)
2759         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2760                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2761
2762         ! $LFS setstripe --foreign --flags foo \
2763                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2764                         error "creating $tfile with '--flags foo' should fail"
2765
2766         ! $LFS setstripe --foreign --flags 0xffffffff \
2767                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2768                         error "creating $tfile w/ 0xffffffff flags should fail"
2769
2770         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2771                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2772
2773         # verify foreign file (raw way)
2774         parse_foreign_file -f $DIR/$tdir/$tfile |
2775                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2776                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2777         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2778                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2779         parse_foreign_file -f $DIR/$tdir/$tfile |
2780                 grep "lov_foreign_size: 73" ||
2781                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2782         parse_foreign_file -f $DIR/$tdir/$tfile |
2783                 grep "lov_foreign_type: 1" ||
2784                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2785         parse_foreign_file -f $DIR/$tdir/$tfile |
2786                 grep "lov_foreign_flags: 0x0000DA08" ||
2787                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2788         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2789                 grep "lov_foreign_value: 0x" |
2790                 sed -e 's/lov_foreign_value: 0x//')
2791         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2792         [[ $lov = ${lov2// /} ]] ||
2793                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2794
2795         # create foreign file (lfs + API)
2796         $LFS setstripe --foreign=none --flags 0xda08 \
2797                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2798                 error "$DIR/$tdir/${tfile}2: create failed"
2799
2800         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2801                 grep "lfm_magic:.*0x0BD70BD0" ||
2802                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2803         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2804         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2805                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2806         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2807                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2808         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2809                 grep "lfm_flags:.*0x0000DA08" ||
2810                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2811         $LFS getstripe $DIR/$tdir/${tfile}2 |
2812                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2813                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2814
2815         # modify striping should fail
2816         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2817                 error "$DIR/$tdir/$tfile: setstripe should fail"
2818         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2819                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2820
2821         # R/W should fail
2822         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2823         cat $DIR/$tdir/${tfile}2 &&
2824                 error "$DIR/$tdir/${tfile}2: read should fail"
2825         cat /etc/passwd > $DIR/$tdir/$tfile &&
2826                 error "$DIR/$tdir/$tfile: write should fail"
2827         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2828                 error "$DIR/$tdir/${tfile}2: write should fail"
2829
2830         # chmod should work
2831         chmod 222 $DIR/$tdir/$tfile ||
2832                 error "$DIR/$tdir/$tfile: chmod failed"
2833         chmod 222 $DIR/$tdir/${tfile}2 ||
2834                 error "$DIR/$tdir/${tfile}2: chmod failed"
2835
2836         # chown should work
2837         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2838                 error "$DIR/$tdir/$tfile: chown failed"
2839         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2840                 error "$DIR/$tdir/${tfile}2: chown failed"
2841
2842         # rename should work
2843         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2844                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2845         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2846                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2847
2848         #remove foreign file
2849         rm $DIR/$tdir/${tfile}.new ||
2850                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2851         rm $DIR/$tdir/${tfile}2.new ||
2852                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2853 }
2854 run_test 27J "basic ops on file with foreign LOV"
2855
2856 test_27K() {
2857         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2858                 skip "Need MDS version newer than 2.12.49"
2859
2860         test_mkdir $DIR/$tdir
2861         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2862         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2863
2864         # create foreign dir (raw way)
2865         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2866                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2867
2868         ! $LFS setdirstripe --foreign --flags foo \
2869                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2870                         error "creating $tdir with '--flags foo' should fail"
2871
2872         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2873                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2874                         error "creating $tdir w/ 0xffffffff flags should fail"
2875
2876         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2877                 error "create_foreign_dir FAILED"
2878
2879         # verify foreign dir (raw way)
2880         parse_foreign_dir -d $DIR/$tdir/$tdir |
2881                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2882                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2883         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2884                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2885         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2886                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2887         parse_foreign_dir -d $DIR/$tdir/$tdir |
2888                 grep "lmv_foreign_flags: 55813$" ||
2889                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2890         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2891                 grep "lmv_foreign_value: 0x" |
2892                 sed 's/lmv_foreign_value: 0x//')
2893         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2894                 sed 's/ //g')
2895         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2896
2897         # create foreign dir (lfs + API)
2898         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2899                 $DIR/$tdir/${tdir}2 ||
2900                 error "$DIR/$tdir/${tdir}2: create failed"
2901
2902         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2903                 grep "lfm_magic:.*0x0CD50CD0" ||
2904                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2905         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2906         # - sizeof(lfm_type) - sizeof(lfm_flags)
2907         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2908                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2909         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2910                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2911         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2912                 grep "lfm_flags:.*0x0000DA05" ||
2913                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2914         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2915                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2916                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2917
2918         # file create in dir should fail
2919         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2920         touch $DIR/$tdir/${tdir}2/$tfile &&
2921                 error "$DIR/${tdir}2: file create should fail"
2922
2923         # chmod should work
2924         chmod 777 $DIR/$tdir/$tdir ||
2925                 error "$DIR/$tdir: chmod failed"
2926         chmod 777 $DIR/$tdir/${tdir}2 ||
2927                 error "$DIR/${tdir}2: chmod failed"
2928
2929         # chown should work
2930         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2931                 error "$DIR/$tdir: chown failed"
2932         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2933                 error "$DIR/${tdir}2: chown failed"
2934
2935         # rename should work
2936         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2937                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2938         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2939                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2940
2941         #remove foreign dir
2942         rmdir $DIR/$tdir/${tdir}.new ||
2943                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2944         rmdir $DIR/$tdir/${tdir}2.new ||
2945                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2946 }
2947 run_test 27K "basic ops on dir with foreign LMV"
2948
2949 test_27L() {
2950         remote_mds_nodsh && skip "remote MDS with nodsh"
2951
2952         local POOL=${POOL:-$TESTNAME}
2953
2954         pool_add $POOL || error "pool_add failed"
2955
2956         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2957                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2958                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2959 }
2960 run_test 27L "lfs pool_list gives correct pool name"
2961
2962 test_27M() {
2963         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2964                 skip "Need MDS version >= than 2.12.57"
2965         remote_mds_nodsh && skip "remote MDS with nodsh"
2966         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2967
2968         test_mkdir $DIR/$tdir
2969
2970         # Set default striping on directory
2971         local setcount=4
2972         local stripe_opt
2973
2974         # if we run against a 2.12 server which lacks overstring support
2975         # then the connect_flag will not report overstriping, even if client
2976         # is 2.14+
2977         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
2978                 stripe_opt="-C $setcount"
2979         elif (( $OSTCOUNT >= $setcount )); then
2980                 stripe_opt="-c $setcount"
2981         else
2982                 skip "server does not support overstriping"
2983         fi
2984         $LFS setstripe $stripe_opt $DIR/$tdir
2985
2986         echo 1 > $DIR/$tdir/${tfile}.1
2987         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2988         [ $count -eq $setcount ] ||
2989                 error "(1) stripe count $count, should be $setcount"
2990
2991         # Capture existing append_stripe_count setting for restore
2992         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2993         local mdts=$(comma_list $(mdts_nodes))
2994         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2995
2996         local appendcount=$orig_count
2997         echo 1 >> $DIR/$tdir/${tfile}.2_append
2998         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2999         [ $count -eq $appendcount ] ||
3000                 error "(2)stripe count $count, should be $appendcount for append"
3001
3002         # Disable O_APPEND striping, verify it works
3003         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3004
3005         # Should now get the default striping, which is 4
3006         setcount=4
3007         echo 1 >> $DIR/$tdir/${tfile}.3_append
3008         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3009         [ $count -eq $setcount ] ||
3010                 error "(3) stripe count $count, should be $setcount"
3011
3012         # Try changing the stripe count for append files
3013         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3014
3015         # Append striping is now 2 (directory default is still 4)
3016         appendcount=2
3017         echo 1 >> $DIR/$tdir/${tfile}.4_append
3018         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3019         [ $count -eq $appendcount ] ||
3020                 error "(4) stripe count $count, should be $appendcount for append"
3021
3022         # Test append stripe count of -1
3023         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3024         appendcount=$OSTCOUNT
3025         echo 1 >> $DIR/$tdir/${tfile}.5
3026         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3027         [ $count -eq $appendcount ] ||
3028                 error "(5) stripe count $count, should be $appendcount for append"
3029
3030         # Set append striping back to default of 1
3031         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3032
3033         # Try a new default striping, PFL + DOM
3034         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3035
3036         # Create normal DOM file, DOM returns stripe count == 0
3037         setcount=0
3038         touch $DIR/$tdir/${tfile}.6
3039         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3040         [ $count -eq $setcount ] ||
3041                 error "(6) stripe count $count, should be $setcount"
3042
3043         # Show
3044         appendcount=1
3045         echo 1 >> $DIR/$tdir/${tfile}.7_append
3046         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3047         [ $count -eq $appendcount ] ||
3048                 error "(7) stripe count $count, should be $appendcount for append"
3049
3050         # Clean up DOM layout
3051         $LFS setstripe -d $DIR/$tdir
3052
3053         save_layout_restore_at_exit $MOUNT
3054         # Now test that append striping works when layout is from root
3055         $LFS setstripe -c 2 $MOUNT
3056         # Make a special directory for this
3057         mkdir $DIR/${tdir}/${tdir}.2
3058
3059         # Verify for normal file
3060         setcount=2
3061         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3062         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3063         [ $count -eq $setcount ] ||
3064                 error "(8) stripe count $count, should be $setcount"
3065
3066         appendcount=1
3067         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3068         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3069         [ $count -eq $appendcount ] ||
3070                 error "(9) stripe count $count, should be $appendcount for append"
3071
3072         # Now test O_APPEND striping with pools
3073         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3074         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3075
3076         # Create the pool
3077         pool_add $TESTNAME || error "pool creation failed"
3078         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3079
3080         echo 1 >> $DIR/$tdir/${tfile}.10_append
3081
3082         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3083         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3084
3085         # Check that count is still correct
3086         appendcount=1
3087         echo 1 >> $DIR/$tdir/${tfile}.11_append
3088         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3089         [ $count -eq $appendcount ] ||
3090                 error "(11) stripe count $count, should be $appendcount for append"
3091
3092         # Disable O_APPEND stripe count, verify pool works separately
3093         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3094
3095         echo 1 >> $DIR/$tdir/${tfile}.12_append
3096
3097         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3098         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3099
3100         # Remove pool setting, verify it's not applied
3101         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3102
3103         echo 1 >> $DIR/$tdir/${tfile}.13_append
3104
3105         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3106         [ "$pool" = "" ] || error "(13) pool found: $pool"
3107 }
3108 run_test 27M "test O_APPEND striping"
3109
3110 test_27N() {
3111         combined_mgs_mds && skip "needs separate MGS/MDT"
3112
3113         pool_add $TESTNAME || error "pool_add failed"
3114         do_facet mgs "$LCTL pool_list $FSNAME" |
3115                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3116                 error "lctl pool_list on MGS failed"
3117 }
3118 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3119
3120 clean_foreign_symlink() {
3121         trap 0
3122         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3123         for i in $DIR/$tdir/* ; do
3124                 $LFS unlink_foreign $i || true
3125         done
3126 }
3127
3128 test_27O() {
3129         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3130                 skip "Need MDS version newer than 2.12.51"
3131
3132         test_mkdir $DIR/$tdir
3133         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3134         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3135
3136         trap clean_foreign_symlink EXIT
3137
3138         # enable foreign_symlink behaviour
3139         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3140
3141         # foreign symlink LOV format is a partial path by default
3142
3143         # create foreign file (lfs + API)
3144         $LFS setstripe --foreign=symlink --flags 0xda05 \
3145                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3146                 error "$DIR/$tdir/${tfile}: create failed"
3147
3148         $LFS getstripe -v $DIR/$tdir/${tfile} |
3149                 grep "lfm_magic:.*0x0BD70BD0" ||
3150                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3151         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3152                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3153         $LFS getstripe -v $DIR/$tdir/${tfile} |
3154                 grep "lfm_flags:.*0x0000DA05" ||
3155                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3156         $LFS getstripe $DIR/$tdir/${tfile} |
3157                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3158                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3159
3160         # modify striping should fail
3161         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3162                 error "$DIR/$tdir/$tfile: setstripe should fail"
3163
3164         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3165         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3166         cat /etc/passwd > $DIR/$tdir/$tfile &&
3167                 error "$DIR/$tdir/$tfile: write should fail"
3168
3169         # rename should succeed
3170         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3171                 error "$DIR/$tdir/$tfile: rename has failed"
3172
3173         #remove foreign_symlink file should fail
3174         rm $DIR/$tdir/${tfile}.new &&
3175                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3176
3177         #test fake symlink
3178         mkdir /tmp/${uuid1} ||
3179                 error "/tmp/${uuid1}: mkdir has failed"
3180         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3181                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3182         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3183         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3184                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3185         #read should succeed now
3186         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3187                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3188         #write should succeed now
3189         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3190                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3191         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3192                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3193         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3194                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3195
3196         #check that getstripe still works
3197         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3198                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3199
3200         # chmod should still succeed
3201         chmod 644 $DIR/$tdir/${tfile}.new ||
3202                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3203
3204         # chown should still succeed
3205         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3206                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3207
3208         # rename should still succeed
3209         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3210                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3211
3212         #remove foreign_symlink file should still fail
3213         rm $DIR/$tdir/${tfile} &&
3214                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3215
3216         #use special ioctl() to unlink foreign_symlink file
3217         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3218                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3219
3220 }
3221 run_test 27O "basic ops on foreign file of symlink type"
3222
3223 test_27P() {
3224         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3225                 skip "Need MDS version newer than 2.12.49"
3226
3227         test_mkdir $DIR/$tdir
3228         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3229         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3230
3231         trap clean_foreign_symlink EXIT
3232
3233         # enable foreign_symlink behaviour
3234         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3235
3236         # foreign symlink LMV format is a partial path by default
3237
3238         # create foreign dir (lfs + API)
3239         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3240                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3241                 error "$DIR/$tdir/${tdir}: create failed"
3242
3243         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3244                 grep "lfm_magic:.*0x0CD50CD0" ||
3245                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3246         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3247                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3248         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3249                 grep "lfm_flags:.*0x0000DA05" ||
3250                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3251         $LFS getdirstripe $DIR/$tdir/${tdir} |
3252                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3253                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3254
3255         # file create in dir should fail
3256         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3257         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3258
3259         # rename should succeed
3260         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3261                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3262
3263         #remove foreign_symlink dir should fail
3264         rmdir $DIR/$tdir/${tdir}.new &&
3265                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3266
3267         #test fake symlink
3268         mkdir -p /tmp/${uuid1}/${uuid2} ||
3269                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3270         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3271                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3272         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3273         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3274                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3275         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3276                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3277
3278         #check that getstripe fails now that foreign_symlink enabled
3279         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3280                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3281
3282         # file create in dir should work now
3283         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3284                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3285         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3286                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3287         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3288                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3289
3290         # chmod should still succeed
3291         chmod 755 $DIR/$tdir/${tdir}.new ||
3292                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3293
3294         # chown should still succeed
3295         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3296                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3297
3298         # rename should still succeed
3299         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3300                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3301
3302         #remove foreign_symlink dir should still fail
3303         rmdir $DIR/$tdir/${tdir} &&
3304                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3305
3306         #use special ioctl() to unlink foreign_symlink file
3307         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3308                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3309
3310         #created file should still exist
3311         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3312                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3313         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3314                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3315 }
3316 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3317
3318 test_27Q() {
3319         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3320         stack_trap "rm -f $TMP/$tfile*"
3321
3322         test_mkdir $DIR/$tdir-1
3323         test_mkdir $DIR/$tdir-2
3324
3325         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3326         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3327
3328         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3329         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3330
3331         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3332         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3333
3334         # Create some bad symlinks and ensure that we don't loop
3335         # forever or something. These should return ELOOP (40) and
3336         # ENOENT (2) but I don't want to test for that because there's
3337         # always some weirdo architecture that needs to ruin
3338         # everything by defining these error numbers differently.
3339
3340         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3341         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3342
3343         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3344         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3345
3346         return 0
3347 }
3348 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3349
3350 test_27R() {
3351         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3352                 skip "need MDS 2.14.55 or later"
3353         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3354
3355         local testdir="$DIR/$tdir"
3356         test_mkdir -p $testdir
3357         stack_trap "rm -rf $testdir"
3358         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3359
3360         local f1="$testdir/f1"
3361         touch $f1 || error "failed to touch $f1"
3362         local count=$($LFS getstripe -c $f1)
3363         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3364
3365         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3366         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3367
3368         local maxcount=$(($OSTCOUNT - 1))
3369         local mdts=$(comma_list $(mdts_nodes))
3370         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3371         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3372
3373         local f2="$testdir/f2"
3374         touch $f2 || error "failed to touch $f2"
3375         local count=$($LFS getstripe -c $f2)
3376         (( $count == $maxcount )) || error "wrong stripe count"
3377 }
3378 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3379
3380 test_27S() {
3381         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
3382                 skip "Need MDS version at least 2.14.54"
3383         [[ "$(facet_host mds1)" != "$(facet_host ost1)" ]] ||
3384                 skip "needs different host for mdt1 ost1"
3385
3386         local count=$(precreated_ost_obj_count 0 0)
3387
3388         echo "precreate count $count"
3389         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
3390         $LFS setstripe -i 0 -c 1 $DIR/$tdir || error "setstripe $tdir failed"
3391         #define OBD_FAIL_OSP_GET_LAST_FID       0x2109
3392         do_facet mds1 $LCTL set_param fail_loc=0x2109
3393         #define OBD_FAIL_OST_GET_LAST_FID       0x252
3394         do_facet ost1 $LCTL set_param fail_loc=0x252
3395         createmany -o $DIR/$tdir/f $count &
3396         pid=$!
3397         echo "precreate count $(precreated_ost_obj_count 0 0)"
3398         do_facet mds1 $LCTL set_param fail_loc=0
3399         do_facet ost1 $LCTL set_param fail_loc=0
3400         wait $pid || error "createmany failed"
3401         echo "precreate count $(precreated_ost_obj_count 0 0)"
3402 }
3403 run_test 27S "don't deactivate OSP on network issue"
3404
3405 # createtest also checks that device nodes are created and
3406 # then visible correctly (#2091)
3407 test_28() { # bug 2091
3408         test_mkdir $DIR/d28
3409         $CREATETEST $DIR/d28/ct || error "createtest failed"
3410 }
3411 run_test 28 "create/mknod/mkdir with bad file types ============"
3412
3413 test_29() {
3414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3415
3416         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3417                 disable_opencache
3418                 stack_trap "restore_opencache"
3419         }
3420
3421         sync; sleep 1; sync # flush out any dirty pages from previous tests
3422         cancel_lru_locks
3423         test_mkdir $DIR/d29
3424         touch $DIR/d29/foo
3425         log 'first d29'
3426         ls -l $DIR/d29
3427
3428         declare -i LOCKCOUNTORIG=0
3429         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3430                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3431         done
3432         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3433
3434         declare -i LOCKUNUSEDCOUNTORIG=0
3435         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3436                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3437         done
3438
3439         log 'second d29'
3440         ls -l $DIR/d29
3441         log 'done'
3442
3443         declare -i LOCKCOUNTCURRENT=0
3444         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3445                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3446         done
3447
3448         declare -i LOCKUNUSEDCOUNTCURRENT=0
3449         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3450                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3451         done
3452
3453         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3454                 $LCTL set_param -n ldlm.dump_namespaces ""
3455                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3456                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3457                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3458                 return 2
3459         fi
3460         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3461                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3462                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3463                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3464                 return 3
3465         fi
3466 }
3467 run_test 29 "IT_GETATTR regression  ============================"
3468
3469 test_30a() { # was test_30
3470         cp $(which ls) $DIR || cp /bin/ls $DIR
3471         $DIR/ls / || error "Can't execute binary from lustre"
3472         rm $DIR/ls
3473 }
3474 run_test 30a "execute binary from Lustre (execve) =============="
3475
3476 test_30b() {
3477         cp `which ls` $DIR || cp /bin/ls $DIR
3478         chmod go+rx $DIR/ls
3479         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3480         rm $DIR/ls
3481 }
3482 run_test 30b "execute binary from Lustre as non-root ==========="
3483
3484 test_30c() { # b=22376
3485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3486
3487         cp $(which ls) $DIR || cp /bin/ls $DIR
3488         chmod a-rw $DIR/ls
3489         cancel_lru_locks mdc
3490         cancel_lru_locks osc
3491         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3492         rm -f $DIR/ls
3493 }
3494 run_test 30c "execute binary from Lustre without read perms ===="
3495
3496 test_30d() {
3497         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3498
3499         for i in {1..10}; do
3500                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3501                 local PID=$!
3502                 sleep 1
3503                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3504                 wait $PID || error "executing dd from Lustre failed"
3505                 rm -f $DIR/$tfile
3506         done
3507
3508         rm -f $DIR/dd
3509 }
3510 run_test 30d "execute binary from Lustre while clear locks"
3511
3512 test_31a() {
3513         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3514         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3515 }
3516 run_test 31a "open-unlink file =================================="
3517
3518 test_31b() {
3519         touch $DIR/f31 || error "touch $DIR/f31 failed"
3520         ln $DIR/f31 $DIR/f31b || error "ln failed"
3521         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3522         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3523 }
3524 run_test 31b "unlink file with multiple links while open ======="
3525
3526 test_31c() {
3527         touch $DIR/f31 || error "touch $DIR/f31 failed"
3528         ln $DIR/f31 $DIR/f31c || error "ln failed"
3529         multiop_bg_pause $DIR/f31 O_uc ||
3530                 error "multiop_bg_pause for $DIR/f31 failed"
3531         MULTIPID=$!
3532         $MULTIOP $DIR/f31c Ouc
3533         kill -USR1 $MULTIPID
3534         wait $MULTIPID
3535 }
3536 run_test 31c "open-unlink file with multiple links ============="
3537
3538 test_31d() {
3539         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3540         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3541 }
3542 run_test 31d "remove of open directory ========================="
3543
3544 test_31e() { # bug 2904
3545         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3546 }
3547 run_test 31e "remove of open non-empty directory ==============="
3548
3549 test_31f() { # bug 4554
3550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3551
3552         set -vx
3553         test_mkdir $DIR/d31f
3554         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3555         cp /etc/hosts $DIR/d31f
3556         ls -l $DIR/d31f
3557         $LFS getstripe $DIR/d31f/hosts
3558         multiop_bg_pause $DIR/d31f D_c || return 1
3559         MULTIPID=$!
3560
3561         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3562         test_mkdir $DIR/d31f
3563         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3564         cp /etc/hosts $DIR/d31f
3565         ls -l $DIR/d31f
3566         $LFS getstripe $DIR/d31f/hosts
3567         multiop_bg_pause $DIR/d31f D_c || return 1
3568         MULTIPID2=$!
3569
3570         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3571         wait $MULTIPID || error "first opendir $MULTIPID failed"
3572
3573         sleep 6
3574
3575         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3576         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3577         set +vx
3578 }
3579 run_test 31f "remove of open directory with open-unlink file ==="
3580
3581 test_31g() {
3582         echo "-- cross directory link --"
3583         test_mkdir -c1 $DIR/${tdir}ga
3584         test_mkdir -c1 $DIR/${tdir}gb
3585         touch $DIR/${tdir}ga/f
3586         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3587         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3588         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3589         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3590         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3591 }
3592 run_test 31g "cross directory link==============="
3593
3594 test_31h() {
3595         echo "-- cross directory link --"
3596         test_mkdir -c1 $DIR/${tdir}
3597         test_mkdir -c1 $DIR/${tdir}/dir
3598         touch $DIR/${tdir}/f
3599         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3600         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3601         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3602         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3603         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3604 }
3605 run_test 31h "cross directory link under child==============="
3606
3607 test_31i() {
3608         echo "-- cross directory link --"
3609         test_mkdir -c1 $DIR/$tdir
3610         test_mkdir -c1 $DIR/$tdir/dir
3611         touch $DIR/$tdir/dir/f
3612         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3613         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3614         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3615         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3616         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3617 }
3618 run_test 31i "cross directory link under parent==============="
3619
3620 test_31j() {
3621         test_mkdir -c1 -p $DIR/$tdir
3622         test_mkdir -c1 -p $DIR/$tdir/dir1
3623         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3624         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3625         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3626         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3627         return 0
3628 }
3629 run_test 31j "link for directory==============="
3630
3631 test_31k() {
3632         test_mkdir -c1 -p $DIR/$tdir
3633         touch $DIR/$tdir/s
3634         touch $DIR/$tdir/exist
3635         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3636         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3637         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3638         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3639         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3640         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3641         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3642         return 0
3643 }
3644 run_test 31k "link to file: the same, non-existing, dir==============="
3645
3646 test_31m() {
3647         mkdir $DIR/d31m
3648         touch $DIR/d31m/s
3649         mkdir $DIR/d31m2
3650         touch $DIR/d31m2/exist
3651         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3652         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3653         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3654         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3655         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3656         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3657         return 0
3658 }
3659 run_test 31m "link to file: the same, non-existing, dir==============="
3660
3661 test_31n() {
3662         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3663         nlink=$(stat --format=%h $DIR/$tfile)
3664         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3665         local fd=$(free_fd)
3666         local cmd="exec $fd<$DIR/$tfile"
3667         eval $cmd
3668         cmd="exec $fd<&-"
3669         trap "eval $cmd" EXIT
3670         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3671         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3672         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3673         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3674         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3675         eval $cmd
3676 }
3677 run_test 31n "check link count of unlinked file"
3678
3679 link_one() {
3680         local tempfile=$(mktemp $1_XXXXXX)
3681         mlink $tempfile $1 2> /dev/null &&
3682                 echo "$BASHPID: link $tempfile to $1 succeeded"
3683         munlink $tempfile
3684 }
3685
3686 test_31o() { # LU-2901
3687         test_mkdir $DIR/$tdir
3688         for LOOP in $(seq 100); do
3689                 rm -f $DIR/$tdir/$tfile*
3690                 for THREAD in $(seq 8); do
3691                         link_one $DIR/$tdir/$tfile.$LOOP &
3692                 done
3693                 wait
3694                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3695                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3696                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3697                         break || true
3698         done
3699 }
3700 run_test 31o "duplicate hard links with same filename"
3701
3702 test_31p() {
3703         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3704
3705         test_mkdir $DIR/$tdir
3706         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3707         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3708
3709         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3710                 error "open unlink test1 failed"
3711         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3712                 error "open unlink test2 failed"
3713
3714         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3715                 error "test1 still exists"
3716         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3717                 error "test2 still exists"
3718 }
3719 run_test 31p "remove of open striped directory"
3720
3721 test_31q() {
3722         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3723
3724         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3725         index=$($LFS getdirstripe -i $DIR/$tdir)
3726         [ $index -eq 3 ] || error "first stripe index $index != 3"
3727         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3728         [ $index -eq 1 ] || error "second stripe index $index != 1"
3729
3730         # when "-c <stripe_count>" is set, the number of MDTs specified after
3731         # "-i" should equal to the stripe count
3732         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3733 }
3734 run_test 31q "create striped directory on specific MDTs"
3735
3736 #LU-14949
3737 test_31r() {
3738         touch $DIR/$tfile.target
3739         touch $DIR/$tfile.source
3740
3741         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3742         $LCTL set_param fail_loc=0x1419 fail_val=3
3743         cat $DIR/$tfile.target &
3744         CATPID=$!
3745
3746         # Guarantee open is waiting before we get here
3747         sleep 1
3748         mv $DIR/$tfile.source $DIR/$tfile.target
3749
3750         wait $CATPID
3751         RC=$?
3752         if [[ $RC -ne 0 ]]; then
3753                 error "open with cat failed, rc=$RC"
3754         fi
3755 }
3756 run_test 31r "open-rename(replace) race"
3757
3758 cleanup_test32_mount() {
3759         local rc=0
3760         trap 0
3761         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3762         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3763         losetup -d $loopdev || true
3764         rm -rf $DIR/$tdir
3765         return $rc
3766 }
3767
3768 test_32a() {
3769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3770
3771         echo "== more mountpoints and symlinks ================="
3772         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3773         trap cleanup_test32_mount EXIT
3774         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3775         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3776                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3777         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3778                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3779         cleanup_test32_mount
3780 }
3781 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3782
3783 test_32b() {
3784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3785
3786         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3787         trap cleanup_test32_mount EXIT
3788         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3789         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3790                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3791         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3792                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3793         cleanup_test32_mount
3794 }
3795 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3796
3797 test_32c() {
3798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3799
3800         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3801         trap cleanup_test32_mount EXIT
3802         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3803         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3804                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3805         test_mkdir -p $DIR/$tdir/d2/test_dir
3806         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3807                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3808         cleanup_test32_mount
3809 }
3810 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3811
3812 test_32d() {
3813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3814
3815         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3816         trap cleanup_test32_mount EXIT
3817         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3818         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3819                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3820         test_mkdir -p $DIR/$tdir/d2/test_dir
3821         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3822                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3823         cleanup_test32_mount
3824 }
3825 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3826
3827 test_32e() {
3828         rm -fr $DIR/$tdir
3829         test_mkdir -p $DIR/$tdir/tmp
3830         local tmp_dir=$DIR/$tdir/tmp
3831         ln -s $DIR/$tdir $tmp_dir/symlink11
3832         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3833         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3834         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3835 }
3836 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3837
3838 test_32f() {
3839         rm -fr $DIR/$tdir
3840         test_mkdir -p $DIR/$tdir/tmp
3841         local tmp_dir=$DIR/$tdir/tmp
3842         ln -s $DIR/$tdir $tmp_dir/symlink11
3843         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3844         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3845         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3846 }
3847 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3848
3849 test_32g() {
3850         local tmp_dir=$DIR/$tdir/tmp
3851         test_mkdir -p $tmp_dir
3852         test_mkdir $DIR/${tdir}2
3853         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3854         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3855         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3856         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3857         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3858         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3859 }
3860 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3861
3862 test_32h() {
3863         rm -fr $DIR/$tdir $DIR/${tdir}2
3864         tmp_dir=$DIR/$tdir/tmp
3865         test_mkdir -p $tmp_dir
3866         test_mkdir $DIR/${tdir}2
3867         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3868         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3869         ls $tmp_dir/symlink12 || error "listing symlink12"
3870         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3871 }
3872 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3873
3874 test_32i() {
3875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3876
3877         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3878         trap cleanup_test32_mount EXIT
3879         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3880         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3881                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3882         touch $DIR/$tdir/test_file
3883         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3884                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3885         cleanup_test32_mount
3886 }
3887 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3888
3889 test_32j() {
3890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3891
3892         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3893         trap cleanup_test32_mount EXIT
3894         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3895         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3896                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3897         touch $DIR/$tdir/test_file
3898         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3899                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3900         cleanup_test32_mount
3901 }
3902 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3903
3904 test_32k() {
3905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3906
3907         rm -fr $DIR/$tdir
3908         trap cleanup_test32_mount EXIT
3909         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3910         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3911                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3912         test_mkdir -p $DIR/$tdir/d2
3913         touch $DIR/$tdir/d2/test_file || error "touch failed"
3914         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3915                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3916         cleanup_test32_mount
3917 }
3918 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3919
3920 test_32l() {
3921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3922
3923         rm -fr $DIR/$tdir
3924         trap cleanup_test32_mount EXIT
3925         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3926         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3927                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3928         test_mkdir -p $DIR/$tdir/d2
3929         touch $DIR/$tdir/d2/test_file || error "touch failed"
3930         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3931                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3932         cleanup_test32_mount
3933 }
3934 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3935
3936 test_32m() {
3937         rm -fr $DIR/d32m
3938         test_mkdir -p $DIR/d32m/tmp
3939         TMP_DIR=$DIR/d32m/tmp
3940         ln -s $DIR $TMP_DIR/symlink11
3941         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3942         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3943                 error "symlink11 not a link"
3944         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3945                 error "symlink01 not a link"
3946 }
3947 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3948
3949 test_32n() {
3950         rm -fr $DIR/d32n
3951         test_mkdir -p $DIR/d32n/tmp
3952         TMP_DIR=$DIR/d32n/tmp
3953         ln -s $DIR $TMP_DIR/symlink11
3954         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3955         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3956         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3957 }
3958 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3959
3960 test_32o() {
3961         touch $DIR/$tfile
3962         test_mkdir -p $DIR/d32o/tmp
3963         TMP_DIR=$DIR/d32o/tmp
3964         ln -s $DIR/$tfile $TMP_DIR/symlink12
3965         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3966         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3967                 error "symlink12 not a link"
3968         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3969         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3970                 error "$DIR/d32o/tmp/symlink12 not file type"
3971         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3972                 error "$DIR/d32o/symlink02 not file type"
3973 }
3974 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3975
3976 test_32p() {
3977         log 32p_1
3978         rm -fr $DIR/d32p
3979         log 32p_2
3980         rm -f $DIR/$tfile
3981         log 32p_3
3982         touch $DIR/$tfile
3983         log 32p_4
3984         test_mkdir -p $DIR/d32p/tmp
3985         log 32p_5
3986         TMP_DIR=$DIR/d32p/tmp
3987         log 32p_6
3988         ln -s $DIR/$tfile $TMP_DIR/symlink12
3989         log 32p_7
3990         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3991         log 32p_8
3992         cat $DIR/d32p/tmp/symlink12 ||
3993                 error "Can't open $DIR/d32p/tmp/symlink12"
3994         log 32p_9
3995         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3996         log 32p_10
3997 }
3998 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3999
4000 test_32q() {
4001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4002
4003         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4004         trap cleanup_test32_mount EXIT
4005         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4006         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4007         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4008                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4009         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4010         cleanup_test32_mount
4011 }
4012 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4013
4014 test_32r() {
4015         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4016
4017         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4018         trap cleanup_test32_mount EXIT
4019         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4020         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4021         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4022                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4023         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4024         cleanup_test32_mount
4025 }
4026 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4027
4028 test_33aa() {
4029         rm -f $DIR/$tfile
4030         touch $DIR/$tfile
4031         chmod 444 $DIR/$tfile
4032         chown $RUNAS_ID $DIR/$tfile
4033         log 33_1
4034         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4035         log 33_2
4036 }
4037 run_test 33aa "write file with mode 444 (should return error)"
4038
4039 test_33a() {
4040         rm -fr $DIR/$tdir
4041         test_mkdir $DIR/$tdir
4042         chown $RUNAS_ID $DIR/$tdir
4043         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4044                 error "$RUNAS create $tdir/$tfile failed"
4045         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4046                 error "open RDWR" || true
4047 }
4048 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4049
4050 test_33b() {
4051         rm -fr $DIR/$tdir
4052         test_mkdir $DIR/$tdir
4053         chown $RUNAS_ID $DIR/$tdir
4054         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4055 }
4056 run_test 33b "test open file with malformed flags (No panic)"
4057
4058 test_33c() {
4059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4060         remote_ost_nodsh && skip "remote OST with nodsh"
4061
4062         local ostnum
4063         local ostname
4064         local write_bytes
4065         local all_zeros
4066
4067         all_zeros=true
4068         test_mkdir $DIR/$tdir
4069         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4070
4071         sync
4072         for ostnum in $(seq $OSTCOUNT); do
4073                 # test-framework's OST numbering is one-based, while Lustre's
4074                 # is zero-based
4075                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4076                 # check if at least some write_bytes stats are counted
4077                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4078                               obdfilter.$ostname.stats |
4079                               awk '/^write_bytes/ {print $7}' )
4080                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4081                 if (( ${write_bytes:-0} > 0 )); then
4082                         all_zeros=false
4083                         break
4084                 fi
4085         done
4086
4087         $all_zeros || return 0
4088
4089         # Write four bytes
4090         echo foo > $DIR/$tdir/bar
4091         # Really write them
4092         sync
4093
4094         # Total up write_bytes after writing.  We'd better find non-zeros.
4095         for ostnum in $(seq $OSTCOUNT); do
4096                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4097                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4098                               obdfilter/$ostname/stats |
4099                               awk '/^write_bytes/ {print $7}' )
4100                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4101                 if (( ${write_bytes:-0} > 0 )); then
4102                         all_zeros=false
4103                         break
4104                 fi
4105         done
4106
4107         if $all_zeros; then
4108                 for ostnum in $(seq $OSTCOUNT); do
4109                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4110                         echo "Check write_bytes is in obdfilter.*.stats:"
4111                         do_facet ost$ostnum lctl get_param -n \
4112                                 obdfilter.$ostname.stats
4113                 done
4114                 error "OST not keeping write_bytes stats (b=22312)"
4115         fi
4116 }
4117 run_test 33c "test write_bytes stats"
4118
4119 test_33d() {
4120         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4122
4123         local MDTIDX=1
4124         local remote_dir=$DIR/$tdir/remote_dir
4125
4126         test_mkdir $DIR/$tdir
4127         $LFS mkdir -i $MDTIDX $remote_dir ||
4128                 error "create remote directory failed"
4129
4130         touch $remote_dir/$tfile
4131         chmod 444 $remote_dir/$tfile
4132         chown $RUNAS_ID $remote_dir/$tfile
4133
4134         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4135
4136         chown $RUNAS_ID $remote_dir
4137         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4138                                         error "create" || true
4139         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4140                                     error "open RDWR" || true
4141         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4142 }
4143 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4144
4145 test_33e() {
4146         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4147
4148         mkdir $DIR/$tdir
4149
4150         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4151         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4152         mkdir $DIR/$tdir/local_dir
4153
4154         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4155         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4156         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4157
4158         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4159                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4160
4161         rmdir $DIR/$tdir/* || error "rmdir failed"
4162
4163         umask 777
4164         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4165         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4166         mkdir $DIR/$tdir/local_dir
4167
4168         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4169         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4170         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4171
4172         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4173                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4174
4175         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4176
4177         umask 000
4178         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4179         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4180         mkdir $DIR/$tdir/local_dir
4181
4182         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4183         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4184         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4185
4186         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4187                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4188 }
4189 run_test 33e "mkdir and striped directory should have same mode"
4190
4191 cleanup_33f() {
4192         trap 0
4193         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4194 }
4195
4196 test_33f() {
4197         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4198         remote_mds_nodsh && skip "remote MDS with nodsh"
4199
4200         mkdir $DIR/$tdir
4201         chmod go+rwx $DIR/$tdir
4202         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4203         trap cleanup_33f EXIT
4204
4205         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4206                 error "cannot create striped directory"
4207
4208         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4209                 error "cannot create files in striped directory"
4210
4211         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4212                 error "cannot remove files in striped directory"
4213
4214         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4215                 error "cannot remove striped directory"
4216
4217         cleanup_33f
4218 }
4219 run_test 33f "nonroot user can create, access, and remove a striped directory"
4220
4221 test_33g() {
4222         mkdir -p $DIR/$tdir/dir2
4223
4224         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4225         echo $err
4226         [[ $err =~ "exists" ]] || error "Not exists error"
4227 }
4228 run_test 33g "nonroot user create already existing root created file"
4229
4230 test_33h() {
4231         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4232         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4233                 skip "Need MDS version at least 2.13.50"
4234
4235         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4236                 error "mkdir $tdir failed"
4237         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4238
4239         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4240         local index2
4241
4242         for fname in $DIR/$tdir/$tfile.bak \
4243                      $DIR/$tdir/$tfile.SAV \
4244                      $DIR/$tdir/$tfile.orig \
4245                      $DIR/$tdir/$tfile~; do
4246                 touch $fname  || error "touch $fname failed"
4247                 index2=$($LFS getstripe -m $fname)
4248                 [ $index -eq $index2 ] ||
4249                         error "$fname MDT index mismatch $index != $index2"
4250         done
4251
4252         local failed=0
4253         for i in {1..250}; do
4254                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4255                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4256                         touch $fname  || error "touch $fname failed"
4257                         index2=$($LFS getstripe -m $fname)
4258                         if [[ $index != $index2 ]]; then
4259                                 failed=$((failed + 1))
4260                                 echo "$fname MDT index mismatch $index != $index2"
4261                         fi
4262                 done
4263         done
4264         echo "$failed MDT index mismatches"
4265         (( failed < 20 )) || error "MDT index mismatch $failed times"
4266
4267 }
4268 run_test 33h "temp file is located on the same MDT as target"
4269
4270 test_33i()
4271 {
4272         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4273
4274         local FNAME=$(str_repeat 'f' 250)
4275
4276         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4277         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4278
4279         local count
4280         local total
4281
4282         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4283
4284         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4285
4286         lctl --device %$MDC deactivate
4287         stack_trap "lctl --device %$MDC activate"
4288         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4289         total=$(\ls -l $DIR/$tdir | wc -l)
4290         # "ls -l" will list total in the first line
4291         total=$((total - 1))
4292         (( total + count == 1000 )) ||
4293                 error "ls list $total files, $count files on MDT1"
4294 }
4295 run_test 33i "striped directory can be accessed when one MDT is down"
4296
4297 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4298 test_34a() {
4299         rm -f $DIR/f34
4300         $MCREATE $DIR/f34 || error "mcreate failed"
4301         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4302                 error "getstripe failed"
4303         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4304         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4305                 error "getstripe failed"
4306         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4307                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4308 }
4309 run_test 34a "truncate file that has not been opened ==========="
4310
4311 test_34b() {
4312         [ ! -f $DIR/f34 ] && test_34a
4313         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4314                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4315         $OPENFILE -f O_RDONLY $DIR/f34
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 34b "O_RDONLY opening file doesn't create objects ====="
4322
4323 test_34c() {
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_RDWR $DIR/f34
4328         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4329                 error "$LFS 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 34c "O_RDWR opening file-with-size works =============="
4334
4335 test_34d() {
4336         [ ! -f $DIR/f34 ] && test_34a
4337         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4338                 error "dd failed"
4339         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4340                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4341         rm $DIR/f34
4342 }
4343 run_test 34d "write to sparse file ============================="
4344
4345 test_34e() {
4346         rm -f $DIR/f34e
4347         $MCREATE $DIR/f34e || error "mcreate failed"
4348         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4349         $CHECKSTAT -s 1000 $DIR/f34e ||
4350                 error "Size of $DIR/f34e not equal to 1000 bytes"
4351         $OPENFILE -f O_RDWR $DIR/f34e
4352         $CHECKSTAT -s 1000 $DIR/f34e ||
4353                 error "Size of $DIR/f34e not equal to 1000 bytes"
4354 }
4355 run_test 34e "create objects, some with size and some without =="
4356
4357 test_34f() { # bug 6242, 6243
4358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4359
4360         SIZE34F=48000
4361         rm -f $DIR/f34f
4362         $MCREATE $DIR/f34f || error "mcreate failed"
4363         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4364         dd if=$DIR/f34f of=$TMP/f34f
4365         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4366         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4367         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4368         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4369         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4370 }
4371 run_test 34f "read from a file with no objects until EOF ======="
4372
4373 test_34g() {
4374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4375
4376         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4377                 error "dd failed"
4378         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4379         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4380                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4381         cancel_lru_locks osc
4382         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4383                 error "wrong size after lock cancel"
4384
4385         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4386         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4387                 error "expanding truncate failed"
4388         cancel_lru_locks osc
4389         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4390                 error "wrong expanded size after lock cancel"
4391 }
4392 run_test 34g "truncate long file ==============================="
4393
4394 test_34h() {
4395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4396
4397         local gid=10
4398         local sz=1000
4399
4400         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4401         sync # Flush the cache so that multiop below does not block on cache
4402              # flush when getting the group lock
4403         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4404         MULTIPID=$!
4405
4406         # Since just timed wait is not good enough, let's do a sync write
4407         # that way we are sure enough time for a roundtrip + processing
4408         # passed + 2 seconds of extra margin.
4409         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4410         rm $DIR/${tfile}-1
4411         sleep 2
4412
4413         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4414                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4415                 kill -9 $MULTIPID
4416         fi
4417         wait $MULTIPID
4418         local nsz=`stat -c %s $DIR/$tfile`
4419         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4420 }
4421 run_test 34h "ftruncate file under grouplock should not block"
4422
4423 test_35a() {
4424         cp /bin/sh $DIR/f35a
4425         chmod 444 $DIR/f35a
4426         chown $RUNAS_ID $DIR/f35a
4427         $RUNAS $DIR/f35a && error || true
4428         rm $DIR/f35a
4429 }
4430 run_test 35a "exec file with mode 444 (should return and not leak)"
4431
4432 test_36a() {
4433         rm -f $DIR/f36
4434         utime $DIR/f36 || error "utime failed for MDS"
4435 }
4436 run_test 36a "MDS utime check (mknod, utime)"
4437
4438 test_36b() {
4439         echo "" > $DIR/f36
4440         utime $DIR/f36 || error "utime failed for OST"
4441 }
4442 run_test 36b "OST utime check (open, utime)"
4443
4444 test_36c() {
4445         rm -f $DIR/d36/f36
4446         test_mkdir $DIR/d36
4447         chown $RUNAS_ID $DIR/d36
4448         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4449 }
4450 run_test 36c "non-root MDS utime check (mknod, utime)"
4451
4452 test_36d() {
4453         [ ! -d $DIR/d36 ] && test_36c
4454         echo "" > $DIR/d36/f36
4455         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4456 }
4457 run_test 36d "non-root OST utime check (open, utime)"
4458
4459 test_36e() {
4460         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4461
4462         test_mkdir $DIR/$tdir
4463         touch $DIR/$tdir/$tfile
4464         $RUNAS utime $DIR/$tdir/$tfile &&
4465                 error "utime worked, expected failure" || true
4466 }
4467 run_test 36e "utime on non-owned file (should return error)"
4468
4469 subr_36fh() {
4470         local fl="$1"
4471         local LANG_SAVE=$LANG
4472         local LC_LANG_SAVE=$LC_LANG
4473         export LANG=C LC_LANG=C # for date language
4474
4475         DATESTR="Dec 20  2000"
4476         test_mkdir $DIR/$tdir
4477         lctl set_param fail_loc=$fl
4478         date; date +%s
4479         cp /etc/hosts $DIR/$tdir/$tfile
4480         sync & # write RPC generated with "current" inode timestamp, but delayed
4481         sleep 1
4482         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4483         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4484         cancel_lru_locks $OSC
4485         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4486         date; date +%s
4487         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4488                 echo "BEFORE: $LS_BEFORE" && \
4489                 echo "AFTER : $LS_AFTER" && \
4490                 echo "WANT  : $DATESTR" && \
4491                 error "$DIR/$tdir/$tfile timestamps changed" || true
4492
4493         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4494 }
4495
4496 test_36f() {
4497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4498
4499         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4500         subr_36fh "0x80000214"
4501 }
4502 run_test 36f "utime on file racing with OST BRW write =========="
4503
4504 test_36g() {
4505         remote_ost_nodsh && skip "remote OST with nodsh"
4506         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4507         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4508                 skip "Need MDS version at least 2.12.51"
4509
4510         local fmd_max_age
4511         local fmd
4512         local facet="ost1"
4513         local tgt="obdfilter"
4514
4515         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4516
4517         test_mkdir $DIR/$tdir
4518         fmd_max_age=$(do_facet $facet \
4519                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4520                 head -n 1")
4521
4522         echo "FMD max age: ${fmd_max_age}s"
4523         touch $DIR/$tdir/$tfile
4524         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4525                 gawk '{cnt=cnt+$1}  END{print cnt}')
4526         echo "FMD before: $fmd"
4527         [[ $fmd == 0 ]] &&
4528                 error "FMD wasn't create by touch"
4529         sleep $((fmd_max_age + 12))
4530         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4531                 gawk '{cnt=cnt+$1}  END{print cnt}')
4532         echo "FMD after: $fmd"
4533         [[ $fmd == 0 ]] ||
4534                 error "FMD wasn't expired by ping"
4535 }
4536 run_test 36g "FMD cache expiry ====================="
4537
4538 test_36h() {
4539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4540
4541         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4542         subr_36fh "0x80000227"
4543 }
4544 run_test 36h "utime on file racing with OST BRW write =========="
4545
4546 test_36i() {
4547         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4548
4549         test_mkdir $DIR/$tdir
4550         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4551
4552         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4553         local new_mtime=$((mtime + 200))
4554
4555         #change Modify time of striped dir
4556         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4557                         error "change mtime failed"
4558
4559         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4560
4561         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4562 }
4563 run_test 36i "change mtime on striped directory"
4564
4565 # test_37 - duplicate with tests 32q 32r
4566
4567 test_38() {
4568         local file=$DIR/$tfile
4569         touch $file
4570         openfile -f O_DIRECTORY $file
4571         local RC=$?
4572         local ENOTDIR=20
4573         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4574         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4575 }
4576 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4577
4578 test_39a() { # was test_39
4579         touch $DIR/$tfile
4580         touch $DIR/${tfile}2
4581 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4582 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4583 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4584         sleep 2
4585         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4586         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4587                 echo "mtime"
4588                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4589                 echo "atime"
4590                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4591                 echo "ctime"
4592                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4593                 error "O_TRUNC didn't change timestamps"
4594         fi
4595 }
4596 run_test 39a "mtime changed on create"
4597
4598 test_39b() {
4599         test_mkdir -c1 $DIR/$tdir
4600         cp -p /etc/passwd $DIR/$tdir/fopen
4601         cp -p /etc/passwd $DIR/$tdir/flink
4602         cp -p /etc/passwd $DIR/$tdir/funlink
4603         cp -p /etc/passwd $DIR/$tdir/frename
4604         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4605
4606         sleep 1
4607         echo "aaaaaa" >> $DIR/$tdir/fopen
4608         echo "aaaaaa" >> $DIR/$tdir/flink
4609         echo "aaaaaa" >> $DIR/$tdir/funlink
4610         echo "aaaaaa" >> $DIR/$tdir/frename
4611
4612         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4613         local link_new=`stat -c %Y $DIR/$tdir/flink`
4614         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4615         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4616
4617         cat $DIR/$tdir/fopen > /dev/null
4618         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4619         rm -f $DIR/$tdir/funlink2
4620         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4621
4622         for (( i=0; i < 2; i++ )) ; do
4623                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4624                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4625                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4626                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4627
4628                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4629                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4630                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4631                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4632
4633                 cancel_lru_locks $OSC
4634                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4635         done
4636 }
4637 run_test 39b "mtime change on open, link, unlink, rename  ======"
4638
4639 # this should be set to past
4640 TEST_39_MTIME=`date -d "1 year ago" +%s`
4641
4642 # bug 11063
4643 test_39c() {
4644         touch $DIR1/$tfile
4645         sleep 2
4646         local mtime0=`stat -c %Y $DIR1/$tfile`
4647
4648         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4649         local mtime1=`stat -c %Y $DIR1/$tfile`
4650         [ "$mtime1" = $TEST_39_MTIME ] || \
4651                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4652
4653         local d1=`date +%s`
4654         echo hello >> $DIR1/$tfile
4655         local d2=`date +%s`
4656         local mtime2=`stat -c %Y $DIR1/$tfile`
4657         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4658                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4659
4660         mv $DIR1/$tfile $DIR1/$tfile-1
4661
4662         for (( i=0; i < 2; i++ )) ; do
4663                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4664                 [ "$mtime2" = "$mtime3" ] || \
4665                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4666
4667                 cancel_lru_locks $OSC
4668                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4669         done
4670 }
4671 run_test 39c "mtime change on rename ==========================="
4672
4673 # bug 21114
4674 test_39d() {
4675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4676
4677         touch $DIR1/$tfile
4678         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4679
4680         for (( i=0; i < 2; i++ )) ; do
4681                 local mtime=`stat -c %Y $DIR1/$tfile`
4682                 [ $mtime = $TEST_39_MTIME ] || \
4683                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4684
4685                 cancel_lru_locks $OSC
4686                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4687         done
4688 }
4689 run_test 39d "create, utime, stat =============================="
4690
4691 # bug 21114
4692 test_39e() {
4693         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4694
4695         touch $DIR1/$tfile
4696         local mtime1=`stat -c %Y $DIR1/$tfile`
4697
4698         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4699
4700         for (( i=0; i < 2; i++ )) ; do
4701                 local mtime2=`stat -c %Y $DIR1/$tfile`
4702                 [ $mtime2 = $TEST_39_MTIME ] || \
4703                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4704
4705                 cancel_lru_locks $OSC
4706                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4707         done
4708 }
4709 run_test 39e "create, stat, utime, stat ========================"
4710
4711 # bug 21114
4712 test_39f() {
4713         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4714
4715         touch $DIR1/$tfile
4716         mtime1=`stat -c %Y $DIR1/$tfile`
4717
4718         sleep 2
4719         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4720
4721         for (( i=0; i < 2; i++ )) ; do
4722                 local mtime2=`stat -c %Y $DIR1/$tfile`
4723                 [ $mtime2 = $TEST_39_MTIME ] || \
4724                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4725
4726                 cancel_lru_locks $OSC
4727                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4728         done
4729 }
4730 run_test 39f "create, stat, sleep, utime, stat ================="
4731
4732 # bug 11063
4733 test_39g() {
4734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4735
4736         echo hello >> $DIR1/$tfile
4737         local mtime1=`stat -c %Y $DIR1/$tfile`
4738
4739         sleep 2
4740         chmod o+r $DIR1/$tfile
4741
4742         for (( i=0; i < 2; i++ )) ; do
4743                 local mtime2=`stat -c %Y $DIR1/$tfile`
4744                 [ "$mtime1" = "$mtime2" ] || \
4745                         error "lost mtime: $mtime2, should be $mtime1"
4746
4747                 cancel_lru_locks $OSC
4748                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4749         done
4750 }
4751 run_test 39g "write, chmod, stat ==============================="
4752
4753 # bug 11063
4754 test_39h() {
4755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4756
4757         touch $DIR1/$tfile
4758         sleep 1
4759
4760         local d1=`date`
4761         echo hello >> $DIR1/$tfile
4762         local mtime1=`stat -c %Y $DIR1/$tfile`
4763
4764         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4765         local d2=`date`
4766         if [ "$d1" != "$d2" ]; then
4767                 echo "write and touch not within one second"
4768         else
4769                 for (( i=0; i < 2; i++ )) ; do
4770                         local mtime2=`stat -c %Y $DIR1/$tfile`
4771                         [ "$mtime2" = $TEST_39_MTIME ] || \
4772                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4773
4774                         cancel_lru_locks $OSC
4775                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4776                 done
4777         fi
4778 }
4779 run_test 39h "write, utime within one second, stat ============="
4780
4781 test_39i() {
4782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4783
4784         touch $DIR1/$tfile
4785         sleep 1
4786
4787         echo hello >> $DIR1/$tfile
4788         local mtime1=`stat -c %Y $DIR1/$tfile`
4789
4790         mv $DIR1/$tfile $DIR1/$tfile-1
4791
4792         for (( i=0; i < 2; i++ )) ; do
4793                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4794
4795                 [ "$mtime1" = "$mtime2" ] || \
4796                         error "lost mtime: $mtime2, should be $mtime1"
4797
4798                 cancel_lru_locks $OSC
4799                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4800         done
4801 }
4802 run_test 39i "write, rename, stat =============================="
4803
4804 test_39j() {
4805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4806
4807         start_full_debug_logging
4808         touch $DIR1/$tfile
4809         sleep 1
4810
4811         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4812         lctl set_param fail_loc=0x80000412
4813         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4814                 error "multiop failed"
4815         local multipid=$!
4816         local mtime1=`stat -c %Y $DIR1/$tfile`
4817
4818         mv $DIR1/$tfile $DIR1/$tfile-1
4819
4820         kill -USR1 $multipid
4821         wait $multipid || error "multiop close failed"
4822
4823         for (( i=0; i < 2; i++ )) ; do
4824                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4825                 [ "$mtime1" = "$mtime2" ] ||
4826                         error "mtime is lost on close: $mtime2, " \
4827                               "should be $mtime1"
4828
4829                 cancel_lru_locks
4830                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4831         done
4832         lctl set_param fail_loc=0
4833         stop_full_debug_logging
4834 }
4835 run_test 39j "write, rename, close, stat ======================="
4836
4837 test_39k() {
4838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4839
4840         touch $DIR1/$tfile
4841         sleep 1
4842
4843         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4844         local multipid=$!
4845         local mtime1=`stat -c %Y $DIR1/$tfile`
4846
4847         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4848
4849         kill -USR1 $multipid
4850         wait $multipid || error "multiop close failed"
4851
4852         for (( i=0; i < 2; i++ )) ; do
4853                 local mtime2=`stat -c %Y $DIR1/$tfile`
4854
4855                 [ "$mtime2" = $TEST_39_MTIME ] || \
4856                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4857
4858                 cancel_lru_locks
4859                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4860         done
4861 }
4862 run_test 39k "write, utime, close, stat ========================"
4863
4864 # this should be set to future
4865 TEST_39_ATIME=`date -d "1 year" +%s`
4866
4867 test_39l() {
4868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4869         remote_mds_nodsh && skip "remote MDS with nodsh"
4870
4871         local atime_diff=$(do_facet $SINGLEMDS \
4872                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4873         rm -rf $DIR/$tdir
4874         mkdir_on_mdt0 $DIR/$tdir
4875
4876         # test setting directory atime to future
4877         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4878         local atime=$(stat -c %X $DIR/$tdir)
4879         [ "$atime" = $TEST_39_ATIME ] ||
4880                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4881
4882         # test setting directory atime from future to now
4883         local now=$(date +%s)
4884         touch -a -d @$now $DIR/$tdir
4885
4886         atime=$(stat -c %X $DIR/$tdir)
4887         [ "$atime" -eq "$now"  ] ||
4888                 error "atime is not updated from future: $atime, $now"
4889
4890         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4891         sleep 3
4892
4893         # test setting directory atime when now > dir atime + atime_diff
4894         local d1=$(date +%s)
4895         ls $DIR/$tdir
4896         local d2=$(date +%s)
4897         cancel_lru_locks mdc
4898         atime=$(stat -c %X $DIR/$tdir)
4899         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4900                 error "atime is not updated  : $atime, should be $d2"
4901
4902         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4903         sleep 3
4904
4905         # test not setting directory atime when now < dir atime + atime_diff
4906         ls $DIR/$tdir
4907         cancel_lru_locks mdc
4908         atime=$(stat -c %X $DIR/$tdir)
4909         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4910                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4911
4912         do_facet $SINGLEMDS \
4913                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4914 }
4915 run_test 39l "directory atime update ==========================="
4916
4917 test_39m() {
4918         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4919
4920         touch $DIR1/$tfile
4921         sleep 2
4922         local far_past_mtime=$(date -d "May 29 1953" +%s)
4923         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4924
4925         touch -m -d @$far_past_mtime $DIR1/$tfile
4926         touch -a -d @$far_past_atime $DIR1/$tfile
4927
4928         for (( i=0; i < 2; i++ )) ; do
4929                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4930                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4931                         error "atime or mtime set incorrectly"
4932
4933                 cancel_lru_locks $OSC
4934                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4935         done
4936 }
4937 run_test 39m "test atime and mtime before 1970"
4938
4939 test_39n() { # LU-3832
4940         remote_mds_nodsh && skip "remote MDS with nodsh"
4941
4942         local atime_diff=$(do_facet $SINGLEMDS \
4943                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4944         local atime0
4945         local atime1
4946         local atime2
4947
4948         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4949
4950         rm -rf $DIR/$tfile
4951         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4952         atime0=$(stat -c %X $DIR/$tfile)
4953
4954         sleep 5
4955         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4956         atime1=$(stat -c %X $DIR/$tfile)
4957
4958         sleep 5
4959         cancel_lru_locks mdc
4960         cancel_lru_locks osc
4961         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4962         atime2=$(stat -c %X $DIR/$tfile)
4963
4964         do_facet $SINGLEMDS \
4965                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4966
4967         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4968         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4969 }
4970 run_test 39n "check that O_NOATIME is honored"
4971
4972 test_39o() {
4973         TESTDIR=$DIR/$tdir/$tfile
4974         [ -e $TESTDIR ] && rm -rf $TESTDIR
4975         mkdir -p $TESTDIR
4976         cd $TESTDIR
4977         links1=2
4978         ls
4979         mkdir a b
4980         ls
4981         links2=$(stat -c %h .)
4982         [ $(($links1 + 2)) != $links2 ] &&
4983                 error "wrong links count $(($links1 + 2)) != $links2"
4984         rmdir b
4985         links3=$(stat -c %h .)
4986         [ $(($links1 + 1)) != $links3 ] &&
4987                 error "wrong links count $links1 != $links3"
4988         return 0
4989 }
4990 run_test 39o "directory cached attributes updated after create"
4991
4992 test_39p() {
4993         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4994
4995         local MDTIDX=1
4996         TESTDIR=$DIR/$tdir/$tdir
4997         [ -e $TESTDIR ] && rm -rf $TESTDIR
4998         test_mkdir -p $TESTDIR
4999         cd $TESTDIR
5000         links1=2
5001         ls
5002         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5003         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5004         ls
5005         links2=$(stat -c %h .)
5006         [ $(($links1 + 2)) != $links2 ] &&
5007                 error "wrong links count $(($links1 + 2)) != $links2"
5008         rmdir remote_dir2
5009         links3=$(stat -c %h .)
5010         [ $(($links1 + 1)) != $links3 ] &&
5011                 error "wrong links count $links1 != $links3"
5012         return 0
5013 }
5014 run_test 39p "remote directory cached attributes updated after create ========"
5015
5016 test_39r() {
5017         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5018                 skip "no atime update on old OST"
5019         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5020                 skip_env "ldiskfs only test"
5021         fi
5022
5023         local saved_adiff
5024         saved_adiff=$(do_facet ost1 \
5025                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5026         stack_trap "do_facet ost1 \
5027                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5028
5029         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5030
5031         $LFS setstripe -i 0 $DIR/$tfile
5032         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5033                 error "can't write initial file"
5034         cancel_lru_locks osc
5035
5036         # exceed atime_diff and access file
5037         sleep 6
5038         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5039                 error "can't udpate atime"
5040
5041         local atime_cli=$(stat -c %X $DIR/$tfile)
5042         echo "client atime: $atime_cli"
5043         # allow atime update to be written to device
5044         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5045         sleep 5
5046
5047         local ostdev=$(ostdevname 1)
5048         local fid=($(lfs getstripe -y $DIR/$tfile |
5049                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
5050         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
5051         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5052
5053         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5054         local atime_ost=$(do_facet ost1 "$cmd" |&
5055                           awk -F'[: ]' '/atime:/ { print $4 }')
5056         (( atime_cli == atime_ost )) ||
5057                 error "atime on client $atime_cli != ost $atime_ost"
5058 }
5059 run_test 39r "lazy atime update on OST"
5060
5061 test_39q() { # LU-8041
5062         local testdir=$DIR/$tdir
5063         mkdir -p $testdir
5064         multiop_bg_pause $testdir D_c || error "multiop failed"
5065         local multipid=$!
5066         cancel_lru_locks mdc
5067         kill -USR1 $multipid
5068         local atime=$(stat -c %X $testdir)
5069         [ "$atime" -ne 0 ] || error "atime is zero"
5070 }
5071 run_test 39q "close won't zero out atime"
5072
5073 test_40() {
5074         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5075         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5076                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5077         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5078                 error "$tfile is not 4096 bytes in size"
5079 }
5080 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5081
5082 test_41() {
5083         # bug 1553
5084         small_write $DIR/f41 18
5085 }
5086 run_test 41 "test small file write + fstat ====================="
5087
5088 count_ost_writes() {
5089         lctl get_param -n ${OSC}.*.stats |
5090                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5091                         END { printf("%0.0f", writes) }'
5092 }
5093
5094 # decent default
5095 WRITEBACK_SAVE=500
5096 DIRTY_RATIO_SAVE=40
5097 MAX_DIRTY_RATIO=50
5098 BG_DIRTY_RATIO_SAVE=10
5099 MAX_BG_DIRTY_RATIO=25
5100
5101 start_writeback() {
5102         trap 0
5103         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5104         # dirty_ratio, dirty_background_ratio
5105         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5106                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5107                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5108                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5109         else
5110                 # if file not here, we are a 2.4 kernel
5111                 kill -CONT `pidof kupdated`
5112         fi
5113 }
5114
5115 stop_writeback() {
5116         # setup the trap first, so someone cannot exit the test at the
5117         # exact wrong time and mess up a machine
5118         trap start_writeback EXIT
5119         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5120         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5121                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5122                 sysctl -w vm.dirty_writeback_centisecs=0
5123                 sysctl -w vm.dirty_writeback_centisecs=0
5124                 # save and increase /proc/sys/vm/dirty_ratio
5125                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5126                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5127                 # save and increase /proc/sys/vm/dirty_background_ratio
5128                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5129                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5130         else
5131                 # if file not here, we are a 2.4 kernel
5132                 kill -STOP `pidof kupdated`
5133         fi
5134 }
5135
5136 # ensure that all stripes have some grant before we test client-side cache
5137 setup_test42() {
5138         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5139                 dd if=/dev/zero of=$i bs=4k count=1
5140                 rm $i
5141         done
5142 }
5143
5144 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5145 # file truncation, and file removal.
5146 test_42a() {
5147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5148
5149         setup_test42
5150         cancel_lru_locks $OSC
5151         stop_writeback
5152         sync; sleep 1; sync # just to be safe
5153         BEFOREWRITES=`count_ost_writes`
5154         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5155         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5156         AFTERWRITES=`count_ost_writes`
5157         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5158                 error "$BEFOREWRITES < $AFTERWRITES"
5159         start_writeback
5160 }
5161 run_test 42a "ensure that we don't flush on close"
5162
5163 test_42b() {
5164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5165
5166         setup_test42
5167         cancel_lru_locks $OSC
5168         stop_writeback
5169         sync
5170         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5171         BEFOREWRITES=$(count_ost_writes)
5172         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5173         AFTERWRITES=$(count_ost_writes)
5174         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5175                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5176         fi
5177         BEFOREWRITES=$(count_ost_writes)
5178         sync || error "sync: $?"
5179         AFTERWRITES=$(count_ost_writes)
5180         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5181                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5182         fi
5183         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5184         start_writeback
5185         return 0
5186 }
5187 run_test 42b "test destroy of file with cached dirty data ======"
5188
5189 # if these tests just want to test the effect of truncation,
5190 # they have to be very careful.  consider:
5191 # - the first open gets a {0,EOF}PR lock
5192 # - the first write conflicts and gets a {0, count-1}PW
5193 # - the rest of the writes are under {count,EOF}PW
5194 # - the open for truncate tries to match a {0,EOF}PR
5195 #   for the filesize and cancels the PWs.
5196 # any number of fixes (don't get {0,EOF} on open, match
5197 # composite locks, do smarter file size management) fix
5198 # this, but for now we want these tests to verify that
5199 # the cancellation with truncate intent works, so we
5200 # start the file with a full-file pw lock to match against
5201 # until the truncate.
5202 trunc_test() {
5203         test=$1
5204         file=$DIR/$test
5205         offset=$2
5206         cancel_lru_locks $OSC
5207         stop_writeback
5208         # prime the file with 0,EOF PW to match
5209         touch $file
5210         $TRUNCATE $file 0
5211         sync; sync
5212         # now the real test..
5213         dd if=/dev/zero of=$file bs=1024 count=100
5214         BEFOREWRITES=`count_ost_writes`
5215         $TRUNCATE $file $offset
5216         cancel_lru_locks $OSC
5217         AFTERWRITES=`count_ost_writes`
5218         start_writeback
5219 }
5220
5221 test_42c() {
5222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5223
5224         trunc_test 42c 1024
5225         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5226                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5227         rm $file
5228 }
5229 run_test 42c "test partial truncate of file with cached dirty data"
5230
5231 test_42d() {
5232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5233
5234         trunc_test 42d 0
5235         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5236                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5237         rm $file
5238 }
5239 run_test 42d "test complete truncate of file with cached dirty data"
5240
5241 test_42e() { # bug22074
5242         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5243
5244         local TDIR=$DIR/${tdir}e
5245         local pages=16 # hardcoded 16 pages, don't change it.
5246         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5247         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5248         local max_dirty_mb
5249         local warmup_files
5250
5251         test_mkdir $DIR/${tdir}e
5252         $LFS setstripe -c 1 $TDIR
5253         createmany -o $TDIR/f $files
5254
5255         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5256
5257         # we assume that with $OSTCOUNT files, at least one of them will
5258         # be allocated on OST0.
5259         warmup_files=$((OSTCOUNT * max_dirty_mb))
5260         createmany -o $TDIR/w $warmup_files
5261
5262         # write a large amount of data into one file and sync, to get good
5263         # avail_grant number from OST.
5264         for ((i=0; i<$warmup_files; i++)); do
5265                 idx=$($LFS getstripe -i $TDIR/w$i)
5266                 [ $idx -ne 0 ] && continue
5267                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5268                 break
5269         done
5270         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5271         sync
5272         $LCTL get_param $proc_osc0/cur_dirty_bytes
5273         $LCTL get_param $proc_osc0/cur_grant_bytes
5274
5275         # create as much dirty pages as we can while not to trigger the actual
5276         # RPCs directly. but depends on the env, VFS may trigger flush during this
5277         # period, hopefully we are good.
5278         for ((i=0; i<$warmup_files; i++)); do
5279                 idx=$($LFS getstripe -i $TDIR/w$i)
5280                 [ $idx -ne 0 ] && continue
5281                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5282         done
5283         $LCTL get_param $proc_osc0/cur_dirty_bytes
5284         $LCTL get_param $proc_osc0/cur_grant_bytes
5285
5286         # perform the real test
5287         $LCTL set_param $proc_osc0/rpc_stats 0
5288         for ((;i<$files; i++)); do
5289                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5290                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5291         done
5292         sync
5293         $LCTL get_param $proc_osc0/rpc_stats
5294
5295         local percent=0
5296         local have_ppr=false
5297         $LCTL get_param $proc_osc0/rpc_stats |
5298                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5299                         # skip lines until we are at the RPC histogram data
5300                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5301                         $have_ppr || continue
5302
5303                         # we only want the percent stat for < 16 pages
5304                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5305
5306                         percent=$((percent + WPCT))
5307                         if [[ $percent -gt 15 ]]; then
5308                                 error "less than 16-pages write RPCs" \
5309                                       "$percent% > 15%"
5310                                 break
5311                         fi
5312                 done
5313         rm -rf $TDIR
5314 }
5315 run_test 42e "verify sub-RPC writes are not done synchronously"
5316
5317 test_43A() { # was test_43
5318         test_mkdir $DIR/$tdir
5319         cp -p /bin/ls $DIR/$tdir/$tfile
5320         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5321         pid=$!
5322         # give multiop a chance to open
5323         sleep 1
5324
5325         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5326         kill -USR1 $pid
5327         # Wait for multiop to exit
5328         wait $pid
5329 }
5330 run_test 43A "execution of file opened for write should return -ETXTBSY"
5331
5332 test_43a() {
5333         test_mkdir $DIR/$tdir
5334         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5335         $DIR/$tdir/sleep 60 &
5336         SLEEP_PID=$!
5337         # Make sure exec of $tdir/sleep wins race with truncate
5338         sleep 1
5339         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5340         kill $SLEEP_PID
5341 }
5342 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5343
5344 test_43b() {
5345         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5346
5347         test_mkdir $DIR/$tdir
5348         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5349         $DIR/$tdir/sleep 60 &
5350         SLEEP_PID=$!
5351         # Make sure exec of $tdir/sleep wins race with truncate
5352         sleep 1
5353         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5354         kill $SLEEP_PID
5355 }
5356 run_test 43b "truncate of file being executed should return -ETXTBSY"
5357
5358 test_43c() {
5359         local testdir="$DIR/$tdir"
5360         test_mkdir $testdir
5361         cp $SHELL $testdir/
5362         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5363                 ( cd $testdir && md5sum -c )
5364 }
5365 run_test 43c "md5sum of copy into lustre"
5366
5367 test_44A() { # was test_44
5368         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5369
5370         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5371         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5372 }
5373 run_test 44A "zero length read from a sparse stripe"
5374
5375 test_44a() {
5376         local nstripe=$($LFS getstripe -c -d $DIR)
5377         [ -z "$nstripe" ] && skip "can't get stripe info"
5378         [[ $nstripe -gt $OSTCOUNT ]] &&
5379                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5380
5381         local stride=$($LFS getstripe -S -d $DIR)
5382         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5383                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5384         fi
5385
5386         OFFSETS="0 $((stride/2)) $((stride-1))"
5387         for offset in $OFFSETS; do
5388                 for i in $(seq 0 $((nstripe-1))); do
5389                         local GLOBALOFFSETS=""
5390                         # size in Bytes
5391                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5392                         local myfn=$DIR/d44a-$size
5393                         echo "--------writing $myfn at $size"
5394                         ll_sparseness_write $myfn $size ||
5395                                 error "ll_sparseness_write"
5396                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5397                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5398                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5399
5400                         for j in $(seq 0 $((nstripe-1))); do
5401                                 # size in Bytes
5402                                 size=$((((j + $nstripe )*$stride + $offset)))
5403                                 ll_sparseness_write $myfn $size ||
5404                                         error "ll_sparseness_write"
5405                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5406                         done
5407                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5408                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5409                         rm -f $myfn
5410                 done
5411         done
5412 }
5413 run_test 44a "test sparse pwrite ==============================="
5414
5415 dirty_osc_total() {
5416         tot=0
5417         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5418                 tot=$(($tot + $d))
5419         done
5420         echo $tot
5421 }
5422 do_dirty_record() {
5423         before=`dirty_osc_total`
5424         echo executing "\"$*\""
5425         eval $*
5426         after=`dirty_osc_total`
5427         echo before $before, after $after
5428 }
5429 test_45() {
5430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5431
5432         f="$DIR/f45"
5433         # Obtain grants from OST if it supports it
5434         echo blah > ${f}_grant
5435         stop_writeback
5436         sync
5437         do_dirty_record "echo blah > $f"
5438         [[ $before -eq $after ]] && error "write wasn't cached"
5439         do_dirty_record "> $f"
5440         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5441         do_dirty_record "echo blah > $f"
5442         [[ $before -eq $after ]] && error "write wasn't cached"
5443         do_dirty_record "sync"
5444         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5445         do_dirty_record "echo blah > $f"
5446         [[ $before -eq $after ]] && error "write wasn't cached"
5447         do_dirty_record "cancel_lru_locks osc"
5448         [[ $before -gt $after ]] ||
5449                 error "lock cancellation didn't lower dirty count"
5450         start_writeback
5451 }
5452 run_test 45 "osc io page accounting ============================"
5453
5454 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5455 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5456 # objects offset and an assert hit when an rpc was built with 1023's mapped
5457 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5458 test_46() {
5459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5460
5461         f="$DIR/f46"
5462         stop_writeback
5463         sync
5464         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5465         sync
5466         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5467         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5468         sync
5469         start_writeback
5470 }
5471 run_test 46 "dirtying a previously written page ================"
5472
5473 # test_47 is removed "Device nodes check" is moved to test_28
5474
5475 test_48a() { # bug 2399
5476         [ "$mds1_FSTYPE" = "zfs" ] &&
5477         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5478                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5479
5480         test_mkdir $DIR/$tdir
5481         cd $DIR/$tdir
5482         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5483         test_mkdir $DIR/$tdir
5484         touch foo || error "'touch foo' failed after recreating cwd"
5485         test_mkdir bar
5486         touch .foo || error "'touch .foo' failed after recreating cwd"
5487         test_mkdir .bar
5488         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5489         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5490         cd . || error "'cd .' failed after recreating cwd"
5491         mkdir . && error "'mkdir .' worked after recreating cwd"
5492         rmdir . && error "'rmdir .' worked after recreating cwd"
5493         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5494         cd .. || error "'cd ..' failed after recreating cwd"
5495 }
5496 run_test 48a "Access renamed working dir (should return errors)="
5497
5498 test_48b() { # bug 2399
5499         rm -rf $DIR/$tdir
5500         test_mkdir $DIR/$tdir
5501         cd $DIR/$tdir
5502         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5503         touch foo && error "'touch foo' worked after removing cwd"
5504         mkdir foo && error "'mkdir foo' worked after removing cwd"
5505         touch .foo && error "'touch .foo' worked after removing cwd"
5506         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5507         ls . > /dev/null && error "'ls .' worked after removing cwd"
5508         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5509         mkdir . && error "'mkdir .' worked after removing cwd"
5510         rmdir . && error "'rmdir .' worked after removing cwd"
5511         ln -s . foo && error "'ln -s .' worked after removing cwd"
5512         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5513 }
5514 run_test 48b "Access removed working dir (should return errors)="
5515
5516 test_48c() { # bug 2350
5517         #lctl set_param debug=-1
5518         #set -vx
5519         rm -rf $DIR/$tdir
5520         test_mkdir -p $DIR/$tdir/dir
5521         cd $DIR/$tdir/dir
5522         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5523         $TRACE touch foo && error "touch foo worked after removing cwd"
5524         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5525         touch .foo && error "touch .foo worked after removing cwd"
5526         mkdir .foo && error "mkdir .foo worked after removing cwd"
5527         $TRACE ls . && error "'ls .' worked after removing cwd"
5528         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5529         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5530         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5531         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5532         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5533 }
5534 run_test 48c "Access removed working subdir (should return errors)"
5535
5536 test_48d() { # bug 2350
5537         #lctl set_param debug=-1
5538         #set -vx
5539         rm -rf $DIR/$tdir
5540         test_mkdir -p $DIR/$tdir/dir
5541         cd $DIR/$tdir/dir
5542         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5543         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5544         $TRACE touch foo && error "'touch foo' worked after removing parent"
5545         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5546         touch .foo && error "'touch .foo' worked after removing parent"
5547         mkdir .foo && error "mkdir .foo worked after removing parent"
5548         $TRACE ls . && error "'ls .' worked after removing parent"
5549         $TRACE ls .. && error "'ls ..' worked after removing parent"
5550         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5551         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5552         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5553         true
5554 }
5555 run_test 48d "Access removed parent subdir (should return errors)"
5556
5557 test_48e() { # bug 4134
5558         #lctl set_param debug=-1
5559         #set -vx
5560         rm -rf $DIR/$tdir
5561         test_mkdir -p $DIR/$tdir/dir
5562         cd $DIR/$tdir/dir
5563         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5564         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5565         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5566         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5567         # On a buggy kernel addition of "touch foo" after cd .. will
5568         # produce kernel oops in lookup_hash_it
5569         touch ../foo && error "'cd ..' worked after recreate parent"
5570         cd $DIR
5571         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5572 }
5573 run_test 48e "Access to recreated parent subdir (should return errors)"
5574
5575 test_48f() {
5576         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5577                 skip "need MDS >= 2.13.55"
5578         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5579         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5580                 skip "needs different host for mdt1 mdt2"
5581         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5582
5583         $LFS mkdir -i0 $DIR/$tdir
5584         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5585
5586         for d in sub1 sub2 sub3; do
5587                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5588                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5589                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5590         done
5591
5592         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5593 }
5594 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5595
5596 test_49() { # LU-1030
5597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5598         remote_ost_nodsh && skip "remote OST with nodsh"
5599
5600         # get ost1 size - $FSNAME-OST0000
5601         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5602                 awk '{ print $4 }')
5603         # write 800M at maximum
5604         [[ $ost1_size -lt 2 ]] && ost1_size=2
5605         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5606
5607         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5608         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5609         local dd_pid=$!
5610
5611         # change max_pages_per_rpc while writing the file
5612         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5613         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5614         # loop until dd process exits
5615         while ps ax -opid | grep -wq $dd_pid; do
5616                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5617                 sleep $((RANDOM % 5 + 1))
5618         done
5619         # restore original max_pages_per_rpc
5620         $LCTL set_param $osc1_mppc=$orig_mppc
5621         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5622 }
5623 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5624
5625 test_50() {
5626         # bug 1485
5627         test_mkdir $DIR/$tdir
5628         cd $DIR/$tdir
5629         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5630 }
5631 run_test 50 "special situations: /proc symlinks  ==============="
5632
5633 test_51a() {    # was test_51
5634         # bug 1516 - create an empty entry right after ".." then split dir
5635         test_mkdir -c1 $DIR/$tdir
5636         touch $DIR/$tdir/foo
5637         $MCREATE $DIR/$tdir/bar
5638         rm $DIR/$tdir/foo
5639         createmany -m $DIR/$tdir/longfile 201
5640         FNUM=202
5641         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5642                 $MCREATE $DIR/$tdir/longfile$FNUM
5643                 FNUM=$(($FNUM + 1))
5644                 echo -n "+"
5645         done
5646         echo
5647         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5648 }
5649 run_test 51a "special situations: split htree with empty entry =="
5650
5651 cleanup_print_lfs_df () {
5652         trap 0
5653         $LFS df
5654         $LFS df -i
5655 }
5656
5657 test_51b() {
5658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5659
5660         local dir=$DIR/$tdir
5661         local nrdirs=$((65536 + 100))
5662
5663         # cleanup the directory
5664         rm -fr $dir
5665
5666         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5667
5668         $LFS df
5669         $LFS df -i
5670         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5671         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5672         [[ $numfree -lt $nrdirs ]] &&
5673                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5674
5675         # need to check free space for the directories as well
5676         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5677         numfree=$(( blkfree / $(fs_inode_ksize) ))
5678         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5679
5680         trap cleanup_print_lfs_df EXIT
5681
5682         # create files
5683         createmany -d $dir/d $nrdirs || {
5684                 unlinkmany $dir/d $nrdirs
5685                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5686         }
5687
5688         # really created :
5689         nrdirs=$(ls -U $dir | wc -l)
5690
5691         # unlink all but 100 subdirectories, then check it still works
5692         local left=100
5693         local delete=$((nrdirs - left))
5694
5695         $LFS df
5696         $LFS df -i
5697
5698         # for ldiskfs the nlink count should be 1, but this is OSD specific
5699         # and so this is listed for informational purposes only
5700         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5701         unlinkmany -d $dir/d $delete ||
5702                 error "unlink of first $delete subdirs failed"
5703
5704         echo "nlink between: $(stat -c %h $dir)"
5705         local found=$(ls -U $dir | wc -l)
5706         [ $found -ne $left ] &&
5707                 error "can't find subdirs: found only $found, expected $left"
5708
5709         unlinkmany -d $dir/d $delete $left ||
5710                 error "unlink of second $left subdirs failed"
5711         # regardless of whether the backing filesystem tracks nlink accurately
5712         # or not, the nlink count shouldn't be more than "." and ".." here
5713         local after=$(stat -c %h $dir)
5714         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5715                 echo "nlink after: $after"
5716
5717         cleanup_print_lfs_df
5718 }
5719 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5720
5721 test_51d() {
5722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5723         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5724         local qos_old
5725
5726         test_mkdir $DIR/$tdir
5727         $LFS setstripe -c $OSTCOUNT $DIR/$tdir
5728
5729         qos_old=$(do_facet mds1 \
5730                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5731         do_nodes $(comma_list $(mdts_nodes)) \
5732                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5733         stack_trap "do_nodes $(comma_list $(mdts_nodes)) \
5734                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5735
5736         createmany -o $DIR/$tdir/t- 1000
5737         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5738         for ((n = 0; n < $OSTCOUNT; n++)); do
5739                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5740                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5741                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5742                             '($1 == '$n') { objs += 1 } \
5743                             END { printf("%0.0f", objs) }')
5744                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5745         done
5746         unlinkmany $DIR/$tdir/t- 1000
5747
5748         nlast=0
5749         for ((n = 0; n < $OSTCOUNT; n++)); do
5750                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5751                         { $LFS df && $LFS df -i &&
5752                         error "OST $n has fewer objects vs. OST $nlast" \
5753                               " (${objs[$n]} < ${objs[$nlast]}"; }
5754                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5755                         { $LFS df && $LFS df -i &&
5756                         error "OST $n has fewer objects vs. OST $nlast" \
5757                               " (${objs[$n]} < ${objs[$nlast]}"; }
5758
5759                 (( ${objs0[$n]} > ${objs0[$nlast]} * 4 / 5 )) ||
5760                         { $LFS df && $LFS df -i &&
5761                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5762                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5763                 (( ${objs0[$n]} < ${objs0[$nlast]} * 5 / 4 )) ||
5764                         { $LFS df && $LFS df -i &&
5765                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5766                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5767                 nlast=$n
5768         done
5769 }
5770 run_test 51d "check object distribution"
5771
5772 test_51e() {
5773         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5774                 skip_env "ldiskfs only test"
5775         fi
5776
5777         test_mkdir -c1 $DIR/$tdir
5778         test_mkdir -c1 $DIR/$tdir/d0
5779
5780         touch $DIR/$tdir/d0/foo
5781         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5782                 error "file exceed 65000 nlink limit!"
5783         unlinkmany $DIR/$tdir/d0/f- 65001
5784         return 0
5785 }
5786 run_test 51e "check file nlink limit"
5787
5788 test_51f() {
5789         test_mkdir $DIR/$tdir
5790
5791         local max=100000
5792         local ulimit_old=$(ulimit -n)
5793         local spare=20 # number of spare fd's for scripts/libraries, etc.
5794         local mdt=$($LFS getstripe -m $DIR/$tdir)
5795         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5796
5797         echo "MDT$mdt numfree=$numfree, max=$max"
5798         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5799         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5800                 while ! ulimit -n $((numfree + spare)); do
5801                         numfree=$((numfree * 3 / 4))
5802                 done
5803                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5804         else
5805                 echo "left ulimit at $ulimit_old"
5806         fi
5807
5808         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5809                 unlinkmany $DIR/$tdir/f $numfree
5810                 error "create+open $numfree files in $DIR/$tdir failed"
5811         }
5812         ulimit -n $ulimit_old
5813
5814         # if createmany exits at 120s there will be fewer than $numfree files
5815         unlinkmany $DIR/$tdir/f $numfree || true
5816 }
5817 run_test 51f "check many open files limit"
5818
5819 test_52a() {
5820         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5821         test_mkdir $DIR/$tdir
5822         touch $DIR/$tdir/foo
5823         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5824         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5825         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5826         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5827         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5828                                         error "link worked"
5829         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5830         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5831         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5832                                                      error "lsattr"
5833         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5834         cp -r $DIR/$tdir $TMP/
5835         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5836 }
5837 run_test 52a "append-only flag test (should return errors)"
5838
5839 test_52b() {
5840         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5841         test_mkdir $DIR/$tdir
5842         touch $DIR/$tdir/foo
5843         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5844         cat test > $DIR/$tdir/foo && error "cat test worked"
5845         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5846         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5847         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5848                                         error "link worked"
5849         echo foo >> $DIR/$tdir/foo && error "echo worked"
5850         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5851         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5852         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5853         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5854                                                         error "lsattr"
5855         chattr -i $DIR/$tdir/foo || error "chattr failed"
5856
5857         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5858 }
5859 run_test 52b "immutable flag test (should return errors) ======="
5860
5861 test_53() {
5862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5863         remote_mds_nodsh && skip "remote MDS with nodsh"
5864         remote_ost_nodsh && skip "remote OST with nodsh"
5865
5866         local param
5867         local param_seq
5868         local ostname
5869         local mds_last
5870         local mds_last_seq
5871         local ost_last
5872         local ost_last_seq
5873         local ost_last_id
5874         local ostnum
5875         local node
5876         local found=false
5877         local support_last_seq=true
5878
5879         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5880                 support_last_seq=false
5881
5882         # only test MDT0000
5883         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5884         local value
5885         for value in $(do_facet $SINGLEMDS \
5886                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5887                 param=$(echo ${value[0]} | cut -d "=" -f1)
5888                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5889
5890                 if $support_last_seq; then
5891                         param_seq=$(echo $param |
5892                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5893                         mds_last_seq=$(do_facet $SINGLEMDS \
5894                                        $LCTL get_param -n $param_seq)
5895                 fi
5896                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5897
5898                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5899                 node=$(facet_active_host ost$((ostnum+1)))
5900                 param="obdfilter.$ostname.last_id"
5901                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5902                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5903                         ost_last_id=$ost_last
5904
5905                         if $support_last_seq; then
5906                                 ost_last_id=$(echo $ost_last |
5907                                               awk -F':' '{print $2}' |
5908                                               sed -e "s/^0x//g")
5909                                 ost_last_seq=$(echo $ost_last |
5910                                                awk -F':' '{print $1}')
5911                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5912                         fi
5913
5914                         if [[ $ost_last_id != $mds_last ]]; then
5915                                 error "$ost_last_id != $mds_last"
5916                         else
5917                                 found=true
5918                                 break
5919                         fi
5920                 done
5921         done
5922         $found || error "can not match last_seq/last_id for $mdtosc"
5923         return 0
5924 }
5925 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5926
5927 test_54a() {
5928         perl -MSocket -e ';' || skip "no Socket perl module installed"
5929
5930         $SOCKETSERVER $DIR/socket ||
5931                 error "$SOCKETSERVER $DIR/socket failed: $?"
5932         $SOCKETCLIENT $DIR/socket ||
5933                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5934         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5935 }
5936 run_test 54a "unix domain socket test =========================="
5937
5938 test_54b() {
5939         f="$DIR/f54b"
5940         mknod $f c 1 3
5941         chmod 0666 $f
5942         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5943 }
5944 run_test 54b "char device works in lustre ======================"
5945
5946 find_loop_dev() {
5947         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5948         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5949         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5950
5951         for i in $(seq 3 7); do
5952                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5953                 LOOPDEV=$LOOPBASE$i
5954                 LOOPNUM=$i
5955                 break
5956         done
5957 }
5958
5959 cleanup_54c() {
5960         local rc=0
5961         loopdev="$DIR/loop54c"
5962
5963         trap 0
5964         $UMOUNT $DIR/$tdir || rc=$?
5965         losetup -d $loopdev || true
5966         losetup -d $LOOPDEV || true
5967         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5968         return $rc
5969 }
5970
5971 test_54c() {
5972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5973
5974         loopdev="$DIR/loop54c"
5975
5976         find_loop_dev
5977         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5978         trap cleanup_54c EXIT
5979         mknod $loopdev b 7 $LOOPNUM
5980         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5981         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5982         losetup $loopdev $DIR/$tfile ||
5983                 error "can't set up $loopdev for $DIR/$tfile"
5984         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5985         test_mkdir $DIR/$tdir
5986         mount -t ext2 $loopdev $DIR/$tdir ||
5987                 error "error mounting $loopdev on $DIR/$tdir"
5988         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5989                 error "dd write"
5990         df $DIR/$tdir
5991         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5992                 error "dd read"
5993         cleanup_54c
5994 }
5995 run_test 54c "block device works in lustre ====================="
5996
5997 test_54d() {
5998         f="$DIR/f54d"
5999         string="aaaaaa"
6000         mknod $f p
6001         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
6002 }
6003 run_test 54d "fifo device works in lustre ======================"
6004
6005 test_54e() {
6006         f="$DIR/f54e"
6007         string="aaaaaa"
6008         cp -aL /dev/console $f
6009         echo $string > $f || error "echo $string to $f failed"
6010 }
6011 run_test 54e "console/tty device works in lustre ======================"
6012
6013 test_56a() {
6014         local numfiles=3
6015         local numdirs=2
6016         local dir=$DIR/$tdir
6017
6018         rm -rf $dir
6019         test_mkdir -p $dir/dir
6020         for i in $(seq $numfiles); do
6021                 touch $dir/file$i
6022                 touch $dir/dir/file$i
6023         done
6024
6025         local numcomp=$($LFS getstripe --component-count $dir)
6026
6027         [[ $numcomp == 0 ]] && numcomp=1
6028
6029         # test lfs getstripe with --recursive
6030         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6031
6032         [[ $filenum -eq $((numfiles * 2)) ]] ||
6033                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6034         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6035         [[ $filenum -eq $numfiles ]] ||
6036                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6037         echo "$LFS getstripe showed obdidx or l_ost_idx"
6038
6039         # test lfs getstripe with file instead of dir
6040         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6041         [[ $filenum -eq 1 ]] ||
6042                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6043         echo "$LFS getstripe file1 passed"
6044
6045         #test lfs getstripe with --verbose
6046         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6047         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6048                 error "$LFS getstripe --verbose $dir: "\
6049                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6050         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6051                 error "$LFS getstripe $dir: showed lmm_magic"
6052
6053         #test lfs getstripe with -v prints lmm_fid
6054         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6055         local countfids=$((numdirs + numfiles * numcomp))
6056         [[ $filenum -eq $countfids ]] ||
6057                 error "$LFS getstripe -v $dir: "\
6058                       "got $filenum want $countfids lmm_fid"
6059         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6060                 error "$LFS getstripe $dir: showed lmm_fid by default"
6061         echo "$LFS getstripe --verbose passed"
6062
6063         #check for FID information
6064         local fid1=$($LFS getstripe --fid $dir/file1)
6065         local fid2=$($LFS getstripe --verbose $dir/file1 |
6066                      awk '/lmm_fid: / { print $2; exit; }')
6067         local fid3=$($LFS path2fid $dir/file1)
6068
6069         [ "$fid1" != "$fid2" ] &&
6070                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6071         [ "$fid1" != "$fid3" ] &&
6072                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6073         echo "$LFS getstripe --fid passed"
6074
6075         #test lfs getstripe with --obd
6076         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6077                 error "$LFS getstripe --obd wrong_uuid: should return error"
6078
6079         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6080
6081         local ostidx=1
6082         local obduuid=$(ostuuid_from_index $ostidx)
6083         local found=$($LFS getstripe -r --obd $obduuid $dir |
6084                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6085
6086         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6087         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6088                 ((filenum--))
6089         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6090                 ((filenum--))
6091
6092         [[ $found -eq $filenum ]] ||
6093                 error "$LFS getstripe --obd: found $found expect $filenum"
6094         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6095                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6096                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6097                 error "$LFS getstripe --obd: should not show file on other obd"
6098         echo "$LFS getstripe --obd passed"
6099 }
6100 run_test 56a "check $LFS getstripe"
6101
6102 test_56b() {
6103         local dir=$DIR/$tdir
6104         local numdirs=3
6105
6106         test_mkdir $dir
6107         for i in $(seq $numdirs); do
6108                 test_mkdir $dir/dir$i
6109         done
6110
6111         # test lfs getdirstripe default mode is non-recursion, which is
6112         # different from lfs getstripe
6113         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6114
6115         [[ $dircnt -eq 1 ]] ||
6116                 error "$LFS getdirstripe: found $dircnt, not 1"
6117         dircnt=$($LFS getdirstripe --recursive $dir |
6118                 grep -c lmv_stripe_count)
6119         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6120                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6121 }
6122 run_test 56b "check $LFS getdirstripe"
6123
6124 test_56c() {
6125         remote_ost_nodsh && skip "remote OST with nodsh"
6126
6127         local ost_idx=0
6128         local ost_name=$(ostname_from_index $ost_idx)
6129         local old_status=$(ost_dev_status $ost_idx)
6130         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6131
6132         [[ -z "$old_status" ]] ||
6133                 skip_env "OST $ost_name is in $old_status status"
6134
6135         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6136         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6137                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6138         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6139                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6140                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6141         fi
6142
6143         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6144                 error "$LFS df -v showing inactive devices"
6145         sleep_maxage
6146
6147         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6148
6149         [[ "$new_status" =~ "D" ]] ||
6150                 error "$ost_name status is '$new_status', missing 'D'"
6151         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6152                 [[ "$new_status" =~ "N" ]] ||
6153                         error "$ost_name status is '$new_status', missing 'N'"
6154         fi
6155         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6156                 [[ "$new_status" =~ "f" ]] ||
6157                         error "$ost_name status is '$new_status', missing 'f'"
6158         fi
6159
6160         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6161         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6162                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6163         [[ -z "$p" ]] && restore_lustre_params < $p || true
6164         sleep_maxage
6165
6166         new_status=$(ost_dev_status $ost_idx)
6167         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6168                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6169         # can't check 'f' as devices may actually be on flash
6170 }
6171 run_test 56c "check 'lfs df' showing device status"
6172
6173 test_56d() {
6174         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6175         local osts=$($LFS df -v $MOUNT | grep -c OST)
6176
6177         $LFS df $MOUNT
6178
6179         (( mdts == MDSCOUNT )) ||
6180                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6181         (( osts == OSTCOUNT )) ||
6182                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6183 }
6184 run_test 56d "'lfs df -v' prints only configured devices"
6185
6186 test_56e() {
6187         err_enoent=2 # No such file or directory
6188         err_eopnotsupp=95 # Operation not supported
6189
6190         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6191         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6192
6193         # Check for handling of path not exists
6194         output=$($LFS df $enoent_mnt 2>&1)
6195         ret=$?
6196
6197         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6198         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6199                 error "expect failure $err_enoent, not $ret"
6200
6201         # Check for handling of non-Lustre FS
6202         output=$($LFS df $notsup_mnt)
6203         ret=$?
6204
6205         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6206         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6207                 error "expect success $err_eopnotsupp, not $ret"
6208
6209         # Check for multiple LustreFS argument
6210         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6211         ret=$?
6212
6213         [[ $output -eq 3 && $ret -eq 0 ]] ||
6214                 error "expect success 3, not $output, rc = $ret"
6215
6216         # Check for correct non-Lustre FS handling among multiple
6217         # LustreFS argument
6218         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6219                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6220         ret=$?
6221
6222         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6223                 error "expect success 2, not $output, rc = $ret"
6224 }
6225 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6226
6227 NUMFILES=3
6228 NUMDIRS=3
6229 setup_56() {
6230         local local_tdir="$1"
6231         local local_numfiles="$2"
6232         local local_numdirs="$3"
6233         local dir_params="$4"
6234         local dir_stripe_params="$5"
6235
6236         if [ ! -d "$local_tdir" ] ; then
6237                 test_mkdir -p $dir_stripe_params $local_tdir
6238                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6239                 for i in $(seq $local_numfiles) ; do
6240                         touch $local_tdir/file$i
6241                 done
6242                 for i in $(seq $local_numdirs) ; do
6243                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6244                         for j in $(seq $local_numfiles) ; do
6245                                 touch $local_tdir/dir$i/file$j
6246                         done
6247                 done
6248         fi
6249 }
6250
6251 setup_56_special() {
6252         local local_tdir=$1
6253         local local_numfiles=$2
6254         local local_numdirs=$3
6255
6256         setup_56 $local_tdir $local_numfiles $local_numdirs
6257
6258         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6259                 for i in $(seq $local_numfiles) ; do
6260                         mknod $local_tdir/loop${i}b b 7 $i
6261                         mknod $local_tdir/null${i}c c 1 3
6262                         ln -s $local_tdir/file1 $local_tdir/link${i}
6263                 done
6264                 for i in $(seq $local_numdirs) ; do
6265                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6266                         mknod $local_tdir/dir$i/null${i}c c 1 3
6267                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6268                 done
6269         fi
6270 }
6271
6272 test_56g() {
6273         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6274         local expected=$(($NUMDIRS + 2))
6275
6276         setup_56 $dir $NUMFILES $NUMDIRS
6277
6278         # test lfs find with -name
6279         for i in $(seq $NUMFILES) ; do
6280                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6281
6282                 [ $nums -eq $expected ] ||
6283                         error "lfs find -name '*$i' $dir wrong: "\
6284                               "found $nums, expected $expected"
6285         done
6286 }
6287 run_test 56g "check lfs find -name"
6288
6289 test_56h() {
6290         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6291         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6292
6293         setup_56 $dir $NUMFILES $NUMDIRS
6294
6295         # test lfs find with ! -name
6296         for i in $(seq $NUMFILES) ; do
6297                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6298
6299                 [ $nums -eq $expected ] ||
6300                         error "lfs find ! -name '*$i' $dir wrong: "\
6301                               "found $nums, expected $expected"
6302         done
6303 }
6304 run_test 56h "check lfs find ! -name"
6305
6306 test_56i() {
6307         local dir=$DIR/$tdir
6308
6309         test_mkdir $dir
6310
6311         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6312         local out=$($cmd)
6313
6314         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6315 }
6316 run_test 56i "check 'lfs find -ost UUID' skips directories"
6317
6318 test_56j() {
6319         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6320
6321         setup_56_special $dir $NUMFILES $NUMDIRS
6322
6323         local expected=$((NUMDIRS + 1))
6324         local cmd="$LFS find -type d $dir"
6325         local nums=$($cmd | wc -l)
6326
6327         [ $nums -eq $expected ] ||
6328                 error "'$cmd' wrong: found $nums, expected $expected"
6329 }
6330 run_test 56j "check lfs find -type d"
6331
6332 test_56k() {
6333         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6334
6335         setup_56_special $dir $NUMFILES $NUMDIRS
6336
6337         local expected=$(((NUMDIRS + 1) * NUMFILES))
6338         local cmd="$LFS find -type f $dir"
6339         local nums=$($cmd | wc -l)
6340
6341         [ $nums -eq $expected ] ||
6342                 error "'$cmd' wrong: found $nums, expected $expected"
6343 }
6344 run_test 56k "check lfs find -type f"
6345
6346 test_56l() {
6347         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6348
6349         setup_56_special $dir $NUMFILES $NUMDIRS
6350
6351         local expected=$((NUMDIRS + NUMFILES))
6352         local cmd="$LFS find -type b $dir"
6353         local nums=$($cmd | wc -l)
6354
6355         [ $nums -eq $expected ] ||
6356                 error "'$cmd' wrong: found $nums, expected $expected"
6357 }
6358 run_test 56l "check lfs find -type b"
6359
6360 test_56m() {
6361         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6362
6363         setup_56_special $dir $NUMFILES $NUMDIRS
6364
6365         local expected=$((NUMDIRS + NUMFILES))
6366         local cmd="$LFS find -type c $dir"
6367         local nums=$($cmd | wc -l)
6368         [ $nums -eq $expected ] ||
6369                 error "'$cmd' wrong: found $nums, expected $expected"
6370 }
6371 run_test 56m "check lfs find -type c"
6372
6373 test_56n() {
6374         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6375         setup_56_special $dir $NUMFILES $NUMDIRS
6376
6377         local expected=$((NUMDIRS + NUMFILES))
6378         local cmd="$LFS find -type l $dir"
6379         local nums=$($cmd | wc -l)
6380
6381         [ $nums -eq $expected ] ||
6382                 error "'$cmd' wrong: found $nums, expected $expected"
6383 }
6384 run_test 56n "check lfs find -type l"
6385
6386 test_56o() {
6387         local dir=$DIR/$tdir
6388
6389         setup_56 $dir $NUMFILES $NUMDIRS
6390         utime $dir/file1 > /dev/null || error "utime (1)"
6391         utime $dir/file2 > /dev/null || error "utime (2)"
6392         utime $dir/dir1 > /dev/null || error "utime (3)"
6393         utime $dir/dir2 > /dev/null || error "utime (4)"
6394         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6395         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6396
6397         local expected=4
6398         local nums=$($LFS find -mtime +0 $dir | wc -l)
6399
6400         [ $nums -eq $expected ] ||
6401                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6402
6403         expected=12
6404         cmd="$LFS find -mtime 0 $dir"
6405         nums=$($cmd | wc -l)
6406         [ $nums -eq $expected ] ||
6407                 error "'$cmd' wrong: found $nums, expected $expected"
6408 }
6409 run_test 56o "check lfs find -mtime for old files"
6410
6411 test_56ob() {
6412         local dir=$DIR/$tdir
6413         local expected=1
6414         local count=0
6415
6416         # just to make sure there is something that won't be found
6417         test_mkdir $dir
6418         touch $dir/$tfile.now
6419
6420         for age in year week day hour min; do
6421                 count=$((count + 1))
6422
6423                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6424                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6425                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6426
6427                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6428                 local nums=$($cmd | wc -l)
6429                 [ $nums -eq $expected ] ||
6430                         error "'$cmd' wrong: found $nums, expected $expected"
6431
6432                 cmd="$LFS find $dir -atime $count${age:0:1}"
6433                 nums=$($cmd | wc -l)
6434                 [ $nums -eq $expected ] ||
6435                         error "'$cmd' wrong: found $nums, expected $expected"
6436         done
6437
6438         sleep 2
6439         cmd="$LFS find $dir -ctime +1s -type f"
6440         nums=$($cmd | wc -l)
6441         (( $nums == $count * 2 + 1)) ||
6442                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6443 }
6444 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6445
6446 test_newerXY_base() {
6447         local x=$1
6448         local y=$2
6449         local dir=$DIR/$tdir
6450         local ref
6451         local negref
6452
6453         if [ $y == "t" ]; then
6454                 if [ $x == "b" ]; then
6455                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6456                 else
6457                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6458                 fi
6459         else
6460                 ref=$DIR/$tfile.newer.$x$y
6461                 touch $ref || error "touch $ref failed"
6462         fi
6463
6464         echo "before = $ref"
6465         sleep 2
6466         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6467         sleep 2
6468         if [ $y == "t" ]; then
6469                 if [ $x == "b" ]; then
6470                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6471                 else
6472                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6473                 fi
6474         else
6475                 negref=$DIR/$tfile.negnewer.$x$y
6476                 touch $negref || error "touch $negref failed"
6477         fi
6478
6479         echo "after = $negref"
6480         local cmd="$LFS find $dir -newer$x$y $ref"
6481         local nums=$(eval $cmd | wc -l)
6482         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6483
6484         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6485                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6486
6487         cmd="$LFS find $dir ! -newer$x$y $negref"
6488         nums=$(eval $cmd | wc -l)
6489         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6490                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6491
6492         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6493         nums=$(eval $cmd | wc -l)
6494         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6495                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6496
6497         rm -rf $DIR/*
6498 }
6499
6500 test_56oc() {
6501         test_newerXY_base "a" "a"
6502         test_newerXY_base "a" "m"
6503         test_newerXY_base "a" "c"
6504         test_newerXY_base "m" "a"
6505         test_newerXY_base "m" "m"
6506         test_newerXY_base "m" "c"
6507         test_newerXY_base "c" "a"
6508         test_newerXY_base "c" "m"
6509         test_newerXY_base "c" "c"
6510
6511         [[ -n "$sles_version" ]] &&
6512                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6513
6514         test_newerXY_base "a" "t"
6515         test_newerXY_base "m" "t"
6516         test_newerXY_base "c" "t"
6517
6518         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6519            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6520                 ! btime_supported && echo "btime unsupported" && return 0
6521
6522         test_newerXY_base "b" "b"
6523         test_newerXY_base "b" "t"
6524 }
6525 run_test 56oc "check lfs find -newerXY work"
6526
6527 btime_supported() {
6528         local dir=$DIR/$tdir
6529         local rc
6530
6531         mkdir -p $dir
6532         touch $dir/$tfile
6533         $LFS find $dir -btime -1d -type f
6534         rc=$?
6535         rm -rf $dir
6536         return $rc
6537 }
6538
6539 test_56od() {
6540         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6541                 ! btime_supported && skip "btime unsupported on MDS"
6542
6543         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6544                 ! btime_supported && skip "btime unsupported on clients"
6545
6546         local dir=$DIR/$tdir
6547         local ref=$DIR/$tfile.ref
6548         local negref=$DIR/$tfile.negref
6549
6550         mkdir $dir || error "mkdir $dir failed"
6551         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6552         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6553         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6554         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6555         touch $ref || error "touch $ref failed"
6556         # sleep 3 seconds at least
6557         sleep 3
6558
6559         local before=$(do_facet mds1 date +%s)
6560         local skew=$(($(date +%s) - before + 1))
6561
6562         if (( skew < 0 && skew > -5 )); then
6563                 sleep $((0 - skew + 1))
6564                 skew=0
6565         fi
6566
6567         # Set the dir stripe params to limit files all on MDT0,
6568         # otherwise we need to calc the max clock skew between
6569         # the client and MDTs.
6570         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6571         sleep 2
6572         touch $negref || error "touch $negref failed"
6573
6574         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6575         local nums=$($cmd | wc -l)
6576         local expected=$(((NUMFILES + 1) * NUMDIRS))
6577
6578         [ $nums -eq $expected ] ||
6579                 error "'$cmd' wrong: found $nums, expected $expected"
6580
6581         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6582         nums=$($cmd | wc -l)
6583         expected=$((NUMFILES + 1))
6584         [ $nums -eq $expected ] ||
6585                 error "'$cmd' wrong: found $nums, expected $expected"
6586
6587         [ $skew -lt 0 ] && return
6588
6589         local after=$(do_facet mds1 date +%s)
6590         local age=$((after - before + 1 + skew))
6591
6592         cmd="$LFS find $dir -btime -${age}s -type f"
6593         nums=$($cmd | wc -l)
6594         expected=$(((NUMFILES + 1) * NUMDIRS))
6595
6596         echo "Clock skew between client and server: $skew, age:$age"
6597         [ $nums -eq $expected ] ||
6598                 error "'$cmd' wrong: found $nums, expected $expected"
6599
6600         expected=$(($NUMDIRS + 1))
6601         cmd="$LFS find $dir -btime -${age}s -type d"
6602         nums=$($cmd | wc -l)
6603         [ $nums -eq $expected ] ||
6604                 error "'$cmd' wrong: found $nums, expected $expected"
6605         rm -f $ref $negref || error "Failed to remove $ref $negref"
6606 }
6607 run_test 56od "check lfs find -btime with units"
6608
6609 test_56p() {
6610         [ $RUNAS_ID -eq $UID ] &&
6611                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6612
6613         local dir=$DIR/$tdir
6614
6615         setup_56 $dir $NUMFILES $NUMDIRS
6616         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6617
6618         local expected=$NUMFILES
6619         local cmd="$LFS find -uid $RUNAS_ID $dir"
6620         local nums=$($cmd | wc -l)
6621
6622         [ $nums -eq $expected ] ||
6623                 error "'$cmd' wrong: found $nums, expected $expected"
6624
6625         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6626         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6627         nums=$($cmd | wc -l)
6628         [ $nums -eq $expected ] ||
6629                 error "'$cmd' wrong: found $nums, expected $expected"
6630 }
6631 run_test 56p "check lfs find -uid and ! -uid"
6632
6633 test_56q() {
6634         [ $RUNAS_ID -eq $UID ] &&
6635                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6636
6637         local dir=$DIR/$tdir
6638
6639         setup_56 $dir $NUMFILES $NUMDIRS
6640         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6641
6642         local expected=$NUMFILES
6643         local cmd="$LFS find -gid $RUNAS_GID $dir"
6644         local nums=$($cmd | wc -l)
6645
6646         [ $nums -eq $expected ] ||
6647                 error "'$cmd' wrong: found $nums, expected $expected"
6648
6649         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6650         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6651         nums=$($cmd | wc -l)
6652         [ $nums -eq $expected ] ||
6653                 error "'$cmd' wrong: found $nums, expected $expected"
6654 }
6655 run_test 56q "check lfs find -gid and ! -gid"
6656
6657 test_56r() {
6658         local dir=$DIR/$tdir
6659
6660         setup_56 $dir $NUMFILES $NUMDIRS
6661
6662         local expected=12
6663         local cmd="$LFS find -size 0 -type f -lazy $dir"
6664         local nums=$($cmd | wc -l)
6665
6666         [ $nums -eq $expected ] ||
6667                 error "'$cmd' wrong: found $nums, expected $expected"
6668         cmd="$LFS find -size 0 -type f $dir"
6669         nums=$($cmd | wc -l)
6670         [ $nums -eq $expected ] ||
6671                 error "'$cmd' wrong: found $nums, expected $expected"
6672
6673         expected=0
6674         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6675         nums=$($cmd | wc -l)
6676         [ $nums -eq $expected ] ||
6677                 error "'$cmd' wrong: found $nums, expected $expected"
6678         cmd="$LFS find ! -size 0 -type f $dir"
6679         nums=$($cmd | wc -l)
6680         [ $nums -eq $expected ] ||
6681                 error "'$cmd' wrong: found $nums, expected $expected"
6682
6683         echo "test" > $dir/$tfile
6684         echo "test2" > $dir/$tfile.2 && sync
6685         expected=1
6686         cmd="$LFS find -size 5 -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 5 -type f $dir"
6691         nums=$($cmd | wc -l)
6692         [ $nums -eq $expected ] ||
6693                 error "'$cmd' wrong: found $nums, expected $expected"
6694
6695         expected=1
6696         cmd="$LFS find -size +5 -type f -lazy $dir"
6697         nums=$($cmd | wc -l)
6698         [ $nums -eq $expected ] ||
6699                 error "'$cmd' wrong: found $nums, expected $expected"
6700         cmd="$LFS find -size +5 -type f $dir"
6701         nums=$($cmd | wc -l)
6702         [ $nums -eq $expected ] ||
6703                 error "'$cmd' wrong: found $nums, expected $expected"
6704
6705         expected=2
6706         cmd="$LFS find -size +0 -type f -lazy $dir"
6707         nums=$($cmd | wc -l)
6708         [ $nums -eq $expected ] ||
6709                 error "'$cmd' wrong: found $nums, expected $expected"
6710         cmd="$LFS find -size +0 -type f $dir"
6711         nums=$($cmd | wc -l)
6712         [ $nums -eq $expected ] ||
6713                 error "'$cmd' wrong: found $nums, expected $expected"
6714
6715         expected=2
6716         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6717         nums=$($cmd | wc -l)
6718         [ $nums -eq $expected ] ||
6719                 error "'$cmd' wrong: found $nums, expected $expected"
6720         cmd="$LFS find ! -size -5 -type f $dir"
6721         nums=$($cmd | wc -l)
6722         [ $nums -eq $expected ] ||
6723                 error "'$cmd' wrong: found $nums, expected $expected"
6724
6725         expected=12
6726         cmd="$LFS find -size -5 -type f -lazy $dir"
6727         nums=$($cmd | wc -l)
6728         [ $nums -eq $expected ] ||
6729                 error "'$cmd' wrong: found $nums, expected $expected"
6730         cmd="$LFS find -size -5 -type f $dir"
6731         nums=$($cmd | wc -l)
6732         [ $nums -eq $expected ] ||
6733                 error "'$cmd' wrong: found $nums, expected $expected"
6734 }
6735 run_test 56r "check lfs find -size works"
6736
6737 test_56ra_sub() {
6738         local expected=$1
6739         local glimpses=$2
6740         local cmd="$3"
6741
6742         cancel_lru_locks $OSC
6743
6744         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6745         local nums=$($cmd | wc -l)
6746
6747         [ $nums -eq $expected ] ||
6748                 error "'$cmd' wrong: found $nums, expected $expected"
6749
6750         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6751
6752         if (( rpcs_before + glimpses != rpcs_after )); then
6753                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6754                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6755
6756                 if [[ $glimpses == 0 ]]; then
6757                         error "'$cmd' should not send glimpse RPCs to OST"
6758                 else
6759                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6760                 fi
6761         fi
6762 }
6763
6764 test_56ra() {
6765         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6766                 skip "MDS < 2.12.58 doesn't return LSOM data"
6767         local dir=$DIR/$tdir
6768         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6769
6770         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6771
6772         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6773         $LCTL set_param -n llite.*.statahead_agl=0
6774         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6775
6776         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6777         # open and close all files to ensure LSOM is updated
6778         cancel_lru_locks $OSC
6779         find $dir -type f | xargs cat > /dev/null
6780
6781         #   expect_found  glimpse_rpcs  command_to_run
6782         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6783         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6784         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6785         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6786
6787         echo "test" > $dir/$tfile
6788         echo "test2" > $dir/$tfile.2 && sync
6789         cancel_lru_locks $OSC
6790         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6791
6792         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6793         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6794         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6795         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6796
6797         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6798         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6799         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6800         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6801         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6802         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6803 }
6804 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6805
6806 test_56rb() {
6807         local dir=$DIR/$tdir
6808         local tmp=$TMP/$tfile.log
6809         local mdt_idx;
6810
6811         test_mkdir -p $dir || error "failed to mkdir $dir"
6812         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6813                 error "failed to setstripe $dir/$tfile"
6814         mdt_idx=$($LFS getdirstripe -i $dir)
6815         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6816
6817         stack_trap "rm -f $tmp" EXIT
6818         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6819         ! grep -q obd_uuid $tmp ||
6820                 error "failed to find --size +100K --ost 0 $dir"
6821         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6822         ! grep -q obd_uuid $tmp ||
6823                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6824 }
6825 run_test 56rb "check lfs find --size --ost/--mdt works"
6826
6827 test_56rc() {
6828         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6829         local dir=$DIR/$tdir
6830         local found
6831
6832         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6833         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6834         (( $MDSCOUNT > 2 )) &&
6835                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6836         mkdir $dir/$tdir-{1..10}
6837         touch $dir/$tfile-{1..10}
6838
6839         found=$($LFS find $dir --mdt-count 2 | wc -l)
6840         expect=11
6841         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6842
6843         found=$($LFS find $dir -T +1 | wc -l)
6844         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6845         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6846
6847         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6848         expect=11
6849         (( $found == $expect )) || error "found $found all_char, expect $expect"
6850
6851         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
6852         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
6853         (( $found == $expect )) || error "found $found all_char, expect $expect"
6854 }
6855 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
6856
6857 test_56s() { # LU-611 #LU-9369
6858         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6859
6860         local dir=$DIR/$tdir
6861         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6862
6863         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6864         for i in $(seq $NUMDIRS); do
6865                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6866         done
6867
6868         local expected=$NUMDIRS
6869         local cmd="$LFS find -c $OSTCOUNT $dir"
6870         local nums=$($cmd | wc -l)
6871
6872         [ $nums -eq $expected ] || {
6873                 $LFS getstripe -R $dir
6874                 error "'$cmd' wrong: found $nums, expected $expected"
6875         }
6876
6877         expected=$((NUMDIRS + onestripe))
6878         cmd="$LFS find -stripe-count +0 -type f $dir"
6879         nums=$($cmd | wc -l)
6880         [ $nums -eq $expected ] || {
6881                 $LFS getstripe -R $dir
6882                 error "'$cmd' wrong: found $nums, expected $expected"
6883         }
6884
6885         expected=$onestripe
6886         cmd="$LFS find -stripe-count 1 -type f $dir"
6887         nums=$($cmd | wc -l)
6888         [ $nums -eq $expected ] || {
6889                 $LFS getstripe -R $dir
6890                 error "'$cmd' wrong: found $nums, expected $expected"
6891         }
6892
6893         cmd="$LFS find -stripe-count -2 -type f $dir"
6894         nums=$($cmd | wc -l)
6895         [ $nums -eq $expected ] || {
6896                 $LFS getstripe -R $dir
6897                 error "'$cmd' wrong: found $nums, expected $expected"
6898         }
6899
6900         expected=0
6901         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6902         nums=$($cmd | wc -l)
6903         [ $nums -eq $expected ] || {
6904                 $LFS getstripe -R $dir
6905                 error "'$cmd' wrong: found $nums, expected $expected"
6906         }
6907 }
6908 run_test 56s "check lfs find -stripe-count works"
6909
6910 test_56t() { # LU-611 #LU-9369
6911         local dir=$DIR/$tdir
6912
6913         setup_56 $dir 0 $NUMDIRS
6914         for i in $(seq $NUMDIRS); do
6915                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6916         done
6917
6918         local expected=$NUMDIRS
6919         local cmd="$LFS find -S 8M $dir"
6920         local nums=$($cmd | wc -l)
6921
6922         [ $nums -eq $expected ] || {
6923                 $LFS getstripe -R $dir
6924                 error "'$cmd' wrong: found $nums, expected $expected"
6925         }
6926         rm -rf $dir
6927
6928         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6929
6930         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6931
6932         expected=$(((NUMDIRS + 1) * NUMFILES))
6933         cmd="$LFS find -stripe-size 512k -type f $dir"
6934         nums=$($cmd | wc -l)
6935         [ $nums -eq $expected ] ||
6936                 error "'$cmd' wrong: found $nums, expected $expected"
6937
6938         cmd="$LFS find -stripe-size +320k -type f $dir"
6939         nums=$($cmd | wc -l)
6940         [ $nums -eq $expected ] ||
6941                 error "'$cmd' wrong: found $nums, expected $expected"
6942
6943         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6944         cmd="$LFS find -stripe-size +200k -type f $dir"
6945         nums=$($cmd | wc -l)
6946         [ $nums -eq $expected ] ||
6947                 error "'$cmd' wrong: found $nums, expected $expected"
6948
6949         cmd="$LFS find -stripe-size -640k -type f $dir"
6950         nums=$($cmd | wc -l)
6951         [ $nums -eq $expected ] ||
6952                 error "'$cmd' wrong: found $nums, expected $expected"
6953
6954         expected=4
6955         cmd="$LFS find -stripe-size 256k -type f $dir"
6956         nums=$($cmd | wc -l)
6957         [ $nums -eq $expected ] ||
6958                 error "'$cmd' wrong: found $nums, expected $expected"
6959
6960         cmd="$LFS find -stripe-size -320k -type f $dir"
6961         nums=$($cmd | wc -l)
6962         [ $nums -eq $expected ] ||
6963                 error "'$cmd' wrong: found $nums, expected $expected"
6964
6965         expected=0
6966         cmd="$LFS find -stripe-size 1024k -type f $dir"
6967         nums=$($cmd | wc -l)
6968         [ $nums -eq $expected ] ||
6969                 error "'$cmd' wrong: found $nums, expected $expected"
6970 }
6971 run_test 56t "check lfs find -stripe-size works"
6972
6973 test_56u() { # LU-611
6974         local dir=$DIR/$tdir
6975
6976         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6977
6978         if [[ $OSTCOUNT -gt 1 ]]; then
6979                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6980                 onestripe=4
6981         else
6982                 onestripe=0
6983         fi
6984
6985         local expected=$(((NUMDIRS + 1) * NUMFILES))
6986         local cmd="$LFS find -stripe-index 0 -type f $dir"
6987         local nums=$($cmd | wc -l)
6988
6989         [ $nums -eq $expected ] ||
6990                 error "'$cmd' wrong: found $nums, expected $expected"
6991
6992         expected=$onestripe
6993         cmd="$LFS find -stripe-index 1 -type f $dir"
6994         nums=$($cmd | wc -l)
6995         [ $nums -eq $expected ] ||
6996                 error "'$cmd' wrong: found $nums, expected $expected"
6997
6998         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6999         nums=$($cmd | wc -l)
7000         [ $nums -eq $expected ] ||
7001                 error "'$cmd' wrong: found $nums, expected $expected"
7002
7003         expected=0
7004         # This should produce an error and not return any files
7005         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7006         nums=$($cmd 2>/dev/null | wc -l)
7007         [ $nums -eq $expected ] ||
7008                 error "'$cmd' wrong: found $nums, expected $expected"
7009
7010         if [[ $OSTCOUNT -gt 1 ]]; then
7011                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7012                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7013                 nums=$($cmd | wc -l)
7014                 [ $nums -eq $expected ] ||
7015                         error "'$cmd' wrong: found $nums, expected $expected"
7016         fi
7017 }
7018 run_test 56u "check lfs find -stripe-index works"
7019
7020 test_56v() {
7021         local mdt_idx=0
7022         local dir=$DIR/$tdir
7023
7024         setup_56 $dir $NUMFILES $NUMDIRS
7025
7026         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7027         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7028
7029         for file in $($LFS find -m $UUID $dir); do
7030                 file_midx=$($LFS getstripe -m $file)
7031                 [ $file_midx -eq $mdt_idx ] ||
7032                         error "lfs find -m $UUID != getstripe -m $file_midx"
7033         done
7034 }
7035 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7036
7037 test_56w() {
7038         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7040
7041         local dir=$DIR/$tdir
7042
7043         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7044
7045         local stripe_size=$($LFS getstripe -S -d $dir) ||
7046                 error "$LFS getstripe -S -d $dir failed"
7047         stripe_size=${stripe_size%% *}
7048
7049         local file_size=$((stripe_size * OSTCOUNT))
7050         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7051         local required_space=$((file_num * file_size))
7052         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7053                            head -n1)
7054         [[ $free_space -le $((required_space / 1024)) ]] &&
7055                 skip_env "need $required_space, have $free_space kbytes"
7056
7057         local dd_bs=65536
7058         local dd_count=$((file_size / dd_bs))
7059
7060         # write data into the files
7061         local i
7062         local j
7063         local file
7064
7065         for i in $(seq $NUMFILES); do
7066                 file=$dir/file$i
7067                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7068                         error "write data into $file failed"
7069         done
7070         for i in $(seq $NUMDIRS); do
7071                 for j in $(seq $NUMFILES); do
7072                         file=$dir/dir$i/file$j
7073                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7074                                 error "write data into $file failed"
7075                 done
7076         done
7077
7078         # $LFS_MIGRATE will fail if hard link migration is unsupported
7079         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7080                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7081                         error "creating links to $dir/dir1/file1 failed"
7082         fi
7083
7084         local expected=-1
7085
7086         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7087
7088         # lfs_migrate file
7089         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7090
7091         echo "$cmd"
7092         eval $cmd || error "$cmd failed"
7093
7094         check_stripe_count $dir/file1 $expected
7095
7096         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7097         then
7098                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7099                 # OST 1 if it is on OST 0. This file is small enough to
7100                 # be on only one stripe.
7101                 file=$dir/migr_1_ost
7102                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7103                         error "write data into $file failed"
7104                 local obdidx=$($LFS getstripe -i $file)
7105                 local oldmd5=$(md5sum $file)
7106                 local newobdidx=0
7107
7108                 [[ $obdidx -eq 0 ]] && newobdidx=1
7109                 cmd="$LFS migrate -i $newobdidx $file"
7110                 echo $cmd
7111                 eval $cmd || error "$cmd failed"
7112
7113                 local realobdix=$($LFS getstripe -i $file)
7114                 local newmd5=$(md5sum $file)
7115
7116                 [[ $newobdidx -ne $realobdix ]] &&
7117                         error "new OST is different (was=$obdidx, "\
7118                               "wanted=$newobdidx, got=$realobdix)"
7119                 [[ "$oldmd5" != "$newmd5" ]] &&
7120                         error "md5sum differ: $oldmd5, $newmd5"
7121         fi
7122
7123         # lfs_migrate dir
7124         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7125         echo "$cmd"
7126         eval $cmd || error "$cmd failed"
7127
7128         for j in $(seq $NUMFILES); do
7129                 check_stripe_count $dir/dir1/file$j $expected
7130         done
7131
7132         # lfs_migrate works with lfs find
7133         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7134              $LFS_MIGRATE -y -c $expected"
7135         echo "$cmd"
7136         eval $cmd || error "$cmd failed"
7137
7138         for i in $(seq 2 $NUMFILES); do
7139                 check_stripe_count $dir/file$i $expected
7140         done
7141         for i in $(seq 2 $NUMDIRS); do
7142                 for j in $(seq $NUMFILES); do
7143                 check_stripe_count $dir/dir$i/file$j $expected
7144                 done
7145         done
7146 }
7147 run_test 56w "check lfs_migrate -c stripe_count works"
7148
7149 test_56wb() {
7150         local file1=$DIR/$tdir/file1
7151         local create_pool=false
7152         local initial_pool=$($LFS getstripe -p $DIR)
7153         local pool_list=()
7154         local pool=""
7155
7156         echo -n "Creating test dir..."
7157         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7158         echo "done."
7159
7160         echo -n "Creating test file..."
7161         touch $file1 || error "cannot create file"
7162         echo "done."
7163
7164         echo -n "Detecting existing pools..."
7165         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7166
7167         if [ ${#pool_list[@]} -gt 0 ]; then
7168                 echo "${pool_list[@]}"
7169                 for thispool in "${pool_list[@]}"; do
7170                         if [[ -z "$initial_pool" ||
7171                               "$initial_pool" != "$thispool" ]]; then
7172                                 pool="$thispool"
7173                                 echo "Using existing pool '$pool'"
7174                                 break
7175                         fi
7176                 done
7177         else
7178                 echo "none detected."
7179         fi
7180         if [ -z "$pool" ]; then
7181                 pool=${POOL:-testpool}
7182                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7183                 echo -n "Creating pool '$pool'..."
7184                 create_pool=true
7185                 pool_add $pool &> /dev/null ||
7186                         error "pool_add failed"
7187                 echo "done."
7188
7189                 echo -n "Adding target to pool..."
7190                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7191                         error "pool_add_targets failed"
7192                 echo "done."
7193         fi
7194
7195         echo -n "Setting pool using -p option..."
7196         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7197                 error "migrate failed rc = $?"
7198         echo "done."
7199
7200         echo -n "Verifying test file is in pool after migrating..."
7201         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7202                 error "file was not migrated to pool $pool"
7203         echo "done."
7204
7205         echo -n "Removing test file from pool '$pool'..."
7206         # "lfs migrate $file" won't remove the file from the pool
7207         # until some striping information is changed.
7208         $LFS migrate -c 1 $file1 &> /dev/null ||
7209                 error "cannot remove from pool"
7210         [ "$($LFS getstripe -p $file1)" ] &&
7211                 error "pool still set"
7212         echo "done."
7213
7214         echo -n "Setting pool using --pool option..."
7215         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7216                 error "migrate failed rc = $?"
7217         echo "done."
7218
7219         # Clean up
7220         rm -f $file1
7221         if $create_pool; then
7222                 destroy_test_pools 2> /dev/null ||
7223                         error "destroy test pools failed"
7224         fi
7225 }
7226 run_test 56wb "check lfs_migrate pool support"
7227
7228 test_56wc() {
7229         local file1="$DIR/$tdir/file1"
7230         local parent_ssize
7231         local parent_scount
7232         local cur_ssize
7233         local cur_scount
7234         local orig_ssize
7235
7236         echo -n "Creating test dir..."
7237         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7238         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7239                 error "cannot set stripe by '-S 1M -c 1'"
7240         echo "done"
7241
7242         echo -n "Setting initial stripe for test file..."
7243         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7244                 error "cannot set stripe"
7245         cur_ssize=$($LFS getstripe -S "$file1")
7246         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7247         echo "done."
7248
7249         # File currently set to -S 512K -c 1
7250
7251         # Ensure -c and -S options are rejected when -R is set
7252         echo -n "Verifying incompatible options are detected..."
7253         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7254                 error "incompatible -c and -R options not detected"
7255         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7256                 error "incompatible -S and -R options not detected"
7257         echo "done."
7258
7259         # Ensure unrecognized options are passed through to 'lfs migrate'
7260         echo -n "Verifying -S option is passed through to lfs migrate..."
7261         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7262                 error "migration failed"
7263         cur_ssize=$($LFS getstripe -S "$file1")
7264         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7265         echo "done."
7266
7267         # File currently set to -S 1M -c 1
7268
7269         # Ensure long options are supported
7270         echo -n "Verifying long options supported..."
7271         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7272                 error "long option without argument not supported"
7273         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7274                 error "long option with argument not supported"
7275         cur_ssize=$($LFS getstripe -S "$file1")
7276         [ $cur_ssize -eq 524288 ] ||
7277                 error "migrate --stripe-size $cur_ssize != 524288"
7278         echo "done."
7279
7280         # File currently set to -S 512K -c 1
7281
7282         if [ "$OSTCOUNT" -gt 1 ]; then
7283                 echo -n "Verifying explicit stripe count can be set..."
7284                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7285                         error "migrate failed"
7286                 cur_scount=$($LFS getstripe -c "$file1")
7287                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7288                 echo "done."
7289         fi
7290
7291         # File currently set to -S 512K -c 1 or -S 512K -c 2
7292
7293         # Ensure parent striping is used if -R is set, and no stripe
7294         # count or size is specified
7295         echo -n "Setting stripe for parent directory..."
7296         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7297                 error "cannot set stripe '-S 2M -c 1'"
7298         echo "done."
7299
7300         echo -n "Verifying restripe option uses parent stripe settings..."
7301         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7302         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7303         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7304                 error "migrate failed"
7305         cur_ssize=$($LFS getstripe -S "$file1")
7306         [ $cur_ssize -eq $parent_ssize ] ||
7307                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7308         cur_scount=$($LFS getstripe -c "$file1")
7309         [ $cur_scount -eq $parent_scount ] ||
7310                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7311         echo "done."
7312
7313         # File currently set to -S 1M -c 1
7314
7315         # Ensure striping is preserved if -R is not set, and no stripe
7316         # count or size is specified
7317         echo -n "Verifying striping size preserved when not specified..."
7318         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7319         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7320                 error "cannot set stripe on parent directory"
7321         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7322                 error "migrate failed"
7323         cur_ssize=$($LFS getstripe -S "$file1")
7324         [ $cur_ssize -eq $orig_ssize ] ||
7325                 error "migrate by default $cur_ssize != $orig_ssize"
7326         echo "done."
7327
7328         # Ensure file name properly detected when final option has no argument
7329         echo -n "Verifying file name properly detected..."
7330         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7331                 error "file name interpreted as option argument"
7332         echo "done."
7333
7334         # Clean up
7335         rm -f "$file1"
7336 }
7337 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7338
7339 test_56wd() {
7340         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7341
7342         local file1=$DIR/$tdir/file1
7343
7344         echo -n "Creating test dir..."
7345         test_mkdir $DIR/$tdir || error "cannot create dir"
7346         echo "done."
7347
7348         echo -n "Creating test file..."
7349         touch $file1
7350         echo "done."
7351
7352         # Ensure 'lfs migrate' will fail by using a non-existent option,
7353         # and make sure rsync is not called to recover
7354         echo -n "Make sure --no-rsync option works..."
7355         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7356                 grep -q 'refusing to fall back to rsync' ||
7357                 error "rsync was called with --no-rsync set"
7358         echo "done."
7359
7360         # Ensure rsync is called without trying 'lfs migrate' first
7361         echo -n "Make sure --rsync option works..."
7362         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7363                 grep -q 'falling back to rsync' &&
7364                 error "lfs migrate was called with --rsync set"
7365         echo "done."
7366
7367         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7368         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7369                 grep -q 'at the same time' ||
7370                 error "--rsync and --no-rsync accepted concurrently"
7371         echo "done."
7372
7373         # Clean up
7374         rm -f $file1
7375 }
7376 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7377
7378 test_56we() {
7379         local td=$DIR/$tdir
7380         local tf=$td/$tfile
7381
7382         test_mkdir $td || error "cannot create $td"
7383         touch $tf || error "cannot touch $tf"
7384
7385         echo -n "Make sure --non-direct|-D works..."
7386         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7387                 grep -q "lfs migrate --non-direct" ||
7388                 error "--non-direct option cannot work correctly"
7389         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7390                 grep -q "lfs migrate -D" ||
7391                 error "-D option cannot work correctly"
7392         echo "done."
7393 }
7394 run_test 56we "check lfs_migrate --non-direct|-D support"
7395
7396 test_56x() {
7397         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7398         check_swap_layouts_support
7399
7400         local dir=$DIR/$tdir
7401         local ref1=/etc/passwd
7402         local file1=$dir/file1
7403
7404         test_mkdir $dir || error "creating dir $dir"
7405         $LFS setstripe -c 2 $file1
7406         cp $ref1 $file1
7407         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7408         stripe=$($LFS getstripe -c $file1)
7409         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7410         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7411
7412         # clean up
7413         rm -f $file1
7414 }
7415 run_test 56x "lfs migration support"
7416
7417 test_56xa() {
7418         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7419         check_swap_layouts_support
7420
7421         local dir=$DIR/$tdir/$testnum
7422
7423         test_mkdir -p $dir
7424
7425         local ref1=/etc/passwd
7426         local file1=$dir/file1
7427
7428         $LFS setstripe -c 2 $file1
7429         cp $ref1 $file1
7430         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7431
7432         local stripe=$($LFS getstripe -c $file1)
7433
7434         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7435         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7436
7437         # clean up
7438         rm -f $file1
7439 }
7440 run_test 56xa "lfs migration --block support"
7441
7442 check_migrate_links() {
7443         local dir="$1"
7444         local file1="$dir/file1"
7445         local begin="$2"
7446         local count="$3"
7447         local runas="$4"
7448         local total_count=$(($begin + $count - 1))
7449         local symlink_count=10
7450         local uniq_count=10
7451
7452         if [ ! -f "$file1" ]; then
7453                 echo -n "creating initial file..."
7454                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7455                         error "cannot setstripe initial file"
7456                 echo "done"
7457
7458                 echo -n "creating symlinks..."
7459                 for s in $(seq 1 $symlink_count); do
7460                         ln -s "$file1" "$dir/slink$s" ||
7461                                 error "cannot create symlinks"
7462                 done
7463                 echo "done"
7464
7465                 echo -n "creating nonlinked files..."
7466                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7467                         error "cannot create nonlinked files"
7468                 echo "done"
7469         fi
7470
7471         # create hard links
7472         if [ ! -f "$dir/file$total_count" ]; then
7473                 echo -n "creating hard links $begin:$total_count..."
7474                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7475                         /dev/null || error "cannot create hard links"
7476                 echo "done"
7477         fi
7478
7479         echo -n "checking number of hard links listed in xattrs..."
7480         local fid=$($LFS getstripe -F "$file1")
7481         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7482
7483         echo "${#paths[*]}"
7484         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7485                         skip "hard link list has unexpected size, skipping test"
7486         fi
7487         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7488                         error "link names should exceed xattrs size"
7489         fi
7490
7491         echo -n "migrating files..."
7492         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7493         local rc=$?
7494         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7495         echo "done"
7496
7497         # make sure all links have been properly migrated
7498         echo -n "verifying files..."
7499         fid=$($LFS getstripe -F "$file1") ||
7500                 error "cannot get fid for file $file1"
7501         for i in $(seq 2 $total_count); do
7502                 local fid2=$($LFS getstripe -F $dir/file$i)
7503
7504                 [ "$fid2" == "$fid" ] ||
7505                         error "migrated hard link has mismatched FID"
7506         done
7507
7508         # make sure hard links were properly detected, and migration was
7509         # performed only once for the entire link set; nonlinked files should
7510         # also be migrated
7511         local actual=$(grep -c 'done' <<< "$migrate_out")
7512         local expected=$(($uniq_count + 1))
7513
7514         [ "$actual" -eq  "$expected" ] ||
7515                 error "hard links individually migrated ($actual != $expected)"
7516
7517         # make sure the correct number of hard links are present
7518         local hardlinks=$(stat -c '%h' "$file1")
7519
7520         [ $hardlinks -eq $total_count ] ||
7521                 error "num hard links $hardlinks != $total_count"
7522         echo "done"
7523
7524         return 0
7525 }
7526
7527 test_56xb() {
7528         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7529                 skip "Need MDS version at least 2.10.55"
7530
7531         local dir="$DIR/$tdir"
7532
7533         test_mkdir "$dir" || error "cannot create dir $dir"
7534
7535         echo "testing lfs migrate mode when all links fit within xattrs"
7536         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7537
7538         echo "testing rsync mode when all links fit within xattrs"
7539         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7540
7541         echo "testing lfs migrate mode when all links do not fit within xattrs"
7542         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7543
7544         echo "testing rsync mode when all links do not fit within xattrs"
7545         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7546
7547         chown -R $RUNAS_ID $dir
7548         echo "testing non-root lfs migrate mode when not all links are in xattr"
7549         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7550
7551         # clean up
7552         rm -rf $dir
7553 }
7554 run_test 56xb "lfs migration hard link support"
7555
7556 test_56xc() {
7557         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7558
7559         local dir="$DIR/$tdir"
7560
7561         test_mkdir "$dir" || error "cannot create dir $dir"
7562
7563         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7564         echo -n "Setting initial stripe for 20MB test file..."
7565         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7566                 error "cannot setstripe 20MB file"
7567         echo "done"
7568         echo -n "Sizing 20MB test file..."
7569         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7570         echo "done"
7571         echo -n "Verifying small file autostripe count is 1..."
7572         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7573                 error "cannot migrate 20MB file"
7574         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7575                 error "cannot get stripe for $dir/20mb"
7576         [ $stripe_count -eq 1 ] ||
7577                 error "unexpected stripe count $stripe_count for 20MB file"
7578         rm -f "$dir/20mb"
7579         echo "done"
7580
7581         # Test 2: File is small enough to fit within the available space on
7582         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7583         # have at least an additional 1KB for each desired stripe for test 3
7584         echo -n "Setting stripe for 1GB test file..."
7585         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7586         echo "done"
7587         echo -n "Sizing 1GB test file..."
7588         # File size is 1GB + 3KB
7589         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7590         echo "done"
7591
7592         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7593         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7594         if (( avail > 524288 * OSTCOUNT )); then
7595                 echo -n "Migrating 1GB file..."
7596                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7597                         error "cannot migrate 1GB file"
7598                 echo "done"
7599                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7600                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7601                         error "cannot getstripe for 1GB file"
7602                 [ $stripe_count -eq 2 ] ||
7603                         error "unexpected stripe count $stripe_count != 2"
7604                 echo "done"
7605         fi
7606
7607         # Test 3: File is too large to fit within the available space on
7608         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7609         if [ $OSTCOUNT -ge 3 ]; then
7610                 # The required available space is calculated as
7611                 # file size (1GB + 3KB) / OST count (3).
7612                 local kb_per_ost=349526
7613
7614                 echo -n "Migrating 1GB file with limit..."
7615                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7616                         error "cannot migrate 1GB file with limit"
7617                 echo "done"
7618
7619                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7620                 echo -n "Verifying 1GB autostripe count with limited space..."
7621                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7622                         error "unexpected stripe count $stripe_count (min 3)"
7623                 echo "done"
7624         fi
7625
7626         # clean up
7627         rm -rf $dir
7628 }
7629 run_test 56xc "lfs migration autostripe"
7630
7631 test_56xd() {
7632         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7633
7634         local dir=$DIR/$tdir
7635         local f_mgrt=$dir/$tfile.mgrt
7636         local f_yaml=$dir/$tfile.yaml
7637         local f_copy=$dir/$tfile.copy
7638         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7639         local layout_copy="-c 2 -S 2M -i 1"
7640         local yamlfile=$dir/yamlfile
7641         local layout_before;
7642         local layout_after;
7643
7644         test_mkdir "$dir" || error "cannot create dir $dir"
7645         $LFS setstripe $layout_yaml $f_yaml ||
7646                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7647         $LFS getstripe --yaml $f_yaml > $yamlfile
7648         $LFS setstripe $layout_copy $f_copy ||
7649                 error "cannot setstripe $f_copy with layout $layout_copy"
7650         touch $f_mgrt
7651         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7652
7653         # 1. test option --yaml
7654         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7655                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7656         layout_before=$(get_layout_param $f_yaml)
7657         layout_after=$(get_layout_param $f_mgrt)
7658         [ "$layout_after" == "$layout_before" ] ||
7659                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7660
7661         # 2. test option --copy
7662         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7663                 error "cannot migrate $f_mgrt with --copy $f_copy"
7664         layout_before=$(get_layout_param $f_copy)
7665         layout_after=$(get_layout_param $f_mgrt)
7666         [ "$layout_after" == "$layout_before" ] ||
7667                 error "lfs_migrate --copy: $layout_after != $layout_before"
7668 }
7669 run_test 56xd "check lfs_migrate --yaml and --copy support"
7670
7671 test_56xe() {
7672         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7673
7674         local dir=$DIR/$tdir
7675         local f_comp=$dir/$tfile
7676         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7677         local layout_before=""
7678         local layout_after=""
7679
7680         test_mkdir "$dir" || error "cannot create dir $dir"
7681         $LFS setstripe $layout $f_comp ||
7682                 error "cannot setstripe $f_comp with layout $layout"
7683         layout_before=$(get_layout_param $f_comp)
7684         dd if=/dev/zero of=$f_comp bs=1M count=4
7685
7686         # 1. migrate a comp layout file by lfs_migrate
7687         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7688         layout_after=$(get_layout_param $f_comp)
7689         [ "$layout_before" == "$layout_after" ] ||
7690                 error "lfs_migrate: $layout_before != $layout_after"
7691
7692         # 2. migrate a comp layout file by lfs migrate
7693         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7694         layout_after=$(get_layout_param $f_comp)
7695         [ "$layout_before" == "$layout_after" ] ||
7696                 error "lfs migrate: $layout_before != $layout_after"
7697 }
7698 run_test 56xe "migrate a composite layout file"
7699
7700 test_56xf() {
7701         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7702
7703         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7704                 skip "Need server version at least 2.13.53"
7705
7706         local dir=$DIR/$tdir
7707         local f_comp=$dir/$tfile
7708         local layout="-E 1M -c1 -E -1 -c2"
7709         local fid_before=""
7710         local fid_after=""
7711
7712         test_mkdir "$dir" || error "cannot create dir $dir"
7713         $LFS setstripe $layout $f_comp ||
7714                 error "cannot setstripe $f_comp with layout $layout"
7715         fid_before=$($LFS getstripe --fid $f_comp)
7716         dd if=/dev/zero of=$f_comp bs=1M count=4
7717
7718         # 1. migrate a comp layout file to a comp layout
7719         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7720         fid_after=$($LFS getstripe --fid $f_comp)
7721         [ "$fid_before" == "$fid_after" ] ||
7722                 error "comp-to-comp migrate: $fid_before != $fid_after"
7723
7724         # 2. migrate a comp layout file to a plain layout
7725         $LFS migrate -c2 $f_comp ||
7726                 error "cannot migrate $f_comp by lfs migrate"
7727         fid_after=$($LFS getstripe --fid $f_comp)
7728         [ "$fid_before" == "$fid_after" ] ||
7729                 error "comp-to-plain migrate: $fid_before != $fid_after"
7730
7731         # 3. migrate a plain layout file to a comp layout
7732         $LFS migrate $layout $f_comp ||
7733                 error "cannot migrate $f_comp by lfs migrate"
7734         fid_after=$($LFS getstripe --fid $f_comp)
7735         [ "$fid_before" == "$fid_after" ] ||
7736                 error "plain-to-comp migrate: $fid_before != $fid_after"
7737 }
7738 run_test 56xf "FID is not lost during migration of a composite layout file"
7739
7740 check_file_ost_range() {
7741         local file="$1"
7742         shift
7743         local range="$*"
7744         local -a file_range
7745         local idx
7746
7747         file_range=($($LFS getstripe -y "$file" |
7748                 awk '/l_ost_idx:/ { print $NF }'))
7749
7750         if [[ "${#file_range[@]}" = 0 ]]; then
7751                 echo "No osts found for $file"
7752                 return 1
7753         fi
7754
7755         for idx in "${file_range[@]}"; do
7756                 [[ " $range " =~ " $idx " ]] ||
7757                         return 1
7758         done
7759
7760         return 0
7761 }
7762
7763 sub_test_56xg() {
7764         local stripe_opt="$1"
7765         local pool="$2"
7766         shift 2
7767         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7768
7769         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7770                 error "Fail to migrate $tfile on $pool"
7771         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7772                 error "$tfile is not in pool $pool"
7773         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7774                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7775 }
7776
7777 test_56xg() {
7778         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7779         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7780         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7781                 skip "Need MDS version newer than 2.14.52"
7782
7783         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7784         local -a pool_ranges=("0 0" "1 1" "0 1")
7785
7786         # init pools
7787         for i in "${!pool_names[@]}"; do
7788                 pool_add ${pool_names[$i]} ||
7789                         error "pool_add failed (pool: ${pool_names[$i]})"
7790                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7791                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7792         done
7793
7794         # init the file to migrate
7795         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7796                 error "Unable to create $tfile on OST1"
7797         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7798                 error "Unable to write on $tfile"
7799
7800         echo "1. migrate $tfile on pool ${pool_names[0]}"
7801         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7802
7803         echo "2. migrate $tfile on pool ${pool_names[2]}"
7804         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7805
7806         echo "3. migrate $tfile on pool ${pool_names[1]}"
7807         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7808
7809         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7810         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7811         echo
7812
7813         # Clean pools
7814         destroy_test_pools ||
7815                 error "pool_destroy failed"
7816 }
7817 run_test 56xg "lfs migrate pool support"
7818
7819 test_56y() {
7820         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7821                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7822
7823         local res=""
7824         local dir=$DIR/$tdir
7825         local f1=$dir/file1
7826         local f2=$dir/file2
7827
7828         test_mkdir -p $dir || error "creating dir $dir"
7829         touch $f1 || error "creating std file $f1"
7830         $MULTIOP $f2 H2c || error "creating released file $f2"
7831
7832         # a directory can be raid0, so ask only for files
7833         res=$($LFS find $dir -L raid0 -type f | wc -l)
7834         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7835
7836         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7837         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7838
7839         # only files can be released, so no need to force file search
7840         res=$($LFS find $dir -L released)
7841         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7842
7843         res=$($LFS find $dir -type f \! -L released)
7844         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7845 }
7846 run_test 56y "lfs find -L raid0|released"
7847
7848 test_56z() { # LU-4824
7849         # This checks to make sure 'lfs find' continues after errors
7850         # There are two classes of errors that should be caught:
7851         # - If multiple paths are provided, all should be searched even if one
7852         #   errors out
7853         # - If errors are encountered during the search, it should not terminate
7854         #   early
7855         local dir=$DIR/$tdir
7856         local i
7857
7858         test_mkdir $dir
7859         for i in d{0..9}; do
7860                 test_mkdir $dir/$i
7861                 touch $dir/$i/$tfile
7862         done
7863         $LFS find $DIR/non_existent_dir $dir &&
7864                 error "$LFS find did not return an error"
7865         # Make a directory unsearchable. This should NOT be the last entry in
7866         # directory order.  Arbitrarily pick the 6th entry
7867         chmod 700 $($LFS find $dir -type d | sed '6!d')
7868
7869         $RUNAS $LFS find $DIR/non_existent $dir
7870         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7871
7872         # The user should be able to see 10 directories and 9 files
7873         (( count == 19 )) ||
7874                 error "$LFS find found $count != 19 entries after error"
7875 }
7876 run_test 56z "lfs find should continue after an error"
7877
7878 test_56aa() { # LU-5937
7879         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7880
7881         local dir=$DIR/$tdir
7882
7883         mkdir $dir
7884         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7885
7886         createmany -o $dir/striped_dir/${tfile}- 1024
7887         local dirs=$($LFS find --size +8k $dir/)
7888
7889         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7890 }
7891 run_test 56aa "lfs find --size under striped dir"
7892
7893 test_56ab() { # LU-10705
7894         test_mkdir $DIR/$tdir
7895         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7896         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7897         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7898         # Flush writes to ensure valid blocks.  Need to be more thorough for
7899         # ZFS, since blocks are not allocated/returned to client immediately.
7900         sync_all_data
7901         wait_zfs_commit ost1 2
7902         cancel_lru_locks osc
7903         ls -ls $DIR/$tdir
7904
7905         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7906
7907         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7908
7909         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7910         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7911
7912         rm -f $DIR/$tdir/$tfile.[123]
7913 }
7914 run_test 56ab "lfs find --blocks"
7915
7916 # LU-11188
7917 test_56aca() {
7918         local dir="$DIR/$tdir"
7919         local perms=(001 002 003 004 005 006 007
7920                      010 020 030 040 050 060 070
7921                      100 200 300 400 500 600 700
7922                      111 222 333 444 555 666 777)
7923         local perm_minus=(8 8 4 8 4 4 2
7924                           8 8 4 8 4 4 2
7925                           8 8 4 8 4 4 2
7926                           4 4 2 4 2 2 1)
7927         local perm_slash=(8  8 12  8 12 12 14
7928                           8  8 12  8 12 12 14
7929                           8  8 12  8 12 12 14
7930                          16 16 24 16 24 24 28)
7931
7932         test_mkdir "$dir"
7933         for perm in ${perms[*]}; do
7934                 touch "$dir/$tfile.$perm"
7935                 chmod $perm "$dir/$tfile.$perm"
7936         done
7937
7938         for ((i = 0; i < ${#perms[*]}; i++)); do
7939                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7940                 (( $num == 1 )) ||
7941                         error "lfs find -perm ${perms[i]}:"\
7942                               "$num != 1"
7943
7944                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7945                 (( $num == ${perm_minus[i]} )) ||
7946                         error "lfs find -perm -${perms[i]}:"\
7947                               "$num != ${perm_minus[i]}"
7948
7949                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7950                 (( $num == ${perm_slash[i]} )) ||
7951                         error "lfs find -perm /${perms[i]}:"\
7952                               "$num != ${perm_slash[i]}"
7953         done
7954 }
7955 run_test 56aca "check lfs find -perm with octal representation"
7956
7957 test_56acb() {
7958         local dir=$DIR/$tdir
7959         # p is the permission of write and execute for user, group and other
7960         # without the umask. It is used to test +wx.
7961         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7962         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7963         local symbolic=(+t  a+t u+t g+t o+t
7964                         g+s u+s o+s +s o+sr
7965                         o=r,ug+o,u+w
7966                         u+ g+ o+ a+ ugo+
7967                         u- g- o- a- ugo-
7968                         u= g= o= a= ugo=
7969                         o=r,ug+o,u+w u=r,a+u,u+w
7970                         g=r,ugo=g,u+w u+x,+X +X
7971                         u+x,u+X u+X u+x,g+X o+r,+X
7972                         u+x,go+X +wx +rwx)
7973
7974         test_mkdir $dir
7975         for perm in ${perms[*]}; do
7976                 touch "$dir/$tfile.$perm"
7977                 chmod $perm "$dir/$tfile.$perm"
7978         done
7979
7980         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
7981                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
7982
7983                 (( $num == 1 )) ||
7984                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
7985         done
7986 }
7987 run_test 56acb "check lfs find -perm with symbolic representation"
7988
7989 test_56acc() {
7990         local dir=$DIR/$tdir
7991         local tests="17777 787 789 abcd
7992                 ug=uu ug=a ug=gu uo=ou urw
7993                 u+xg+x a=r,u+x,"
7994
7995         test_mkdir $dir
7996         for err in $tests; do
7997                 if $LFS find $dir -perm $err 2>/dev/null; then
7998                         error "lfs find -perm $err: parsing should have failed"
7999                 fi
8000         done
8001 }
8002 run_test 56acc "check parsing error for lfs find -perm"
8003
8004 test_56ba() {
8005         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8006                 skip "Need MDS version at least 2.10.50"
8007
8008         # Create composite files with one component
8009         local dir=$DIR/$tdir
8010
8011         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8012         # Create composite files with three components
8013         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8014         # Create non-composite files
8015         createmany -o $dir/${tfile}- 10
8016
8017         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8018
8019         [[ $nfiles == 10 ]] ||
8020                 error "lfs find -E 1M found $nfiles != 10 files"
8021
8022         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8023         [[ $nfiles == 25 ]] ||
8024                 error "lfs find ! -E 1M found $nfiles != 25 files"
8025
8026         # All files have a component that starts at 0
8027         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8028         [[ $nfiles == 35 ]] ||
8029                 error "lfs find --component-start 0 - $nfiles != 35 files"
8030
8031         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8032         [[ $nfiles == 15 ]] ||
8033                 error "lfs find --component-start 2M - $nfiles != 15 files"
8034
8035         # All files created here have a componenet that does not starts at 2M
8036         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8037         [[ $nfiles == 35 ]] ||
8038                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8039
8040         # Find files with a specified number of components
8041         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8042         [[ $nfiles == 15 ]] ||
8043                 error "lfs find --component-count 3 - $nfiles != 15 files"
8044
8045         # Remember non-composite files have a component count of zero
8046         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8047         [[ $nfiles == 10 ]] ||
8048                 error "lfs find --component-count 0 - $nfiles != 10 files"
8049
8050         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8051         [[ $nfiles == 20 ]] ||
8052                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8053
8054         # All files have a flag called "init"
8055         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8056         [[ $nfiles == 35 ]] ||
8057                 error "lfs find --component-flags init - $nfiles != 35 files"
8058
8059         # Multi-component files will have a component not initialized
8060         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8061         [[ $nfiles == 15 ]] ||
8062                 error "lfs find !--component-flags init - $nfiles != 15 files"
8063
8064         rm -rf $dir
8065
8066 }
8067 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8068
8069 test_56ca() {
8070         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8071                 skip "Need MDS version at least 2.10.57"
8072
8073         local td=$DIR/$tdir
8074         local tf=$td/$tfile
8075         local dir
8076         local nfiles
8077         local cmd
8078         local i
8079         local j
8080
8081         # create mirrored directories and mirrored files
8082         mkdir $td || error "mkdir $td failed"
8083         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8084         createmany -o $tf- 10 || error "create $tf- failed"
8085
8086         for i in $(seq 2); do
8087                 dir=$td/dir$i
8088                 mkdir $dir || error "mkdir $dir failed"
8089                 $LFS mirror create -N$((3 + i)) $dir ||
8090                         error "create mirrored dir $dir failed"
8091                 createmany -o $dir/$tfile- 10 ||
8092                         error "create $dir/$tfile- failed"
8093         done
8094
8095         # change the states of some mirrored files
8096         echo foo > $tf-6
8097         for i in $(seq 2); do
8098                 dir=$td/dir$i
8099                 for j in $(seq 4 9); do
8100                         echo foo > $dir/$tfile-$j
8101                 done
8102         done
8103
8104         # find mirrored files with specific mirror count
8105         cmd="$LFS find --mirror-count 3 --type f $td"
8106         nfiles=$($cmd | wc -l)
8107         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8108
8109         cmd="$LFS find ! --mirror-count 3 --type f $td"
8110         nfiles=$($cmd | wc -l)
8111         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8112
8113         cmd="$LFS find --mirror-count +2 --type f $td"
8114         nfiles=$($cmd | wc -l)
8115         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8116
8117         cmd="$LFS find --mirror-count -6 --type f $td"
8118         nfiles=$($cmd | wc -l)
8119         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8120
8121         # find mirrored files with specific file state
8122         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8123         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8124
8125         cmd="$LFS find --mirror-state=ro --type f $td"
8126         nfiles=$($cmd | wc -l)
8127         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8128
8129         cmd="$LFS find ! --mirror-state=ro --type f $td"
8130         nfiles=$($cmd | wc -l)
8131         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8132
8133         cmd="$LFS find --mirror-state=wp --type f $td"
8134         nfiles=$($cmd | wc -l)
8135         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8136
8137         cmd="$LFS find ! --mirror-state=sp --type f $td"
8138         nfiles=$($cmd | wc -l)
8139         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8140 }
8141 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8142
8143 test_56da() { # LU-14179
8144         local path=$DIR/$tdir
8145
8146         test_mkdir $path
8147         cd $path
8148
8149         local longdir=$(str_repeat 'a' 255)
8150
8151         for i in {1..15}; do
8152                 path=$path/$longdir
8153                 test_mkdir $longdir
8154                 cd $longdir
8155         done
8156
8157         local len=${#path}
8158         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8159
8160         test_mkdir $lastdir
8161         cd $lastdir
8162         # PATH_MAX-1
8163         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8164
8165         # NAME_MAX
8166         touch $(str_repeat 'f' 255)
8167
8168         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8169                 error "lfs find reported an error"
8170
8171         rm -rf $DIR/$tdir
8172 }
8173 run_test 56da "test lfs find with long paths"
8174
8175 test_57a() {
8176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8177         # note test will not do anything if MDS is not local
8178         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8179                 skip_env "ldiskfs only test"
8180         fi
8181         remote_mds_nodsh && skip "remote MDS with nodsh"
8182
8183         local MNTDEV="osd*.*MDT*.mntdev"
8184         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8185         [ -z "$DEV" ] && error "can't access $MNTDEV"
8186         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8187                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8188                         error "can't access $DEV"
8189                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8190                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8191                 rm $TMP/t57a.dump
8192         done
8193 }
8194 run_test 57a "verify MDS filesystem created with large inodes =="
8195
8196 test_57b() {
8197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8198         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8199                 skip_env "ldiskfs only test"
8200         fi
8201         remote_mds_nodsh && skip "remote MDS with nodsh"
8202
8203         local dir=$DIR/$tdir
8204         local filecount=100
8205         local file1=$dir/f1
8206         local fileN=$dir/f$filecount
8207
8208         rm -rf $dir || error "removing $dir"
8209         test_mkdir -c1 $dir
8210         local mdtidx=$($LFS getstripe -m $dir)
8211         local mdtname=MDT$(printf %04x $mdtidx)
8212         local facet=mds$((mdtidx + 1))
8213
8214         echo "mcreating $filecount files"
8215         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8216
8217         # verify that files do not have EAs yet
8218         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8219                 error "$file1 has an EA"
8220         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8221                 error "$fileN has an EA"
8222
8223         sync
8224         sleep 1
8225         df $dir  #make sure we get new statfs data
8226         local mdsfree=$(do_facet $facet \
8227                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8228         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8229         local file
8230
8231         echo "opening files to create objects/EAs"
8232         for file in $(seq -f $dir/f%g 1 $filecount); do
8233                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8234                         error "opening $file"
8235         done
8236
8237         # verify that files have EAs now
8238         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8239         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8240
8241         sleep 1  #make sure we get new statfs data
8242         df $dir
8243         local mdsfree2=$(do_facet $facet \
8244                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8245         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8246
8247         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8248                 if [ "$mdsfree" != "$mdsfree2" ]; then
8249                         error "MDC before $mdcfree != after $mdcfree2"
8250                 else
8251                         echo "MDC before $mdcfree != after $mdcfree2"
8252                         echo "unable to confirm if MDS has large inodes"
8253                 fi
8254         fi
8255         rm -rf $dir
8256 }
8257 run_test 57b "default LOV EAs are stored inside large inodes ==="
8258
8259 test_58() {
8260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8261         [ -z "$(which wiretest 2>/dev/null)" ] &&
8262                         skip_env "could not find wiretest"
8263
8264         wiretest
8265 }
8266 run_test 58 "verify cross-platform wire constants =============="
8267
8268 test_59() {
8269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8270
8271         echo "touch 130 files"
8272         createmany -o $DIR/f59- 130
8273         echo "rm 130 files"
8274         unlinkmany $DIR/f59- 130
8275         sync
8276         # wait for commitment of removal
8277         wait_delete_completed
8278 }
8279 run_test 59 "verify cancellation of llog records async ========="
8280
8281 TEST60_HEAD="test_60 run $RANDOM"
8282 test_60a() {
8283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8284         remote_mgs_nodsh && skip "remote MGS with nodsh"
8285         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8286                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8287                         skip_env "missing subtest run-llog.sh"
8288
8289         log "$TEST60_HEAD - from kernel mode"
8290         do_facet mgs "$LCTL dk > /dev/null"
8291         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8292         do_facet mgs $LCTL dk > $TMP/$tfile
8293
8294         # LU-6388: test llog_reader
8295         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8296         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8297         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8298                         skip_env "missing llog_reader"
8299         local fstype=$(facet_fstype mgs)
8300         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8301                 skip_env "Only for ldiskfs or zfs type mgs"
8302
8303         local mntpt=$(facet_mntpt mgs)
8304         local mgsdev=$(mgsdevname 1)
8305         local fid_list
8306         local fid
8307         local rec_list
8308         local rec
8309         local rec_type
8310         local obj_file
8311         local path
8312         local seq
8313         local oid
8314         local pass=true
8315
8316         #get fid and record list
8317         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8318                 tail -n 4))
8319         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8320                 tail -n 4))
8321         #remount mgs as ldiskfs or zfs type
8322         stop mgs || error "stop mgs failed"
8323         mount_fstype mgs || error "remount mgs failed"
8324         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8325                 fid=${fid_list[i]}
8326                 rec=${rec_list[i]}
8327                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8328                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8329                 oid=$((16#$oid))
8330
8331                 case $fstype in
8332                         ldiskfs )
8333                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8334                         zfs )
8335                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8336                 esac
8337                 echo "obj_file is $obj_file"
8338                 do_facet mgs $llog_reader $obj_file
8339
8340                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8341                         awk '{ print $3 }' | sed -e "s/^type=//g")
8342                 if [ $rec_type != $rec ]; then
8343                         echo "FAILED test_60a wrong record type $rec_type," \
8344                               "should be $rec"
8345                         pass=false
8346                         break
8347                 fi
8348
8349                 #check obj path if record type is LLOG_LOGID_MAGIC
8350                 if [ "$rec" == "1064553b" ]; then
8351                         path=$(do_facet mgs $llog_reader $obj_file |
8352                                 grep "path=" | awk '{ print $NF }' |
8353                                 sed -e "s/^path=//g")
8354                         if [ $obj_file != $mntpt/$path ]; then
8355                                 echo "FAILED test_60a wrong obj path" \
8356                                       "$montpt/$path, should be $obj_file"
8357                                 pass=false
8358                                 break
8359                         fi
8360                 fi
8361         done
8362         rm -f $TMP/$tfile
8363         #restart mgs before "error", otherwise it will block the next test
8364         stop mgs || error "stop mgs failed"
8365         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8366         $pass || error "test failed, see FAILED test_60a messages for specifics"
8367 }
8368 run_test 60a "llog_test run from kernel module and test llog_reader"
8369
8370 test_60b() { # bug 6411
8371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8372
8373         dmesg > $DIR/$tfile
8374         LLOG_COUNT=$(do_facet mgs dmesg |
8375                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8376                           /llog_[a-z]*.c:[0-9]/ {
8377                                 if (marker)
8378                                         from_marker++
8379                                 from_begin++
8380                           }
8381                           END {
8382                                 if (marker)
8383                                         print from_marker
8384                                 else
8385                                         print from_begin
8386                           }")
8387
8388         [[ $LLOG_COUNT -gt 120 ]] &&
8389                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8390 }
8391 run_test 60b "limit repeated messages from CERROR/CWARN"
8392
8393 test_60c() {
8394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8395
8396         echo "create 5000 files"
8397         createmany -o $DIR/f60c- 5000
8398 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8399         lctl set_param fail_loc=0x80000137
8400         unlinkmany $DIR/f60c- 5000
8401         lctl set_param fail_loc=0
8402 }
8403 run_test 60c "unlink file when mds full"
8404
8405 test_60d() {
8406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8407
8408         SAVEPRINTK=$(lctl get_param -n printk)
8409         # verify "lctl mark" is even working"
8410         MESSAGE="test message ID $RANDOM $$"
8411         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8412         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8413
8414         lctl set_param printk=0 || error "set lnet.printk failed"
8415         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8416         MESSAGE="new test message ID $RANDOM $$"
8417         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8418         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8419         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8420
8421         lctl set_param -n printk="$SAVEPRINTK"
8422 }
8423 run_test 60d "test printk console message masking"
8424
8425 test_60e() {
8426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8427         remote_mds_nodsh && skip "remote MDS with nodsh"
8428
8429         touch $DIR/$tfile
8430 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8431         do_facet mds1 lctl set_param fail_loc=0x15b
8432         rm $DIR/$tfile
8433 }
8434 run_test 60e "no space while new llog is being created"
8435
8436 test_60f() {
8437         local old_path=$($LCTL get_param -n debug_path)
8438
8439         stack_trap "$LCTL set_param debug_path=$old_path"
8440         stack_trap "rm -f $TMP/$tfile*"
8441         rm -f $TMP/$tfile* 2> /dev/null
8442         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8443         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8444         test_mkdir $DIR/$tdir
8445         # retry in case the open is cached and not released
8446         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8447                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8448                 sleep 0.1
8449         done
8450         ls $TMP/$tfile*
8451         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8452 }
8453 run_test 60f "change debug_path works"
8454
8455 test_60g() {
8456         local pid
8457         local i
8458
8459         test_mkdir -c $MDSCOUNT $DIR/$tdir
8460
8461         (
8462                 local index=0
8463                 while true; do
8464                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8465                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8466                                 2>/dev/null
8467                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8468                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8469                         index=$((index + 1))
8470                 done
8471         ) &
8472
8473         pid=$!
8474
8475         for i in {0..100}; do
8476                 # define OBD_FAIL_OSD_TXN_START    0x19a
8477                 local index=$((i % MDSCOUNT + 1))
8478
8479                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8480                         > /dev/null
8481                 sleep 0.01
8482         done
8483
8484         kill -9 $pid
8485
8486         for i in $(seq $MDSCOUNT); do
8487                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8488         done
8489
8490         mkdir $DIR/$tdir/new || error "mkdir failed"
8491         rmdir $DIR/$tdir/new || error "rmdir failed"
8492
8493         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8494                 -t namespace
8495         for i in $(seq $MDSCOUNT); do
8496                 wait_update_facet mds$i "$LCTL get_param -n \
8497                         mdd.$(facet_svc mds$i).lfsck_namespace |
8498                         awk '/^status/ { print \\\$2 }'" "completed"
8499         done
8500
8501         ls -R $DIR/$tdir
8502         rm -rf $DIR/$tdir || error "rmdir failed"
8503 }
8504 run_test 60g "transaction abort won't cause MDT hung"
8505
8506 test_60h() {
8507         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8508                 skip "Need MDS version at least 2.12.52"
8509         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8510
8511         local f
8512
8513         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8514         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8515         for fail_loc in 0x80000188 0x80000189; do
8516                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8517                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8518                         error "mkdir $dir-$fail_loc failed"
8519                 for i in {0..10}; do
8520                         # create may fail on missing stripe
8521                         echo $i > $DIR/$tdir-$fail_loc/$i
8522                 done
8523                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8524                         error "getdirstripe $tdir-$fail_loc failed"
8525                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8526                         error "migrate $tdir-$fail_loc failed"
8527                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8528                         error "getdirstripe $tdir-$fail_loc failed"
8529                 pushd $DIR/$tdir-$fail_loc
8530                 for f in *; do
8531                         echo $f | cmp $f - || error "$f data mismatch"
8532                 done
8533                 popd
8534                 rm -rf $DIR/$tdir-$fail_loc
8535         done
8536 }
8537 run_test 60h "striped directory with missing stripes can be accessed"
8538
8539 function t60i_load() {
8540         mkdir $DIR/$tdir
8541         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8542         $LCTL set_param fail_loc=0x131c fail_val=1
8543         for ((i=0; i<5000; i++)); do
8544                 touch $DIR/$tdir/f$i
8545         done
8546 }
8547
8548 test_60i() {
8549         changelog_register || error "changelog_register failed"
8550         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8551         changelog_users $SINGLEMDS | grep -q $cl_user ||
8552                 error "User $cl_user not found in changelog_users"
8553         changelog_chmask "ALL"
8554         t60i_load &
8555         local PID=$!
8556         for((i=0; i<100; i++)); do
8557                 changelog_dump >/dev/null ||
8558                         error "can't read changelog"
8559         done
8560         kill $PID
8561         wait $PID
8562         changelog_deregister || error "changelog_deregister failed"
8563         $LCTL set_param fail_loc=0
8564 }
8565 run_test 60i "llog: new record vs reader race"
8566
8567 test_61a() {
8568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8569
8570         f="$DIR/f61"
8571         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8572         cancel_lru_locks osc
8573         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8574         sync
8575 }
8576 run_test 61a "mmap() writes don't make sync hang ================"
8577
8578 test_61b() {
8579         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8580 }
8581 run_test 61b "mmap() of unstriped file is successful"
8582
8583 # bug 2330 - insufficient obd_match error checking causes LBUG
8584 test_62() {
8585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8586
8587         f="$DIR/f62"
8588         echo foo > $f
8589         cancel_lru_locks osc
8590         lctl set_param fail_loc=0x405
8591         cat $f && error "cat succeeded, expect -EIO"
8592         lctl set_param fail_loc=0
8593 }
8594 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8595 # match every page all of the time.
8596 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8597
8598 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8599 # Though this test is irrelevant anymore, it helped to reveal some
8600 # other grant bugs (LU-4482), let's keep it.
8601 test_63a() {   # was test_63
8602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8603
8604         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8605
8606         for i in `seq 10` ; do
8607                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8608                 sleep 5
8609                 kill $!
8610                 sleep 1
8611         done
8612
8613         rm -f $DIR/f63 || true
8614 }
8615 run_test 63a "Verify oig_wait interruption does not crash ======="
8616
8617 # bug 2248 - async write errors didn't return to application on sync
8618 # bug 3677 - async write errors left page locked
8619 test_63b() {
8620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8621
8622         debugsave
8623         lctl set_param debug=-1
8624
8625         # ensure we have a grant to do async writes
8626         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8627         rm $DIR/$tfile
8628
8629         sync    # sync lest earlier test intercept the fail_loc
8630
8631         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8632         lctl set_param fail_loc=0x80000406
8633         $MULTIOP $DIR/$tfile Owy && \
8634                 error "sync didn't return ENOMEM"
8635         sync; sleep 2; sync     # do a real sync this time to flush page
8636         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8637                 error "locked page left in cache after async error" || true
8638         debugrestore
8639 }
8640 run_test 63b "async write errors should be returned to fsync ==="
8641
8642 test_64a () {
8643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8644
8645         lfs df $DIR
8646         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8647 }
8648 run_test 64a "verify filter grant calculations (in kernel) ====="
8649
8650 test_64b () {
8651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8652
8653         bash oos.sh $MOUNT || error "oos.sh failed: $?"
8654 }
8655 run_test 64b "check out-of-space detection on client"
8656
8657 test_64c() {
8658         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8659 }
8660 run_test 64c "verify grant shrink"
8661
8662 import_param() {
8663         local tgt=$1
8664         local param=$2
8665
8666         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8667 }
8668
8669 # this does exactly what osc_request.c:osc_announce_cached() does in
8670 # order to calculate max amount of grants to ask from server
8671 want_grant() {
8672         local tgt=$1
8673
8674         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8675         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8676
8677         ((rpc_in_flight++));
8678         nrpages=$((nrpages * rpc_in_flight))
8679
8680         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8681
8682         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8683
8684         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8685         local undirty=$((nrpages * PAGE_SIZE))
8686
8687         local max_extent_pages
8688         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8689         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8690         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8691         local grant_extent_tax
8692         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8693
8694         undirty=$((undirty + nrextents * grant_extent_tax))
8695
8696         echo $undirty
8697 }
8698
8699 # this is size of unit for grant allocation. It should be equal to
8700 # what tgt_grant.c:tgt_grant_chunk() calculates
8701 grant_chunk() {
8702         local tgt=$1
8703         local max_brw_size
8704         local grant_extent_tax
8705
8706         max_brw_size=$(import_param $tgt max_brw_size)
8707
8708         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8709
8710         echo $(((max_brw_size + grant_extent_tax) * 2))
8711 }
8712
8713 test_64d() {
8714         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8715                 skip "OST < 2.10.55 doesn't limit grants enough"
8716
8717         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8718
8719         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8720                 skip "no grant_param connect flag"
8721
8722         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8723
8724         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8725         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8726
8727
8728         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8729         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8730
8731         $LFS setstripe $DIR/$tfile -i 0 -c 1
8732         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8733         ddpid=$!
8734
8735         while kill -0 $ddpid; do
8736                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8737
8738                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8739                         kill $ddpid
8740                         error "cur_grant $cur_grant > $max_cur_granted"
8741                 fi
8742
8743                 sleep 1
8744         done
8745 }
8746 run_test 64d "check grant limit exceed"
8747
8748 check_grants() {
8749         local tgt=$1
8750         local expected=$2
8751         local msg=$3
8752         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8753
8754         ((cur_grants == expected)) ||
8755                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8756 }
8757
8758 round_up_p2() {
8759         echo $((($1 + $2 - 1) & ~($2 - 1)))
8760 }
8761
8762 test_64e() {
8763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8764         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8765                 skip "Need OSS version at least 2.11.56"
8766
8767         # Remount client to reset grant
8768         remount_client $MOUNT || error "failed to remount client"
8769         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8770
8771         local init_grants=$(import_param $osc_tgt initial_grant)
8772
8773         check_grants $osc_tgt $init_grants "init grants"
8774
8775         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8776         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8777         local gbs=$(import_param $osc_tgt grant_block_size)
8778
8779         # write random number of bytes from max_brw_size / 4 to max_brw_size
8780         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8781         # align for direct io
8782         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8783         # round to grant consumption unit
8784         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8785
8786         local grants=$((wb_round_up + extent_tax))
8787
8788         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8789
8790         # define OBD_FAIL_TGT_NO_GRANT 0x725
8791         # make the server not grant more back
8792         do_facet ost1 $LCTL set_param fail_loc=0x725
8793         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8794
8795         do_facet ost1 $LCTL set_param fail_loc=0
8796
8797         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8798
8799         rm -f $DIR/$tfile || error "rm failed"
8800
8801         # Remount client to reset grant
8802         remount_client $MOUNT || error "failed to remount client"
8803         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8804
8805         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8806
8807         # define OBD_FAIL_TGT_NO_GRANT 0x725
8808         # make the server not grant more back
8809         do_facet ost1 $LCTL set_param fail_loc=0x725
8810         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8811         do_facet ost1 $LCTL set_param fail_loc=0
8812
8813         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8814 }
8815 run_test 64e "check grant consumption (no grant allocation)"
8816
8817 test_64f() {
8818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8819
8820         # Remount client to reset grant
8821         remount_client $MOUNT || error "failed to remount client"
8822         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8823
8824         local init_grants=$(import_param $osc_tgt initial_grant)
8825         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8826         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8827         local gbs=$(import_param $osc_tgt grant_block_size)
8828         local chunk=$(grant_chunk $osc_tgt)
8829
8830         # write random number of bytes from max_brw_size / 4 to max_brw_size
8831         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8832         # align for direct io
8833         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8834         # round to grant consumption unit
8835         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8836
8837         local grants=$((wb_round_up + extent_tax))
8838
8839         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8840         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8841                 error "error writing to $DIR/$tfile"
8842
8843         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8844                 "direct io with grant allocation"
8845
8846         rm -f $DIR/$tfile || error "rm failed"
8847
8848         # Remount client to reset grant
8849         remount_client $MOUNT || error "failed to remount client"
8850         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8851
8852         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8853
8854         local cmd="oO_WRONLY:w${write_bytes}_yc"
8855
8856         $MULTIOP $DIR/$tfile $cmd &
8857         MULTIPID=$!
8858         sleep 1
8859
8860         check_grants $osc_tgt $((init_grants - grants)) \
8861                 "buffered io, not write rpc"
8862
8863         kill -USR1 $MULTIPID
8864         wait
8865
8866         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8867                 "buffered io, one RPC"
8868 }
8869 run_test 64f "check grant consumption (with grant allocation)"
8870
8871 test_64g() {
8872         #[ $MDS1_VERSION -lt $(version_code 2.14.54) ] &&
8873         #       skip "Need MDS version at least 2.14.54"
8874
8875         local mdts=$(comma_list $(mdts_nodes))
8876
8877         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
8878                         tr '\n' ' ')
8879         stack_trap "$LCTL set_param $old"
8880
8881         # generate dirty pages and increase dirty granted on MDT
8882         stack_trap "rm -f $DIR/$tfile-*"
8883         for (( i = 0; i < 10; i++)); do
8884                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
8885                         error "can't set stripe"
8886                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
8887                         error "can't dd"
8888                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
8889                         $LFS getstripe $DIR/$tfile-$i
8890                         error "not DoM file"
8891                 }
8892         done
8893
8894         # flush dirty pages
8895         sync
8896
8897         # wait until grant shrink reset grant dirty on MDTs
8898         for ((i = 0; i < 120; i++)); do
8899                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8900                         awk '{sum=sum+$1} END {print sum}')
8901                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
8902                 echo "$grant_dirty grants, $vm_dirty pages"
8903                 (( grant_dirty + vm_dirty == 0 )) && break
8904                 (( i == 3 )) && sync &&
8905                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
8906                 sleep 1
8907         done
8908
8909         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8910                 awk '{sum=sum+$1} END {print sum}')
8911         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
8912 }
8913 run_test 64g "grant shrink on MDT"
8914
8915 test_64h() {
8916         local instance=$($LFS getname -i $DIR)
8917         local osc_tgt="$FSNAME-OST0000-osc-$instance"
8918         local num_exps=$(do_facet ost1 \
8919             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
8920         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8921         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
8922         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8923
8924         # 10MiB is for file to be written, max_brw_size * 16 *
8925         # num_exps is space reserve so that tgt_grant_shrink() decided
8926         # to not shrink
8927         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
8928         (( avail * 1024 < expect )) &&
8929                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
8930
8931         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
8932         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
8933         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
8934         $LCTL set_param osc.*OST0000*.grant_shrink=1
8935         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
8936
8937         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8938         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
8939
8940         # drop cache so that coming read would do rpc
8941         cancel_lru_locks osc
8942
8943         # shrink interval is set to 10, pause for 7 seconds so that
8944         # grant thread did not wake up yet but coming read entered
8945         # shrink mode for rpc (osc_should_shrink_grant())
8946         sleep 7
8947
8948         declare -a cur_grant_bytes
8949         declare -a tot_granted
8950         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
8951         tot_granted[0]=$(do_facet ost1 \
8952             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
8953
8954         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
8955
8956         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
8957         tot_granted[1]=$(do_facet ost1 \
8958             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
8959
8960         # grant change should be equal on both sides
8961         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
8962                 tot_granted[0] - tot_granted[1])) ||
8963                 error "grant change mismatch, "                                \
8964                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
8965                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
8966 }
8967 run_test 64h "grant shrink on read"
8968
8969 test_64i() {
8970         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
8971                 skip "need OST at least 2.14.55 to avoid grant shrink on replay"
8972
8973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8974         remote_ost_nodsh && skip "remote OSTs with nodsh"
8975
8976         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8977
8978         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
8979
8980         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
8981         local instance=$($LFS getname -i $DIR)
8982
8983         local osc_tgt="$FSNAME-OST0000-osc-$instance"
8984         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
8985
8986         # shrink grants and simulate rpc loss
8987         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
8988         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
8989         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
8990
8991         fail ost1
8992
8993         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
8994
8995         local testid=$(echo $TESTNAME | tr '_' ' ')
8996
8997         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
8998                 grep "GRANT, real grant" &&
8999                 error "client has more grants then it owns" || true
9000 }
9001 run_test 64i "shrink on reconnect"
9002
9003 # bug 1414 - set/get directories' stripe info
9004 test_65a() {
9005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9006
9007         test_mkdir $DIR/$tdir
9008         touch $DIR/$tdir/f1
9009         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9010 }
9011 run_test 65a "directory with no stripe info"
9012
9013 test_65b() {
9014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9015
9016         test_mkdir $DIR/$tdir
9017         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9018
9019         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9020                                                 error "setstripe"
9021         touch $DIR/$tdir/f2
9022         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9023 }
9024 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9025
9026 test_65c() {
9027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9028         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9029
9030         test_mkdir $DIR/$tdir
9031         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9032
9033         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9034                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9035         touch $DIR/$tdir/f3
9036         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9037 }
9038 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9039
9040 test_65d() {
9041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9042
9043         test_mkdir $DIR/$tdir
9044         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9045         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9046
9047         if [[ $STRIPECOUNT -le 0 ]]; then
9048                 sc=1
9049         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9050                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9051                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9052         else
9053                 sc=$(($STRIPECOUNT - 1))
9054         fi
9055         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9056         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9057         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9058                 error "lverify failed"
9059 }
9060 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9061
9062 test_65e() {
9063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9064
9065         test_mkdir $DIR/$tdir
9066
9067         $LFS setstripe $DIR/$tdir || error "setstripe"
9068         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9069                                         error "no stripe info failed"
9070         touch $DIR/$tdir/f6
9071         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9072 }
9073 run_test 65e "directory setstripe defaults"
9074
9075 test_65f() {
9076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9077
9078         test_mkdir $DIR/${tdir}f
9079         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9080                 error "setstripe succeeded" || true
9081 }
9082 run_test 65f "dir setstripe permission (should return error) ==="
9083
9084 test_65g() {
9085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9086
9087         test_mkdir $DIR/$tdir
9088         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9089
9090         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9091                 error "setstripe -S failed"
9092         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9093         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9094                 error "delete default stripe failed"
9095 }
9096 run_test 65g "directory setstripe -d"
9097
9098 test_65h() {
9099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9100
9101         test_mkdir $DIR/$tdir
9102         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9103
9104         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9105                 error "setstripe -S failed"
9106         test_mkdir $DIR/$tdir/dd1
9107         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9108                 error "stripe info inherit failed"
9109 }
9110 run_test 65h "directory stripe info inherit ===================="
9111
9112 test_65i() {
9113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9114
9115         save_layout_restore_at_exit $MOUNT
9116
9117         # bug6367: set non-default striping on root directory
9118         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9119
9120         # bug12836: getstripe on -1 default directory striping
9121         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9122
9123         # bug12836: getstripe -v on -1 default directory striping
9124         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9125
9126         # bug12836: new find on -1 default directory striping
9127         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9128 }
9129 run_test 65i "various tests to set root directory striping"
9130
9131 test_65j() { # bug6367
9132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9133
9134         sync; sleep 1
9135
9136         # if we aren't already remounting for each test, do so for this test
9137         if [ "$I_MOUNTED" = "yes" ]; then
9138                 cleanup || error "failed to unmount"
9139                 setup
9140         fi
9141
9142         save_layout_restore_at_exit $MOUNT
9143
9144         $LFS setstripe -d $MOUNT || error "setstripe failed"
9145 }
9146 run_test 65j "set default striping on root directory (bug 6367)="
9147
9148 cleanup_65k() {
9149         rm -rf $DIR/$tdir
9150         wait_delete_completed
9151         do_facet $SINGLEMDS "lctl set_param -n \
9152                 osp.$ost*MDT0000.max_create_count=$max_count"
9153         do_facet $SINGLEMDS "lctl set_param -n \
9154                 osp.$ost*MDT0000.create_count=$count"
9155         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9156         echo $INACTIVE_OSC "is Activate"
9157
9158         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9159 }
9160
9161 test_65k() { # bug11679
9162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9163         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9164         remote_mds_nodsh && skip "remote MDS with nodsh"
9165
9166         local disable_precreate=true
9167         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9168                 disable_precreate=false
9169
9170         echo "Check OST status: "
9171         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9172                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9173
9174         for OSC in $MDS_OSCS; do
9175                 echo $OSC "is active"
9176                 do_facet $SINGLEMDS lctl --device %$OSC activate
9177         done
9178
9179         for INACTIVE_OSC in $MDS_OSCS; do
9180                 local ost=$(osc_to_ost $INACTIVE_OSC)
9181                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9182                                lov.*md*.target_obd |
9183                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9184
9185                 mkdir -p $DIR/$tdir
9186                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9187                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9188
9189                 echo "Deactivate: " $INACTIVE_OSC
9190                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9191
9192                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9193                               osp.$ost*MDT0000.create_count")
9194                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9195                                   osp.$ost*MDT0000.max_create_count")
9196                 $disable_precreate &&
9197                         do_facet $SINGLEMDS "lctl set_param -n \
9198                                 osp.$ost*MDT0000.max_create_count=0"
9199
9200                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9201                         [ -f $DIR/$tdir/$idx ] && continue
9202                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9203                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9204                                 { cleanup_65k;
9205                                   error "setstripe $idx should succeed"; }
9206                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9207                 done
9208                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9209                 rmdir $DIR/$tdir
9210
9211                 do_facet $SINGLEMDS "lctl set_param -n \
9212                         osp.$ost*MDT0000.max_create_count=$max_count"
9213                 do_facet $SINGLEMDS "lctl set_param -n \
9214                         osp.$ost*MDT0000.create_count=$count"
9215                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9216                 echo $INACTIVE_OSC "is Activate"
9217
9218                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9219         done
9220 }
9221 run_test 65k "validate manual striping works properly with deactivated OSCs"
9222
9223 test_65l() { # bug 12836
9224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9225
9226         test_mkdir -p $DIR/$tdir/test_dir
9227         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9228         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9229 }
9230 run_test 65l "lfs find on -1 stripe dir ========================"
9231
9232 test_65m() {
9233         local layout=$(save_layout $MOUNT)
9234         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9235                 restore_layout $MOUNT $layout
9236                 error "setstripe should fail by non-root users"
9237         }
9238         true
9239 }
9240 run_test 65m "normal user can't set filesystem default stripe"
9241
9242 test_65n() {
9243         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9244         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9245                 skip "Need MDS version at least 2.12.50"
9246         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9247
9248         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9249         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9250         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9251
9252         save_layout_restore_at_exit $MOUNT
9253
9254         # new subdirectory under root directory should not inherit
9255         # the default layout from root
9256         local dir1=$MOUNT/$tdir-1
9257         mkdir $dir1 || error "mkdir $dir1 failed"
9258         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9259                 error "$dir1 shouldn't have LOV EA"
9260
9261         # delete the default layout on root directory
9262         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9263
9264         local dir2=$MOUNT/$tdir-2
9265         mkdir $dir2 || error "mkdir $dir2 failed"
9266         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9267                 error "$dir2 shouldn't have LOV EA"
9268
9269         # set a new striping pattern on root directory
9270         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9271         local new_def_stripe_size=$((def_stripe_size * 2))
9272         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9273                 error "set stripe size on $MOUNT failed"
9274
9275         # new file created in $dir2 should inherit the new stripe size from
9276         # the filesystem default
9277         local file2=$dir2/$tfile-2
9278         touch $file2 || error "touch $file2 failed"
9279
9280         local file2_stripe_size=$($LFS getstripe -S $file2)
9281         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9282         {
9283                 echo "file2_stripe_size: '$file2_stripe_size'"
9284                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9285                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9286         }
9287
9288         local dir3=$MOUNT/$tdir-3
9289         mkdir $dir3 || error "mkdir $dir3 failed"
9290         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9291         # the root layout, which is the actual default layout that will be used
9292         # when new files are created in $dir3.
9293         local dir3_layout=$(get_layout_param $dir3)
9294         local root_dir_layout=$(get_layout_param $MOUNT)
9295         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9296         {
9297                 echo "dir3_layout: '$dir3_layout'"
9298                 echo "root_dir_layout: '$root_dir_layout'"
9299                 error "$dir3 should show the default layout from $MOUNT"
9300         }
9301
9302         # set OST pool on root directory
9303         local pool=$TESTNAME
9304         pool_add $pool || error "add $pool failed"
9305         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9306                 error "add targets to $pool failed"
9307
9308         $LFS setstripe -p $pool $MOUNT ||
9309                 error "set OST pool on $MOUNT failed"
9310
9311         # new file created in $dir3 should inherit the pool from
9312         # the filesystem default
9313         local file3=$dir3/$tfile-3
9314         touch $file3 || error "touch $file3 failed"
9315
9316         local file3_pool=$($LFS getstripe -p $file3)
9317         [[ "$file3_pool" = "$pool" ]] ||
9318                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9319
9320         local dir4=$MOUNT/$tdir-4
9321         mkdir $dir4 || error "mkdir $dir4 failed"
9322         local dir4_layout=$(get_layout_param $dir4)
9323         root_dir_layout=$(get_layout_param $MOUNT)
9324         echo "$LFS getstripe -d $dir4"
9325         $LFS getstripe -d $dir4
9326         echo "$LFS getstripe -d $MOUNT"
9327         $LFS getstripe -d $MOUNT
9328         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9329         {
9330                 echo "dir4_layout: '$dir4_layout'"
9331                 echo "root_dir_layout: '$root_dir_layout'"
9332                 error "$dir4 should show the default layout from $MOUNT"
9333         }
9334
9335         # new file created in $dir4 should inherit the pool from
9336         # the filesystem default
9337         local file4=$dir4/$tfile-4
9338         touch $file4 || error "touch $file4 failed"
9339
9340         local file4_pool=$($LFS getstripe -p $file4)
9341         [[ "$file4_pool" = "$pool" ]] ||
9342                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9343
9344         # new subdirectory under non-root directory should inherit
9345         # the default layout from its parent directory
9346         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9347                 error "set directory layout on $dir4 failed"
9348
9349         local dir5=$dir4/$tdir-5
9350         mkdir $dir5 || error "mkdir $dir5 failed"
9351
9352         dir4_layout=$(get_layout_param $dir4)
9353         local dir5_layout=$(get_layout_param $dir5)
9354         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9355         {
9356                 echo "dir4_layout: '$dir4_layout'"
9357                 echo "dir5_layout: '$dir5_layout'"
9358                 error "$dir5 should inherit the default layout from $dir4"
9359         }
9360
9361         # though subdir under ROOT doesn't inherit default layout, but
9362         # its sub dir/file should be created with default layout.
9363         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9364         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9365                 skip "Need MDS version at least 2.12.59"
9366
9367         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9368         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9369         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9370
9371         if [ $default_lmv_hash == "none" ]; then
9372                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9373         else
9374                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9375                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9376         fi
9377
9378         $LFS setdirstripe -D -c 2 $MOUNT ||
9379                 error "setdirstripe -D -c 2 failed"
9380         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9381         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9382         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9383 }
9384 run_test 65n "don't inherit default layout from root for new subdirectories"
9385
9386 # bug 2543 - update blocks count on client
9387 test_66() {
9388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9389
9390         COUNT=${COUNT:-8}
9391         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9392         sync; sync_all_data; sync; sync_all_data
9393         cancel_lru_locks osc
9394         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9395         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9396 }
9397 run_test 66 "update inode blocks count on client ==============="
9398
9399 meminfo() {
9400         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9401 }
9402
9403 swap_used() {
9404         swapon -s | awk '($1 == "'$1'") { print $4 }'
9405 }
9406
9407 # bug5265, obdfilter oa2dentry return -ENOENT
9408 # #define OBD_FAIL_SRV_ENOENT 0x217
9409 test_69() {
9410         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9411         remote_ost_nodsh && skip "remote OST with nodsh"
9412
9413         f="$DIR/$tfile"
9414         $LFS setstripe -c 1 -i 0 $f
9415
9416         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9417
9418         do_facet ost1 lctl set_param fail_loc=0x217
9419         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9420         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9421
9422         do_facet ost1 lctl set_param fail_loc=0
9423         $DIRECTIO write $f 0 2 || error "write error"
9424
9425         cancel_lru_locks osc
9426         $DIRECTIO read $f 0 1 || error "read error"
9427
9428         do_facet ost1 lctl set_param fail_loc=0x217
9429         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9430
9431         do_facet ost1 lctl set_param fail_loc=0
9432         rm -f $f
9433 }
9434 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9435
9436 test_71() {
9437         test_mkdir $DIR/$tdir
9438         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9439         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9440 }
9441 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9442
9443 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9445         [ "$RUNAS_ID" = "$UID" ] &&
9446                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9447         # Check that testing environment is properly set up. Skip if not
9448         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9449                 skip_env "User $RUNAS_ID does not exist - skipping"
9450
9451         touch $DIR/$tfile
9452         chmod 777 $DIR/$tfile
9453         chmod ug+s $DIR/$tfile
9454         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9455                 error "$RUNAS dd $DIR/$tfile failed"
9456         # See if we are still setuid/sgid
9457         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9458                 error "S/gid is not dropped on write"
9459         # Now test that MDS is updated too
9460         cancel_lru_locks mdc
9461         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9462                 error "S/gid is not dropped on MDS"
9463         rm -f $DIR/$tfile
9464 }
9465 run_test 72a "Test that remove suid works properly (bug5695) ===="
9466
9467 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9468         local perm
9469
9470         [ "$RUNAS_ID" = "$UID" ] &&
9471                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9472         [ "$RUNAS_ID" -eq 0 ] &&
9473                 skip_env "RUNAS_ID = 0 -- skipping"
9474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9475         # Check that testing environment is properly set up. Skip if not
9476         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9477                 skip_env "User $RUNAS_ID does not exist - skipping"
9478
9479         touch $DIR/${tfile}-f{g,u}
9480         test_mkdir $DIR/${tfile}-dg
9481         test_mkdir $DIR/${tfile}-du
9482         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9483         chmod g+s $DIR/${tfile}-{f,d}g
9484         chmod u+s $DIR/${tfile}-{f,d}u
9485         for perm in 777 2777 4777; do
9486                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9487                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9488                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9489                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9490         done
9491         true
9492 }
9493 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9494
9495 # bug 3462 - multiple simultaneous MDC requests
9496 test_73() {
9497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9498
9499         test_mkdir $DIR/d73-1
9500         test_mkdir $DIR/d73-2
9501         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9502         pid1=$!
9503
9504         lctl set_param fail_loc=0x80000129
9505         $MULTIOP $DIR/d73-1/f73-2 Oc &
9506         sleep 1
9507         lctl set_param fail_loc=0
9508
9509         $MULTIOP $DIR/d73-2/f73-3 Oc &
9510         pid3=$!
9511
9512         kill -USR1 $pid1
9513         wait $pid1 || return 1
9514
9515         sleep 25
9516
9517         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9518         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9519         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9520
9521         rm -rf $DIR/d73-*
9522 }
9523 run_test 73 "multiple MDC requests (should not deadlock)"
9524
9525 test_74a() { # bug 6149, 6184
9526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9527
9528         touch $DIR/f74a
9529         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9530         #
9531         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9532         # will spin in a tight reconnection loop
9533         $LCTL set_param fail_loc=0x8000030e
9534         # get any lock that won't be difficult - lookup works.
9535         ls $DIR/f74a
9536         $LCTL set_param fail_loc=0
9537         rm -f $DIR/f74a
9538         true
9539 }
9540 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9541
9542 test_74b() { # bug 13310
9543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9544
9545         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9546         #
9547         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9548         # will spin in a tight reconnection loop
9549         $LCTL set_param fail_loc=0x8000030e
9550         # get a "difficult" lock
9551         touch $DIR/f74b
9552         $LCTL set_param fail_loc=0
9553         rm -f $DIR/f74b
9554         true
9555 }
9556 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9557
9558 test_74c() {
9559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9560
9561         #define OBD_FAIL_LDLM_NEW_LOCK
9562         $LCTL set_param fail_loc=0x319
9563         touch $DIR/$tfile && error "touch successful"
9564         $LCTL set_param fail_loc=0
9565         true
9566 }
9567 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9568
9569 slab_lic=/sys/kernel/slab/lustre_inode_cache
9570 num_objects() {
9571         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9572         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9573                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9574 }
9575
9576 test_76a() { # Now for b=20433, added originally in b=1443
9577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9578
9579         cancel_lru_locks osc
9580         # there may be some slab objects cached per core
9581         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9582         local before=$(num_objects)
9583         local count=$((512 * cpus))
9584         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9585         local margin=$((count / 10))
9586         if [[ -f $slab_lic/aliases ]]; then
9587                 local aliases=$(cat $slab_lic/aliases)
9588                 (( aliases > 0 )) && margin=$((margin * aliases))
9589         fi
9590
9591         echo "before slab objects: $before"
9592         for i in $(seq $count); do
9593                 touch $DIR/$tfile
9594                 rm -f $DIR/$tfile
9595         done
9596         cancel_lru_locks osc
9597         local after=$(num_objects)
9598         echo "created: $count, after slab objects: $after"
9599         # shared slab counts are not very accurate, allow significant margin
9600         # the main goal is that the cache growth is not permanently > $count
9601         while (( after > before + margin )); do
9602                 sleep 1
9603                 after=$(num_objects)
9604                 wait=$((wait + 1))
9605                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9606                 if (( wait > 60 )); then
9607                         error "inode slab grew from $before+$margin to $after"
9608                 fi
9609         done
9610 }
9611 run_test 76a "confirm clients recycle inodes properly ===="
9612
9613 test_76b() {
9614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9615         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9616
9617         local count=512
9618         local before=$(num_objects)
9619
9620         for i in $(seq $count); do
9621                 mkdir $DIR/$tdir
9622                 rmdir $DIR/$tdir
9623         done
9624
9625         local after=$(num_objects)
9626         local wait=0
9627
9628         while (( after > before )); do
9629                 sleep 1
9630                 after=$(num_objects)
9631                 wait=$((wait + 1))
9632                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9633                 if (( wait > 60 )); then
9634                         error "inode slab grew from $before to $after"
9635                 fi
9636         done
9637
9638         echo "slab objects before: $before, after: $after"
9639 }
9640 run_test 76b "confirm clients recycle directory inodes properly ===="
9641
9642 export ORIG_CSUM=""
9643 set_checksums()
9644 {
9645         # Note: in sptlrpc modes which enable its own bulk checksum, the
9646         # original crc32_le bulk checksum will be automatically disabled,
9647         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9648         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9649         # In this case set_checksums() will not be no-op, because sptlrpc
9650         # bulk checksum will be enabled all through the test.
9651
9652         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9653         lctl set_param -n osc.*.checksums $1
9654         return 0
9655 }
9656
9657 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9658                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9659 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9660                              tr -d [] | head -n1)}
9661 set_checksum_type()
9662 {
9663         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9664         rc=$?
9665         log "set checksum type to $1, rc = $rc"
9666         return $rc
9667 }
9668
9669 get_osc_checksum_type()
9670 {
9671         # arugment 1: OST name, like OST0000
9672         ost=$1
9673         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9674                         sed 's/.*\[\(.*\)\].*/\1/g')
9675         rc=$?
9676         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9677         echo $checksum_type
9678 }
9679
9680 F77_TMP=$TMP/f77-temp
9681 F77SZ=8
9682 setup_f77() {
9683         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9684                 error "error writing to $F77_TMP"
9685 }
9686
9687 test_77a() { # bug 10889
9688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9689         $GSS && skip_env "could not run with gss"
9690
9691         [ ! -f $F77_TMP ] && setup_f77
9692         set_checksums 1
9693         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9694         set_checksums 0
9695         rm -f $DIR/$tfile
9696 }
9697 run_test 77a "normal checksum read/write operation"
9698
9699 test_77b() { # 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         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9705         $LCTL set_param fail_loc=0x80000409
9706         set_checksums 1
9707
9708         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9709                 error "dd error: $?"
9710         $LCTL set_param fail_loc=0
9711
9712         for algo in $CKSUM_TYPES; do
9713                 cancel_lru_locks osc
9714                 set_checksum_type $algo
9715                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9716                 $LCTL set_param fail_loc=0x80000408
9717                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9718                 $LCTL set_param fail_loc=0
9719         done
9720         set_checksums 0
9721         set_checksum_type $ORIG_CSUM_TYPE
9722         rm -f $DIR/$tfile
9723 }
9724 run_test 77b "checksum error on client write, read"
9725
9726 cleanup_77c() {
9727         trap 0
9728         set_checksums 0
9729         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9730         $check_ost &&
9731                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9732         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9733         $check_ost && [ -n "$ost_file_prefix" ] &&
9734                 do_facet ost1 rm -f ${ost_file_prefix}\*
9735 }
9736
9737 test_77c() {
9738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9739         $GSS && skip_env "could not run with gss"
9740         remote_ost_nodsh && skip "remote OST with nodsh"
9741
9742         local bad1
9743         local osc_file_prefix
9744         local osc_file
9745         local check_ost=false
9746         local ost_file_prefix
9747         local ost_file
9748         local orig_cksum
9749         local dump_cksum
9750         local fid
9751
9752         # ensure corruption will occur on first OSS/OST
9753         $LFS setstripe -i 0 $DIR/$tfile
9754
9755         [ ! -f $F77_TMP ] && setup_f77
9756         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9757                 error "dd write error: $?"
9758         fid=$($LFS path2fid $DIR/$tfile)
9759
9760         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9761         then
9762                 check_ost=true
9763                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9764                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9765         else
9766                 echo "OSS do not support bulk pages dump upon error"
9767         fi
9768
9769         osc_file_prefix=$($LCTL get_param -n debug_path)
9770         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9771
9772         trap cleanup_77c EXIT
9773
9774         set_checksums 1
9775         # enable bulk pages dump upon error on Client
9776         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9777         # enable bulk pages dump upon error on OSS
9778         $check_ost &&
9779                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9780
9781         # flush Client cache to allow next read to reach OSS
9782         cancel_lru_locks osc
9783
9784         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9785         $LCTL set_param fail_loc=0x80000408
9786         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9787         $LCTL set_param fail_loc=0
9788
9789         rm -f $DIR/$tfile
9790
9791         # check cksum dump on Client
9792         osc_file=$(ls ${osc_file_prefix}*)
9793         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9794         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9795         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9796         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9797         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9798                      cksum)
9799         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9800         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9801                 error "dump content does not match on Client"
9802
9803         $check_ost || skip "No need to check cksum dump on OSS"
9804
9805         # check cksum dump on OSS
9806         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9807         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9808         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9809         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9810         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9811                 error "dump content does not match on OSS"
9812
9813         cleanup_77c
9814 }
9815 run_test 77c "checksum error on client read with debug"
9816
9817 test_77d() { # bug 10889
9818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9819         $GSS && skip_env "could not run with gss"
9820
9821         stack_trap "rm -f $DIR/$tfile"
9822         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9823         $LCTL set_param fail_loc=0x80000409
9824         set_checksums 1
9825         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9826                 error "direct write: rc=$?"
9827         $LCTL set_param fail_loc=0
9828         set_checksums 0
9829
9830         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9831         $LCTL set_param fail_loc=0x80000408
9832         set_checksums 1
9833         cancel_lru_locks osc
9834         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9835                 error "direct read: rc=$?"
9836         $LCTL set_param fail_loc=0
9837         set_checksums 0
9838 }
9839 run_test 77d "checksum error on OST direct write, read"
9840
9841 test_77f() { # bug 10889
9842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9843         $GSS && skip_env "could not run with gss"
9844
9845         set_checksums 1
9846         stack_trap "rm -f $DIR/$tfile"
9847         for algo in $CKSUM_TYPES; do
9848                 cancel_lru_locks osc
9849                 set_checksum_type $algo
9850                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9851                 $LCTL set_param fail_loc=0x409
9852                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9853                         error "direct write succeeded"
9854                 $LCTL set_param fail_loc=0
9855         done
9856         set_checksum_type $ORIG_CSUM_TYPE
9857         set_checksums 0
9858 }
9859 run_test 77f "repeat checksum error on write (expect error)"
9860
9861 test_77g() { # bug 10889
9862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9863         $GSS && skip_env "could not run with gss"
9864         remote_ost_nodsh && skip "remote OST with nodsh"
9865
9866         [ ! -f $F77_TMP ] && setup_f77
9867
9868         local file=$DIR/$tfile
9869         stack_trap "rm -f $file" EXIT
9870
9871         $LFS setstripe -c 1 -i 0 $file
9872         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9873         do_facet ost1 lctl set_param fail_loc=0x8000021a
9874         set_checksums 1
9875         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9876                 error "write error: rc=$?"
9877         do_facet ost1 lctl set_param fail_loc=0
9878         set_checksums 0
9879
9880         cancel_lru_locks osc
9881         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9882         do_facet ost1 lctl set_param fail_loc=0x8000021b
9883         set_checksums 1
9884         cmp $F77_TMP $file || error "file compare failed"
9885         do_facet ost1 lctl set_param fail_loc=0
9886         set_checksums 0
9887 }
9888 run_test 77g "checksum error on OST write, read"
9889
9890 test_77k() { # LU-10906
9891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9892         $GSS && skip_env "could not run with gss"
9893
9894         local cksum_param="osc.$FSNAME*.checksums"
9895         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9896         local checksum
9897         local i
9898
9899         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9900         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9901         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9902
9903         for i in 0 1; do
9904                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9905                         error "failed to set checksum=$i on MGS"
9906                 wait_update $HOSTNAME "$get_checksum" $i
9907                 #remount
9908                 echo "remount client, checksum should be $i"
9909                 remount_client $MOUNT || error "failed to remount client"
9910                 checksum=$(eval $get_checksum)
9911                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9912         done
9913         # remove persistent param to avoid races with checksum mountopt below
9914         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9915                 error "failed to delete checksum on MGS"
9916
9917         for opt in "checksum" "nochecksum"; do
9918                 #remount with mount option
9919                 echo "remount client with option $opt, checksum should be $i"
9920                 umount_client $MOUNT || error "failed to umount client"
9921                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9922                         error "failed to mount client with option '$opt'"
9923                 checksum=$(eval $get_checksum)
9924                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9925                 i=$((i - 1))
9926         done
9927
9928         remount_client $MOUNT || error "failed to remount client"
9929 }
9930 run_test 77k "enable/disable checksum correctly"
9931
9932 test_77l() {
9933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9934         $GSS && skip_env "could not run with gss"
9935
9936         set_checksums 1
9937         stack_trap "set_checksums $ORIG_CSUM" EXIT
9938         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9939
9940         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9941
9942         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9943         for algo in $CKSUM_TYPES; do
9944                 set_checksum_type $algo || error "fail to set checksum type $algo"
9945                 osc_algo=$(get_osc_checksum_type OST0000)
9946                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9947
9948                 # no locks, no reqs to let the connection idle
9949                 cancel_lru_locks osc
9950                 lru_resize_disable osc
9951                 wait_osc_import_state client ost1 IDLE
9952
9953                 # ensure ost1 is connected
9954                 stat $DIR/$tfile >/dev/null || error "can't stat"
9955                 wait_osc_import_state client ost1 FULL
9956
9957                 osc_algo=$(get_osc_checksum_type OST0000)
9958                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9959         done
9960         return 0
9961 }
9962 run_test 77l "preferred checksum type is remembered after reconnected"
9963
9964 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9965 rm -f $F77_TMP
9966 unset F77_TMP
9967
9968 test_77m() {
9969         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
9970                 skip "Need at least version 2.14.52"
9971         local param=checksum_speed
9972
9973         $LCTL get_param $param || error "reading $param failed"
9974
9975         csum_speeds=$($LCTL get_param -n $param)
9976
9977         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
9978                 error "known checksum types are missing"
9979 }
9980 run_test 77m "Verify checksum_speed is correctly read"
9981
9982 check_filefrag_77n() {
9983         local nr_ext=0
9984         local starts=()
9985         local ends=()
9986
9987         while read extidx a b start end rest; do
9988                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
9989                         nr_ext=$(( $nr_ext + 1 ))
9990                         starts+=( ${start%..} )
9991                         ends+=( ${end%:} )
9992                 fi
9993         done < <( filefrag -sv $1 )
9994
9995         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
9996         return 1
9997 }
9998
9999 test_77n() {
10000         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10001
10002         touch $DIR/$tfile
10003         $TRUNCATE $DIR/$tfile 0
10004         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10005         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10006         check_filefrag_77n $DIR/$tfile ||
10007                 skip "$tfile blocks not contiguous around hole"
10008
10009         set_checksums 1
10010         stack_trap "set_checksums $ORIG_CSUM" EXIT
10011         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10012         stack_trap "rm -f $DIR/$tfile"
10013
10014         for algo in $CKSUM_TYPES; do
10015                 if [[ "$algo" =~ ^t10 ]]; then
10016                         set_checksum_type $algo ||
10017                                 error "fail to set checksum type $algo"
10018                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10019                                 error "fail to read $tfile with $algo"
10020                 fi
10021         done
10022         rm -f $DIR/$tfile
10023         return 0
10024 }
10025 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10026
10027 test_77o() {
10028         (( $CLIENT_VERSION >= $(version_code 2.14.54) )) ||
10029                 skip "Need at least version 2.14.54"
10030         local ofd=obdfilter
10031         local mdt=mdt
10032
10033         # print OST checksum_type
10034         echo "$ofd.$FSNAME-*.checksum_type:"
10035         do_nodes $(comma_list $(osts_nodes)) \
10036                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10037
10038         # print MDT checksum_type
10039         echo "$mdt.$FSNAME-*.checksum_type:"
10040         do_nodes $(comma_list $(mdts_nodes)) \
10041                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10042
10043         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10044                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10045
10046         (( $o_count == $OSTCOUNT )) ||
10047                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10048
10049         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10050                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10051
10052         (( $m_count == $MDSCOUNT )) ||
10053                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10054 }
10055 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10056
10057 cleanup_test_78() {
10058         trap 0
10059         rm -f $DIR/$tfile
10060 }
10061
10062 test_78() { # bug 10901
10063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10064         remote_ost || skip_env "local OST"
10065
10066         NSEQ=5
10067         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10068         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10069         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10070         echo "MemTotal: $MEMTOTAL"
10071
10072         # reserve 256MB of memory for the kernel and other running processes,
10073         # and then take 1/2 of the remaining memory for the read/write buffers.
10074         if [ $MEMTOTAL -gt 512 ] ;then
10075                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10076         else
10077                 # for those poor memory-starved high-end clusters...
10078                 MEMTOTAL=$((MEMTOTAL / 2))
10079         fi
10080         echo "Mem to use for directio: $MEMTOTAL"
10081
10082         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10083         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10084         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10085         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10086                 head -n1)
10087         echo "Smallest OST: $SMALLESTOST"
10088         [[ $SMALLESTOST -lt 10240 ]] &&
10089                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10090
10091         trap cleanup_test_78 EXIT
10092
10093         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10094                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10095
10096         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10097         echo "File size: $F78SIZE"
10098         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10099         for i in $(seq 1 $NSEQ); do
10100                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10101                 echo directIO rdwr round $i of $NSEQ
10102                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10103         done
10104
10105         cleanup_test_78
10106 }
10107 run_test 78 "handle large O_DIRECT writes correctly ============"
10108
10109 test_79() { # bug 12743
10110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10111
10112         wait_delete_completed
10113
10114         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10115         BKFREE=$(calc_osc_kbytes kbytesfree)
10116         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10117
10118         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10119         DFTOTAL=`echo $STRING | cut -d, -f1`
10120         DFUSED=`echo $STRING  | cut -d, -f2`
10121         DFAVAIL=`echo $STRING | cut -d, -f3`
10122         DFFREE=$(($DFTOTAL - $DFUSED))
10123
10124         ALLOWANCE=$((64 * $OSTCOUNT))
10125
10126         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10127            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10128                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10129         fi
10130         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10131            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10132                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10133         fi
10134         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10135            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10136                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10137         fi
10138 }
10139 run_test 79 "df report consistency check ======================="
10140
10141 test_80() { # bug 10718
10142         remote_ost_nodsh && skip "remote OST with nodsh"
10143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10144
10145         # relax strong synchronous semantics for slow backends like ZFS
10146         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10147                 local soc="obdfilter.*.sync_lock_cancel"
10148                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10149
10150                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10151                 if [ -z "$save" ]; then
10152                         soc="obdfilter.*.sync_on_lock_cancel"
10153                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10154                 fi
10155
10156                 if [ "$save" != "never" ]; then
10157                         local hosts=$(comma_list $(osts_nodes))
10158
10159                         do_nodes $hosts $LCTL set_param $soc=never
10160                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10161                 fi
10162         fi
10163
10164         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10165         sync; sleep 1; sync
10166         local before=$(date +%s)
10167         cancel_lru_locks osc
10168         local after=$(date +%s)
10169         local diff=$((after - before))
10170         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10171
10172         rm -f $DIR/$tfile
10173 }
10174 run_test 80 "Page eviction is equally fast at high offsets too"
10175
10176 test_81a() { # LU-456
10177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10178         remote_ost_nodsh && skip "remote OST with nodsh"
10179
10180         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10181         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10182         do_facet ost1 lctl set_param fail_loc=0x80000228
10183
10184         # write should trigger a retry and success
10185         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10186         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10187         RC=$?
10188         if [ $RC -ne 0 ] ; then
10189                 error "write should success, but failed for $RC"
10190         fi
10191 }
10192 run_test 81a "OST should retry write when get -ENOSPC ==============="
10193
10194 test_81b() { # LU-456
10195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10196         remote_ost_nodsh && skip "remote OST with nodsh"
10197
10198         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10199         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10200         do_facet ost1 lctl set_param fail_loc=0x228
10201
10202         # write should retry several times and return -ENOSPC finally
10203         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10204         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10205         RC=$?
10206         ENOSPC=28
10207         if [ $RC -ne $ENOSPC ] ; then
10208                 error "dd should fail for -ENOSPC, but succeed."
10209         fi
10210 }
10211 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10212
10213 test_99() {
10214         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10215
10216         test_mkdir $DIR/$tdir.cvsroot
10217         chown $RUNAS_ID $DIR/$tdir.cvsroot
10218
10219         cd $TMP
10220         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10221
10222         cd /etc/init.d
10223         # some versions of cvs import exit(1) when asked to import links or
10224         # files they can't read.  ignore those files.
10225         local toignore=$(find . -type l -printf '-I %f\n' -o \
10226                          ! -perm /4 -printf '-I %f\n')
10227         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10228                 $tdir.reposname vtag rtag
10229
10230         cd $DIR
10231         test_mkdir $DIR/$tdir.reposname
10232         chown $RUNAS_ID $DIR/$tdir.reposname
10233         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10234
10235         cd $DIR/$tdir.reposname
10236         $RUNAS touch foo99
10237         $RUNAS cvs add -m 'addmsg' foo99
10238         $RUNAS cvs update
10239         $RUNAS cvs commit -m 'nomsg' foo99
10240         rm -fr $DIR/$tdir.cvsroot
10241 }
10242 run_test 99 "cvs strange file/directory operations"
10243
10244 test_100() {
10245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10246         [[ "$NETTYPE" =~ tcp ]] ||
10247                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10248         remote_ost_nodsh && skip "remote OST with nodsh"
10249         remote_mds_nodsh && skip "remote MDS with nodsh"
10250         remote_servers ||
10251                 skip "useless for local single node setup"
10252
10253         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10254                 [ "$PROT" != "tcp" ] && continue
10255                 RPORT=$(echo $REMOTE | cut -d: -f2)
10256                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10257
10258                 rc=0
10259                 LPORT=`echo $LOCAL | cut -d: -f2`
10260                 if [ $LPORT -ge 1024 ]; then
10261                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10262                         netstat -tna
10263                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10264                 fi
10265         done
10266         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10267 }
10268 run_test 100 "check local port using privileged port ==========="
10269
10270 function get_named_value()
10271 {
10272     local tag=$1
10273
10274     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10275 }
10276
10277 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10278                    awk '/^max_cached_mb/ { print $2 }')
10279
10280 cleanup_101a() {
10281         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10282         trap 0
10283 }
10284
10285 test_101a() {
10286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10287
10288         local s
10289         local discard
10290         local nreads=10000
10291         local cache_limit=32
10292
10293         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10294         trap cleanup_101a EXIT
10295         $LCTL set_param -n llite.*.read_ahead_stats=0
10296         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10297
10298         #
10299         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10300         #
10301         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10302         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10303
10304         discard=0
10305         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10306                    get_named_value 'read.but.discarded'); do
10307                         discard=$(($discard + $s))
10308         done
10309         cleanup_101a
10310
10311         $LCTL get_param osc.*-osc*.rpc_stats
10312         $LCTL get_param llite.*.read_ahead_stats
10313
10314         # Discard is generally zero, but sometimes a few random reads line up
10315         # and trigger larger readahead, which is wasted & leads to discards.
10316         if [[ $(($discard)) -gt $nreads ]]; then
10317                 error "too many ($discard) discarded pages"
10318         fi
10319         rm -f $DIR/$tfile || true
10320 }
10321 run_test 101a "check read-ahead for random reads"
10322
10323 setup_test101bc() {
10324         test_mkdir $DIR/$tdir
10325         local ssize=$1
10326         local FILE_LENGTH=$2
10327         STRIPE_OFFSET=0
10328
10329         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10330
10331         local list=$(comma_list $(osts_nodes))
10332         set_osd_param $list '' read_cache_enable 0
10333         set_osd_param $list '' writethrough_cache_enable 0
10334
10335         trap cleanup_test101bc EXIT
10336         # prepare the read-ahead file
10337         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10338
10339         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10340                                 count=$FILE_SIZE_MB 2> /dev/null
10341
10342 }
10343
10344 cleanup_test101bc() {
10345         trap 0
10346         rm -rf $DIR/$tdir
10347         rm -f $DIR/$tfile
10348
10349         local list=$(comma_list $(osts_nodes))
10350         set_osd_param $list '' read_cache_enable 1
10351         set_osd_param $list '' writethrough_cache_enable 1
10352 }
10353
10354 calc_total() {
10355         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10356 }
10357
10358 ra_check_101() {
10359         local READ_SIZE=$1
10360         local STRIPE_SIZE=$2
10361         local FILE_LENGTH=$3
10362         local RA_INC=1048576
10363         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
10364         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
10365                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
10366         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
10367                   get_named_value 'read.but.discarded' | calc_total)
10368         if [[ $DISCARD -gt $discard_limit ]]; then
10369                 $LCTL get_param llite.*.read_ahead_stats
10370                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
10371         else
10372                 echo "Read-ahead success for size ${READ_SIZE}"
10373         fi
10374 }
10375
10376 test_101b() {
10377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10378         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10379
10380         local STRIPE_SIZE=1048576
10381         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10382
10383         if [ $SLOW == "yes" ]; then
10384                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10385         else
10386                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10387         fi
10388
10389         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10390
10391         # prepare the read-ahead file
10392         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10393         cancel_lru_locks osc
10394         for BIDX in 2 4 8 16 32 64 128 256
10395         do
10396                 local BSIZE=$((BIDX*4096))
10397                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10398                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10399                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10400                 $LCTL set_param -n llite.*.read_ahead_stats=0
10401                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10402                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10403                 cancel_lru_locks osc
10404                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10405         done
10406         cleanup_test101bc
10407         true
10408 }
10409 run_test 101b "check stride-io mode read-ahead ================="
10410
10411 test_101c() {
10412         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10413
10414         local STRIPE_SIZE=1048576
10415         local FILE_LENGTH=$((STRIPE_SIZE*100))
10416         local nreads=10000
10417         local rsize=65536
10418         local osc_rpc_stats
10419
10420         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10421
10422         cancel_lru_locks osc
10423         $LCTL set_param osc.*.rpc_stats=0
10424         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10425         $LCTL get_param osc.*.rpc_stats
10426         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10427                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10428                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10429                 local size
10430
10431                 if [ $lines -le 20 ]; then
10432                         echo "continue debug"
10433                         continue
10434                 fi
10435                 for size in 1 2 4 8; do
10436                         local rpc=$(echo "$stats" |
10437                                     awk '($1 == "'$size':") {print $2; exit; }')
10438                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10439                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10440                 done
10441                 echo "$osc_rpc_stats check passed!"
10442         done
10443         cleanup_test101bc
10444         true
10445 }
10446 run_test 101c "check stripe_size aligned read-ahead"
10447
10448 test_101d() {
10449         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10450
10451         local file=$DIR/$tfile
10452         local sz_MB=${FILESIZE_101d:-80}
10453         local ra_MB=${READAHEAD_MB:-40}
10454
10455         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10456         [ $free_MB -lt $sz_MB ] &&
10457                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10458
10459         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10460         $LFS setstripe -c -1 $file || error "setstripe failed"
10461
10462         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10463         echo Cancel LRU locks on lustre client to flush the client cache
10464         cancel_lru_locks osc
10465
10466         echo Disable read-ahead
10467         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10468         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10469         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10470         $LCTL get_param -n llite.*.max_read_ahead_mb
10471
10472         echo "Reading the test file $file with read-ahead disabled"
10473         local sz_KB=$((sz_MB * 1024 / 4))
10474         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10475         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10476         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10477                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10478
10479         echo "Cancel LRU locks on lustre client to flush the client cache"
10480         cancel_lru_locks osc
10481         echo Enable read-ahead with ${ra_MB}MB
10482         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10483
10484         echo "Reading the test file $file with read-ahead enabled"
10485         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10486                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10487
10488         echo "read-ahead disabled time read $raOFF"
10489         echo "read-ahead enabled time read $raON"
10490
10491         rm -f $file
10492         wait_delete_completed
10493
10494         # use awk for this check instead of bash because it handles decimals
10495         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10496                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10497 }
10498 run_test 101d "file read with and without read-ahead enabled"
10499
10500 test_101e() {
10501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10502
10503         local file=$DIR/$tfile
10504         local size_KB=500  #KB
10505         local count=100
10506         local bsize=1024
10507
10508         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10509         local need_KB=$((count * size_KB))
10510         [[ $free_KB -le $need_KB ]] &&
10511                 skip_env "Need free space $need_KB, have $free_KB"
10512
10513         echo "Creating $count ${size_KB}K test files"
10514         for ((i = 0; i < $count; i++)); do
10515                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10516         done
10517
10518         echo "Cancel LRU locks on lustre client to flush the client cache"
10519         cancel_lru_locks $OSC
10520
10521         echo "Reset readahead stats"
10522         $LCTL set_param -n llite.*.read_ahead_stats=0
10523
10524         for ((i = 0; i < $count; i++)); do
10525                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10526         done
10527
10528         $LCTL get_param llite.*.max_cached_mb
10529         $LCTL get_param llite.*.read_ahead_stats
10530         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10531                      get_named_value 'misses' | calc_total)
10532
10533         for ((i = 0; i < $count; i++)); do
10534                 rm -rf $file.$i 2>/dev/null
10535         done
10536
10537         #10000 means 20% reads are missing in readahead
10538         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10539 }
10540 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10541
10542 test_101f() {
10543         which iozone || skip_env "no iozone installed"
10544
10545         local old_debug=$($LCTL get_param debug)
10546         old_debug=${old_debug#*=}
10547         $LCTL set_param debug="reada mmap"
10548
10549         # create a test file
10550         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10551
10552         echo Cancel LRU locks on lustre client to flush the client cache
10553         cancel_lru_locks osc
10554
10555         echo Reset readahead stats
10556         $LCTL set_param -n llite.*.read_ahead_stats=0
10557
10558         echo mmap read the file with small block size
10559         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10560                 > /dev/null 2>&1
10561
10562         echo checking missing pages
10563         $LCTL get_param llite.*.read_ahead_stats
10564         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10565                         get_named_value 'misses' | calc_total)
10566
10567         $LCTL set_param debug="$old_debug"
10568         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10569         rm -f $DIR/$tfile
10570 }
10571 run_test 101f "check mmap read performance"
10572
10573 test_101g_brw_size_test() {
10574         local mb=$1
10575         local pages=$((mb * 1048576 / PAGE_SIZE))
10576         local file=$DIR/$tfile
10577
10578         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10579                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10580         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10581                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10582                         return 2
10583         done
10584
10585         stack_trap "rm -f $file" EXIT
10586         $LCTL set_param -n osc.*.rpc_stats=0
10587
10588         # 10 RPCs should be enough for the test
10589         local count=10
10590         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10591                 { error "dd write ${mb} MB blocks failed"; return 3; }
10592         cancel_lru_locks osc
10593         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10594                 { error "dd write ${mb} MB blocks failed"; return 4; }
10595
10596         # calculate number of full-sized read and write RPCs
10597         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10598                 sed -n '/pages per rpc/,/^$/p' |
10599                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10600                 END { print reads,writes }'))
10601         # allow one extra full-sized read RPC for async readahead
10602         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10603                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10604         [[ ${rpcs[1]} == $count ]] ||
10605                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10606 }
10607
10608 test_101g() {
10609         remote_ost_nodsh && skip "remote OST with nodsh"
10610
10611         local rpcs
10612         local osts=$(get_facets OST)
10613         local list=$(comma_list $(osts_nodes))
10614         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10615         local brw_size="obdfilter.*.brw_size"
10616
10617         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10618
10619         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10620
10621         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10622                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10623                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10624            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10625                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10626                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10627
10628                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10629                         suffix="M"
10630
10631                 if [[ $orig_mb -lt 16 ]]; then
10632                         save_lustre_params $osts "$brw_size" > $p
10633                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10634                                 error "set 16MB RPC size failed"
10635
10636                         echo "remount client to enable new RPC size"
10637                         remount_client $MOUNT || error "remount_client failed"
10638                 fi
10639
10640                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10641                 # should be able to set brw_size=12, but no rpc_stats for that
10642                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10643         fi
10644
10645         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10646
10647         if [[ $orig_mb -lt 16 ]]; then
10648                 restore_lustre_params < $p
10649                 remount_client $MOUNT || error "remount_client restore failed"
10650         fi
10651
10652         rm -f $p $DIR/$tfile
10653 }
10654 run_test 101g "Big bulk(4/16 MiB) readahead"
10655
10656 test_101h() {
10657         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10658
10659         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10660                 error "dd 70M file failed"
10661         echo Cancel LRU locks on lustre client to flush the client cache
10662         cancel_lru_locks osc
10663
10664         echo "Reset readahead stats"
10665         $LCTL set_param -n llite.*.read_ahead_stats 0
10666
10667         echo "Read 10M of data but cross 64M bundary"
10668         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10669         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10670                      get_named_value 'misses' | calc_total)
10671         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10672         rm -f $p $DIR/$tfile
10673 }
10674 run_test 101h "Readahead should cover current read window"
10675
10676 test_101i() {
10677         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10678                 error "dd 10M file failed"
10679
10680         local max_per_file_mb=$($LCTL get_param -n \
10681                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10682         cancel_lru_locks osc
10683         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10684         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10685                 error "set max_read_ahead_per_file_mb to 1 failed"
10686
10687         echo "Reset readahead stats"
10688         $LCTL set_param llite.*.read_ahead_stats=0
10689
10690         dd if=$DIR/$tfile of=/dev/null bs=2M
10691
10692         $LCTL get_param llite.*.read_ahead_stats
10693         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10694                      awk '/misses/ { print $2 }')
10695         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10696         rm -f $DIR/$tfile
10697 }
10698 run_test 101i "allow current readahead to exceed reservation"
10699
10700 test_101j() {
10701         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10702                 error "setstripe $DIR/$tfile failed"
10703         local file_size=$((1048576 * 16))
10704         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10705         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10706
10707         echo Disable read-ahead
10708         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10709
10710         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10711         for blk in $PAGE_SIZE 1048576 $file_size; do
10712                 cancel_lru_locks osc
10713                 echo "Reset readahead stats"
10714                 $LCTL set_param -n llite.*.read_ahead_stats=0
10715                 local count=$(($file_size / $blk))
10716                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10717                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10718                              get_named_value 'failed.to.fast.read' | calc_total)
10719                 $LCTL get_param -n llite.*.read_ahead_stats
10720                 [ $miss -eq $count ] || error "expected $count got $miss"
10721         done
10722
10723         rm -f $p $DIR/$tfile
10724 }
10725 run_test 101j "A complete read block should be submitted when no RA"
10726
10727 setup_test102() {
10728         test_mkdir $DIR/$tdir
10729         chown $RUNAS_ID $DIR/$tdir
10730         STRIPE_SIZE=65536
10731         STRIPE_OFFSET=1
10732         STRIPE_COUNT=$OSTCOUNT
10733         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10734
10735         trap cleanup_test102 EXIT
10736         cd $DIR
10737         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10738         cd $DIR/$tdir
10739         for num in 1 2 3 4; do
10740                 for count in $(seq 1 $STRIPE_COUNT); do
10741                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10742                                 local size=`expr $STRIPE_SIZE \* $num`
10743                                 local file=file"$num-$idx-$count"
10744                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10745                         done
10746                 done
10747         done
10748
10749         cd $DIR
10750         $1 tar cf $TMP/f102.tar $tdir --xattrs
10751 }
10752
10753 cleanup_test102() {
10754         trap 0
10755         rm -f $TMP/f102.tar
10756         rm -rf $DIR/d0.sanity/d102
10757 }
10758
10759 test_102a() {
10760         [ "$UID" != 0 ] && skip "must run as root"
10761         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10762                 skip_env "must have user_xattr"
10763
10764         [ -z "$(which setfattr 2>/dev/null)" ] &&
10765                 skip_env "could not find setfattr"
10766
10767         local testfile=$DIR/$tfile
10768
10769         touch $testfile
10770         echo "set/get xattr..."
10771         setfattr -n trusted.name1 -v value1 $testfile ||
10772                 error "setfattr -n trusted.name1=value1 $testfile failed"
10773         getfattr -n trusted.name1 $testfile 2> /dev/null |
10774           grep "trusted.name1=.value1" ||
10775                 error "$testfile missing trusted.name1=value1"
10776
10777         setfattr -n user.author1 -v author1 $testfile ||
10778                 error "setfattr -n user.author1=author1 $testfile failed"
10779         getfattr -n user.author1 $testfile 2> /dev/null |
10780           grep "user.author1=.author1" ||
10781                 error "$testfile missing trusted.author1=author1"
10782
10783         echo "listxattr..."
10784         setfattr -n trusted.name2 -v value2 $testfile ||
10785                 error "$testfile unable to set trusted.name2"
10786         setfattr -n trusted.name3 -v value3 $testfile ||
10787                 error "$testfile unable to set trusted.name3"
10788         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10789             grep "trusted.name" | wc -l) -eq 3 ] ||
10790                 error "$testfile missing 3 trusted.name xattrs"
10791
10792         setfattr -n user.author2 -v author2 $testfile ||
10793                 error "$testfile unable to set user.author2"
10794         setfattr -n user.author3 -v author3 $testfile ||
10795                 error "$testfile unable to set user.author3"
10796         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10797             grep "user.author" | wc -l) -eq 3 ] ||
10798                 error "$testfile missing 3 user.author xattrs"
10799
10800         echo "remove xattr..."
10801         setfattr -x trusted.name1 $testfile ||
10802                 error "$testfile error deleting trusted.name1"
10803         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10804                 error "$testfile did not delete trusted.name1 xattr"
10805
10806         setfattr -x user.author1 $testfile ||
10807                 error "$testfile error deleting user.author1"
10808         echo "set lustre special xattr ..."
10809         $LFS setstripe -c1 $testfile
10810         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10811                 awk -F "=" '/trusted.lov/ { print $2 }' )
10812         setfattr -n "trusted.lov" -v $lovea $testfile ||
10813                 error "$testfile doesn't ignore setting trusted.lov again"
10814         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10815                 error "$testfile allow setting invalid trusted.lov"
10816         rm -f $testfile
10817 }
10818 run_test 102a "user xattr test =================================="
10819
10820 check_102b_layout() {
10821         local layout="$*"
10822         local testfile=$DIR/$tfile
10823
10824         echo "test layout '$layout'"
10825         $LFS setstripe $layout $testfile || error "setstripe failed"
10826         $LFS getstripe -y $testfile
10827
10828         echo "get/set/list trusted.lov xattr ..." # b=10930
10829         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10830         [[ "$value" =~ "trusted.lov" ]] ||
10831                 error "can't get trusted.lov from $testfile"
10832         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10833                 error "getstripe failed"
10834
10835         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10836
10837         value=$(cut -d= -f2 <<<$value)
10838         # LU-13168: truncated xattr should fail if short lov_user_md header
10839         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10840                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10841         for len in $lens; do
10842                 echo "setfattr $len $testfile.2"
10843                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10844                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10845         done
10846         local stripe_size=$($LFS getstripe -S $testfile.2)
10847         local stripe_count=$($LFS getstripe -c $testfile.2)
10848         [[ $stripe_size -eq 65536 ]] ||
10849                 error "stripe size $stripe_size != 65536"
10850         [[ $stripe_count -eq $stripe_count_orig ]] ||
10851                 error "stripe count $stripe_count != $stripe_count_orig"
10852         rm $testfile $testfile.2
10853 }
10854
10855 test_102b() {
10856         [ -z "$(which setfattr 2>/dev/null)" ] &&
10857                 skip_env "could not find setfattr"
10858         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10859
10860         # check plain layout
10861         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10862
10863         # and also check composite layout
10864         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10865
10866 }
10867 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10868
10869 test_102c() {
10870         [ -z "$(which setfattr 2>/dev/null)" ] &&
10871                 skip_env "could not find setfattr"
10872         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10873
10874         # b10930: get/set/list lustre.lov xattr
10875         echo "get/set/list lustre.lov xattr ..."
10876         test_mkdir $DIR/$tdir
10877         chown $RUNAS_ID $DIR/$tdir
10878         local testfile=$DIR/$tdir/$tfile
10879         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10880                 error "setstripe failed"
10881         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10882                 error "getstripe failed"
10883         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10884         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10885
10886         local testfile2=${testfile}2
10887         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10888                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10889
10890         $RUNAS $MCREATE $testfile2
10891         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10892         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10893         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10894         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10895         [ $stripe_count -eq $STRIPECOUNT ] ||
10896                 error "stripe count $stripe_count != $STRIPECOUNT"
10897 }
10898 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10899
10900 compare_stripe_info1() {
10901         local stripe_index_all_zero=true
10902
10903         for num in 1 2 3 4; do
10904                 for count in $(seq 1 $STRIPE_COUNT); do
10905                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10906                                 local size=$((STRIPE_SIZE * num))
10907                                 local file=file"$num-$offset-$count"
10908                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10909                                 [[ $stripe_size -ne $size ]] &&
10910                                     error "$file: size $stripe_size != $size"
10911                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10912                                 # allow fewer stripes to be created, ORI-601
10913                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10914                                     error "$file: count $stripe_count != $count"
10915                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10916                                 [[ $stripe_index -ne 0 ]] &&
10917                                         stripe_index_all_zero=false
10918                         done
10919                 done
10920         done
10921         $stripe_index_all_zero &&
10922                 error "all files are being extracted starting from OST index 0"
10923         return 0
10924 }
10925
10926 have_xattrs_include() {
10927         tar --help | grep -q xattrs-include &&
10928                 echo --xattrs-include="lustre.*"
10929 }
10930
10931 test_102d() {
10932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10933         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10934
10935         XINC=$(have_xattrs_include)
10936         setup_test102
10937         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10938         cd $DIR/$tdir/$tdir
10939         compare_stripe_info1
10940 }
10941 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10942
10943 test_102f() {
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         test_mkdir $DIR/$tdir.restore
10950         cd $DIR
10951         tar cf - --xattrs $tdir | tar xf - \
10952                 -C $DIR/$tdir.restore --xattrs $XINC
10953         cd $DIR/$tdir.restore/$tdir
10954         compare_stripe_info1
10955 }
10956 run_test 102f "tar copy files, not keep osts"
10957
10958 grow_xattr() {
10959         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10960                 skip "must have user_xattr"
10961         [ -z "$(which setfattr 2>/dev/null)" ] &&
10962                 skip_env "could not find setfattr"
10963         [ -z "$(which getfattr 2>/dev/null)" ] &&
10964                 skip_env "could not find getfattr"
10965
10966         local xsize=${1:-1024}  # in bytes
10967         local file=$DIR/$tfile
10968         local value="$(generate_string $xsize)"
10969         local xbig=trusted.big
10970         local toobig=$2
10971
10972         touch $file
10973         log "save $xbig on $file"
10974         if [ -z "$toobig" ]
10975         then
10976                 setfattr -n $xbig -v $value $file ||
10977                         error "saving $xbig on $file failed"
10978         else
10979                 setfattr -n $xbig -v $value $file &&
10980                         error "saving $xbig on $file succeeded"
10981                 return 0
10982         fi
10983
10984         local orig=$(get_xattr_value $xbig $file)
10985         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10986
10987         local xsml=trusted.sml
10988         log "save $xsml on $file"
10989         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10990
10991         local new=$(get_xattr_value $xbig $file)
10992         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10993
10994         log "grow $xsml on $file"
10995         setfattr -n $xsml -v "$value" $file ||
10996                 error "growing $xsml on $file failed"
10997
10998         new=$(get_xattr_value $xbig $file)
10999         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11000         log "$xbig still valid after growing $xsml"
11001
11002         rm -f $file
11003 }
11004
11005 test_102h() { # bug 15777
11006         grow_xattr 1024
11007 }
11008 run_test 102h "grow xattr from inside inode to external block"
11009
11010 test_102ha() {
11011         large_xattr_enabled || skip_env "ea_inode feature disabled"
11012
11013         echo "setting xattr of max xattr size: $(max_xattr_size)"
11014         grow_xattr $(max_xattr_size)
11015
11016         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11017         echo "This should fail:"
11018         grow_xattr $(($(max_xattr_size) + 10)) 1
11019 }
11020 run_test 102ha "grow xattr from inside inode to external inode"
11021
11022 test_102i() { # bug 17038
11023         [ -z "$(which getfattr 2>/dev/null)" ] &&
11024                 skip "could not find getfattr"
11025
11026         touch $DIR/$tfile
11027         ln -s $DIR/$tfile $DIR/${tfile}link
11028         getfattr -n trusted.lov $DIR/$tfile ||
11029                 error "lgetxattr on $DIR/$tfile failed"
11030         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11031                 grep -i "no such attr" ||
11032                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11033         rm -f $DIR/$tfile $DIR/${tfile}link
11034 }
11035 run_test 102i "lgetxattr test on symbolic link ============"
11036
11037 test_102j() {
11038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11039         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11040
11041         XINC=$(have_xattrs_include)
11042         setup_test102 "$RUNAS"
11043         chown $RUNAS_ID $DIR/$tdir
11044         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11045         cd $DIR/$tdir/$tdir
11046         compare_stripe_info1 "$RUNAS"
11047 }
11048 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11049
11050 test_102k() {
11051         [ -z "$(which setfattr 2>/dev/null)" ] &&
11052                 skip "could not find setfattr"
11053
11054         touch $DIR/$tfile
11055         # b22187 just check that does not crash for regular file.
11056         setfattr -n trusted.lov $DIR/$tfile
11057         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11058         local test_kdir=$DIR/$tdir
11059         test_mkdir $test_kdir
11060         local default_size=$($LFS getstripe -S $test_kdir)
11061         local default_count=$($LFS getstripe -c $test_kdir)
11062         local default_offset=$($LFS getstripe -i $test_kdir)
11063         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11064                 error 'dir setstripe failed'
11065         setfattr -n trusted.lov $test_kdir
11066         local stripe_size=$($LFS getstripe -S $test_kdir)
11067         local stripe_count=$($LFS getstripe -c $test_kdir)
11068         local stripe_offset=$($LFS getstripe -i $test_kdir)
11069         [ $stripe_size -eq $default_size ] ||
11070                 error "stripe size $stripe_size != $default_size"
11071         [ $stripe_count -eq $default_count ] ||
11072                 error "stripe count $stripe_count != $default_count"
11073         [ $stripe_offset -eq $default_offset ] ||
11074                 error "stripe offset $stripe_offset != $default_offset"
11075         rm -rf $DIR/$tfile $test_kdir
11076 }
11077 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11078
11079 test_102l() {
11080         [ -z "$(which getfattr 2>/dev/null)" ] &&
11081                 skip "could not find getfattr"
11082
11083         # LU-532 trusted. xattr is invisible to non-root
11084         local testfile=$DIR/$tfile
11085
11086         touch $testfile
11087
11088         echo "listxattr as user..."
11089         chown $RUNAS_ID $testfile
11090         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11091             grep -q "trusted" &&
11092                 error "$testfile trusted xattrs are user visible"
11093
11094         return 0;
11095 }
11096 run_test 102l "listxattr size test =================================="
11097
11098 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11099         local path=$DIR/$tfile
11100         touch $path
11101
11102         listxattr_size_check $path || error "listattr_size_check $path failed"
11103 }
11104 run_test 102m "Ensure listxattr fails on small bufffer ========"
11105
11106 cleanup_test102
11107
11108 getxattr() { # getxattr path name
11109         # Return the base64 encoding of the value of xattr name on path.
11110         local path=$1
11111         local name=$2
11112
11113         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11114         # file: $path
11115         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11116         #
11117         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11118
11119         getfattr --absolute-names --encoding=base64 --name=$name $path |
11120                 awk -F= -v name=$name '$1 == name {
11121                         print substr($0, index($0, "=") + 1);
11122         }'
11123 }
11124
11125 test_102n() { # LU-4101 mdt: protect internal xattrs
11126         [ -z "$(which setfattr 2>/dev/null)" ] &&
11127                 skip "could not find setfattr"
11128         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11129         then
11130                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11131         fi
11132
11133         local file0=$DIR/$tfile.0
11134         local file1=$DIR/$tfile.1
11135         local xattr0=$TMP/$tfile.0
11136         local xattr1=$TMP/$tfile.1
11137         local namelist="lov lma lmv link fid version som hsm"
11138         local name
11139         local value
11140
11141         rm -rf $file0 $file1 $xattr0 $xattr1
11142         touch $file0 $file1
11143
11144         # Get 'before' xattrs of $file1.
11145         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11146
11147         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11148                 namelist+=" lfsck_namespace"
11149         for name in $namelist; do
11150                 # Try to copy xattr from $file0 to $file1.
11151                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11152
11153                 setfattr --name=trusted.$name --value="$value" $file1 ||
11154                         error "setxattr 'trusted.$name' failed"
11155
11156                 # Try to set a garbage xattr.
11157                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11158
11159                 if [[ x$name == "xlov" ]]; then
11160                         setfattr --name=trusted.lov --value="$value" $file1 &&
11161                         error "setxattr invalid 'trusted.lov' success"
11162                 else
11163                         setfattr --name=trusted.$name --value="$value" $file1 ||
11164                                 error "setxattr invalid 'trusted.$name' failed"
11165                 fi
11166
11167                 # Try to remove the xattr from $file1. We don't care if this
11168                 # appears to succeed or fail, we just don't want there to be
11169                 # any changes or crashes.
11170                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11171         done
11172
11173         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11174         then
11175                 name="lfsck_ns"
11176                 # Try to copy xattr from $file0 to $file1.
11177                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11178
11179                 setfattr --name=trusted.$name --value="$value" $file1 ||
11180                         error "setxattr 'trusted.$name' failed"
11181
11182                 # Try to set a garbage xattr.
11183                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11184
11185                 setfattr --name=trusted.$name --value="$value" $file1 ||
11186                         error "setxattr 'trusted.$name' failed"
11187
11188                 # Try to remove the xattr from $file1. We don't care if this
11189                 # appears to succeed or fail, we just don't want there to be
11190                 # any changes or crashes.
11191                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11192         fi
11193
11194         # Get 'after' xattrs of file1.
11195         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11196
11197         if ! diff $xattr0 $xattr1; then
11198                 error "before and after xattrs of '$file1' differ"
11199         fi
11200
11201         rm -rf $file0 $file1 $xattr0 $xattr1
11202
11203         return 0
11204 }
11205 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11206
11207 test_102p() { # LU-4703 setxattr did not check ownership
11208         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11209                 skip "MDS needs to be at least 2.5.56"
11210
11211         local testfile=$DIR/$tfile
11212
11213         touch $testfile
11214
11215         echo "setfacl as user..."
11216         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11217         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11218
11219         echo "setfattr as user..."
11220         setfacl -m "u:$RUNAS_ID:---" $testfile
11221         $RUNAS setfattr -x system.posix_acl_access $testfile
11222         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11223 }
11224 run_test 102p "check setxattr(2) correctly fails without permission"
11225
11226 test_102q() {
11227         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11228                 skip "MDS needs to be at least 2.6.92"
11229
11230         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11231 }
11232 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11233
11234 test_102r() {
11235         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11236                 skip "MDS needs to be at least 2.6.93"
11237
11238         touch $DIR/$tfile || error "touch"
11239         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11240         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11241         rm $DIR/$tfile || error "rm"
11242
11243         #normal directory
11244         mkdir -p $DIR/$tdir || error "mkdir"
11245         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11246         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11247         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11248                 error "$testfile error deleting user.author1"
11249         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11250                 grep "user.$(basename $tdir)" &&
11251                 error "$tdir did not delete user.$(basename $tdir)"
11252         rmdir $DIR/$tdir || error "rmdir"
11253
11254         #striped directory
11255         test_mkdir $DIR/$tdir
11256         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11257         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11258         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11259                 error "$testfile error deleting user.author1"
11260         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11261                 grep "user.$(basename $tdir)" &&
11262                 error "$tdir did not delete user.$(basename $tdir)"
11263         rmdir $DIR/$tdir || error "rm striped dir"
11264 }
11265 run_test 102r "set EAs with empty values"
11266
11267 test_102s() {
11268         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11269                 skip "MDS needs to be at least 2.11.52"
11270
11271         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11272
11273         save_lustre_params client "llite.*.xattr_cache" > $save
11274
11275         for cache in 0 1; do
11276                 lctl set_param llite.*.xattr_cache=$cache
11277
11278                 rm -f $DIR/$tfile
11279                 touch $DIR/$tfile || error "touch"
11280                 for prefix in lustre security system trusted user; do
11281                         # Note getxattr() may fail with 'Operation not
11282                         # supported' or 'No such attribute' depending
11283                         # on prefix and cache.
11284                         getfattr -n $prefix.n102s $DIR/$tfile &&
11285                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11286                 done
11287         done
11288
11289         restore_lustre_params < $save
11290 }
11291 run_test 102s "getting nonexistent xattrs should fail"
11292
11293 test_102t() {
11294         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11295                 skip "MDS needs to be at least 2.11.52"
11296
11297         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11298
11299         save_lustre_params client "llite.*.xattr_cache" > $save
11300
11301         for cache in 0 1; do
11302                 lctl set_param llite.*.xattr_cache=$cache
11303
11304                 for buf_size in 0 256; do
11305                         rm -f $DIR/$tfile
11306                         touch $DIR/$tfile || error "touch"
11307                         setfattr -n user.multiop $DIR/$tfile
11308                         $MULTIOP $DIR/$tfile oa$buf_size ||
11309                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11310                 done
11311         done
11312
11313         restore_lustre_params < $save
11314 }
11315 run_test 102t "zero length xattr values handled correctly"
11316
11317 run_acl_subtest()
11318 {
11319     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11320     return $?
11321 }
11322
11323 test_103a() {
11324         [ "$UID" != 0 ] && skip "must run as root"
11325         $GSS && skip_env "could not run under gss"
11326         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11327                 skip_env "must have acl enabled"
11328         [ -z "$(which setfacl 2>/dev/null)" ] &&
11329                 skip_env "could not find setfacl"
11330         remote_mds_nodsh && skip "remote MDS with nodsh"
11331
11332         gpasswd -a daemon bin                           # LU-5641
11333         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11334
11335         declare -a identity_old
11336
11337         for num in $(seq $MDSCOUNT); do
11338                 switch_identity $num true || identity_old[$num]=$?
11339         done
11340
11341         SAVE_UMASK=$(umask)
11342         umask 0022
11343         mkdir -p $DIR/$tdir
11344         cd $DIR/$tdir
11345
11346         echo "performing cp ..."
11347         run_acl_subtest cp || error "run_acl_subtest cp failed"
11348         echo "performing getfacl-noacl..."
11349         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11350         echo "performing misc..."
11351         run_acl_subtest misc || error  "misc test failed"
11352         echo "performing permissions..."
11353         run_acl_subtest permissions || error "permissions failed"
11354         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11355         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11356                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11357                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11358         then
11359                 echo "performing permissions xattr..."
11360                 run_acl_subtest permissions_xattr ||
11361                         error "permissions_xattr failed"
11362         fi
11363         echo "performing setfacl..."
11364         run_acl_subtest setfacl || error  "setfacl test failed"
11365
11366         # inheritance test got from HP
11367         echo "performing inheritance..."
11368         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11369         chmod +x make-tree || error "chmod +x failed"
11370         run_acl_subtest inheritance || error "inheritance test failed"
11371         rm -f make-tree
11372
11373         echo "LU-974 ignore umask when acl is enabled..."
11374         run_acl_subtest 974 || error "LU-974 umask test failed"
11375         if [ $MDSCOUNT -ge 2 ]; then
11376                 run_acl_subtest 974_remote ||
11377                         error "LU-974 umask test failed under remote dir"
11378         fi
11379
11380         echo "LU-2561 newly created file is same size as directory..."
11381         if [ "$mds1_FSTYPE" != "zfs" ]; then
11382                 run_acl_subtest 2561 || error "LU-2561 test failed"
11383         else
11384                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11385         fi
11386
11387         run_acl_subtest 4924 || error "LU-4924 test failed"
11388
11389         cd $SAVE_PWD
11390         umask $SAVE_UMASK
11391
11392         for num in $(seq $MDSCOUNT); do
11393                 if [ "${identity_old[$num]}" = 1 ]; then
11394                         switch_identity $num false || identity_old[$num]=$?
11395                 fi
11396         done
11397 }
11398 run_test 103a "acl test"
11399
11400 test_103b() {
11401         declare -a pids
11402         local U
11403
11404         for U in {0..511}; do
11405                 {
11406                 local O=$(printf "%04o" $U)
11407
11408                 umask $(printf "%04o" $((511 ^ $O)))
11409                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11410                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11411
11412                 (( $S == ($O & 0666) )) ||
11413                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11414
11415                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11416                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11417                 (( $S == ($O & 0666) )) ||
11418                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11419
11420                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11421                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11422                 (( $S == ($O & 0666) )) ||
11423                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11424                 rm -f $DIR/$tfile.[smp]$0
11425                 } &
11426                 local pid=$!
11427
11428                 # limit the concurrently running threads to 64. LU-11878
11429                 local idx=$((U % 64))
11430                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11431                 pids[idx]=$pid
11432         done
11433         wait
11434 }
11435 run_test 103b "umask lfs setstripe"
11436
11437 test_103c() {
11438         mkdir -p $DIR/$tdir
11439         cp -rp $DIR/$tdir $DIR/$tdir.bak
11440
11441         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11442                 error "$DIR/$tdir shouldn't contain default ACL"
11443         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11444                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11445         true
11446 }
11447 run_test 103c "'cp -rp' won't set empty acl"
11448
11449 test_103e() {
11450         local numacl
11451         local fileacl
11452         local saved_debug=$($LCTL get_param -n debug)
11453
11454         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
11455                 skip "MDS needs to be at least 2.14.0"
11456
11457         large_xattr_enabled || skip_env "ea_inode feature disabled"
11458
11459         mkdir -p $DIR/$tdir
11460         # add big LOV EA to cause reply buffer overflow earlier
11461         $LFS setstripe -C 1000 $DIR/$tdir
11462         lctl set_param mdc.*-mdc*.stats=clear
11463
11464         $LCTL set_param debug=0
11465         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11466         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11467
11468         # add a large number of default ACLs (expect 8000+ for 2.13+)
11469         for U in {2..7000}; do
11470                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11471                         error "Able to add just $U default ACLs"
11472         done
11473         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11474         echo "$numacl default ACLs created"
11475
11476         stat $DIR/$tdir || error "Cannot stat directory"
11477         # check file creation
11478         touch $DIR/$tdir/$tfile ||
11479                 error "failed to create $tfile with $numacl default ACLs"
11480         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11481         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11482         echo "$fileacl ACLs were inherited"
11483         (( $fileacl == $numacl )) ||
11484                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11485         # check that new ACLs creation adds new ACLs to inherited ACLs
11486         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11487                 error "Cannot set new ACL"
11488         numacl=$((numacl + 1))
11489         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11490         (( $fileacl == $numacl )) ||
11491                 error "failed to add new ACL: $fileacl != $numacl as expected"
11492         # adds more ACLs to a file to reach their maximum at 8000+
11493         numacl=0
11494         for U in {20000..25000}; do
11495                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11496                 numacl=$((numacl + 1))
11497         done
11498         echo "Added $numacl more ACLs to the file"
11499         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11500         echo "Total $fileacl ACLs in file"
11501         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11502         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11503         rmdir $DIR/$tdir || error "Cannot remove directory"
11504 }
11505 run_test 103e "inheritance of big amount of default ACLs"
11506
11507 test_103f() {
11508         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11509                 skip "MDS needs to be at least 2.14.51"
11510
11511         large_xattr_enabled || skip_env "ea_inode feature disabled"
11512
11513         # enable changelog to consume more internal MDD buffers
11514         changelog_register
11515
11516         mkdir -p $DIR/$tdir
11517         # add big LOV EA
11518         $LFS setstripe -C 1000 $DIR/$tdir
11519         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11520         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11521         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11522         rmdir $DIR/$tdir || error "Cannot remove directory"
11523 }
11524 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11525
11526 test_104a() {
11527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11528
11529         touch $DIR/$tfile
11530         lfs df || error "lfs df failed"
11531         lfs df -ih || error "lfs df -ih failed"
11532         lfs df -h $DIR || error "lfs df -h $DIR failed"
11533         lfs df -i $DIR || error "lfs df -i $DIR failed"
11534         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11535         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11536
11537         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11538         lctl --device %$OSC deactivate
11539         lfs df || error "lfs df with deactivated OSC failed"
11540         lctl --device %$OSC activate
11541         # wait the osc back to normal
11542         wait_osc_import_ready client ost
11543
11544         lfs df || error "lfs df with reactivated OSC failed"
11545         rm -f $DIR/$tfile
11546 }
11547 run_test 104a "lfs df [-ih] [path] test ========================="
11548
11549 test_104b() {
11550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11551         [ $RUNAS_ID -eq $UID ] &&
11552                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11553
11554         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11555                         grep "Permission denied" | wc -l)))
11556         if [ $denied_cnt -ne 0 ]; then
11557                 error "lfs check servers test failed"
11558         fi
11559 }
11560 run_test 104b "$RUNAS lfs check servers test ===================="
11561
11562 #
11563 # Verify $1 is within range of $2.
11564 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11565 # $1 is <= 2% of $2. Else Fail.
11566 #
11567 value_in_range() {
11568         # Strip all units (M, G, T)
11569         actual=$(echo $1 | tr -d A-Z)
11570         expect=$(echo $2 | tr -d A-Z)
11571
11572         expect_lo=$(($expect * 98 / 100)) # 2% below
11573         expect_hi=$(($expect * 102 / 100)) # 2% above
11574
11575         # permit 2% drift above and below
11576         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11577 }
11578
11579 test_104c() {
11580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11581         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11582
11583         local ost_param="osd-zfs.$FSNAME-OST0000."
11584         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11585         local ofacets=$(get_facets OST)
11586         local mfacets=$(get_facets MDS)
11587         local saved_ost_blocks=
11588         local saved_mdt_blocks=
11589
11590         echo "Before recordsize change"
11591         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11592         df=($(df -h | grep "/mnt/lustre"$))
11593
11594         # For checking.
11595         echo "lfs output : ${lfs_df[*]}"
11596         echo "df  output : ${df[*]}"
11597
11598         for facet in ${ofacets//,/ }; do
11599                 if [ -z $saved_ost_blocks ]; then
11600                         saved_ost_blocks=$(do_facet $facet \
11601                                 lctl get_param -n $ost_param.blocksize)
11602                         echo "OST Blocksize: $saved_ost_blocks"
11603                 fi
11604                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11605                 do_facet $facet zfs set recordsize=32768 $ost
11606         done
11607
11608         # BS too small. Sufficient for functional testing.
11609         for facet in ${mfacets//,/ }; do
11610                 if [ -z $saved_mdt_blocks ]; then
11611                         saved_mdt_blocks=$(do_facet $facet \
11612                                 lctl get_param -n $mdt_param.blocksize)
11613                         echo "MDT Blocksize: $saved_mdt_blocks"
11614                 fi
11615                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11616                 do_facet $facet zfs set recordsize=32768 $mdt
11617         done
11618
11619         # Give new values chance to reflect change
11620         sleep 2
11621
11622         echo "After recordsize change"
11623         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11624         df_after=($(df -h | grep "/mnt/lustre"$))
11625
11626         # For checking.
11627         echo "lfs output : ${lfs_df_after[*]}"
11628         echo "df  output : ${df_after[*]}"
11629
11630         # Verify lfs df
11631         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11632                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11633         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11634                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11635         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11636                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11637
11638         # Verify df
11639         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11640                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11641         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11642                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11643         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11644                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11645
11646         # Restore MDT recordize back to original
11647         for facet in ${mfacets//,/ }; do
11648                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11649                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11650         done
11651
11652         # Restore OST recordize back to original
11653         for facet in ${ofacets//,/ }; do
11654                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11655                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11656         done
11657
11658         return 0
11659 }
11660 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11661
11662 test_105a() {
11663         # doesn't work on 2.4 kernels
11664         touch $DIR/$tfile
11665         if $(flock_is_enabled); then
11666                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11667         else
11668                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11669         fi
11670         rm -f $DIR/$tfile
11671 }
11672 run_test 105a "flock when mounted without -o flock test ========"
11673
11674 test_105b() {
11675         touch $DIR/$tfile
11676         if $(flock_is_enabled); then
11677                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11678         else
11679                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11680         fi
11681         rm -f $DIR/$tfile
11682 }
11683 run_test 105b "fcntl when mounted without -o flock test ========"
11684
11685 test_105c() {
11686         touch $DIR/$tfile
11687         if $(flock_is_enabled); then
11688                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11689         else
11690                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11691         fi
11692         rm -f $DIR/$tfile
11693 }
11694 run_test 105c "lockf when mounted without -o flock test"
11695
11696 test_105d() { # bug 15924
11697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11698
11699         test_mkdir $DIR/$tdir
11700         flock_is_enabled || skip_env "mount w/o flock enabled"
11701         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11702         $LCTL set_param fail_loc=0x80000315
11703         flocks_test 2 $DIR/$tdir
11704 }
11705 run_test 105d "flock race (should not freeze) ========"
11706
11707 test_105e() { # bug 22660 && 22040
11708         flock_is_enabled || skip_env "mount w/o flock enabled"
11709
11710         touch $DIR/$tfile
11711         flocks_test 3 $DIR/$tfile
11712 }
11713 run_test 105e "Two conflicting flocks from same process"
11714
11715 test_106() { #bug 10921
11716         test_mkdir $DIR/$tdir
11717         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11718         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11719 }
11720 run_test 106 "attempt exec of dir followed by chown of that dir"
11721
11722 test_107() {
11723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11724
11725         CDIR=`pwd`
11726         local file=core
11727
11728         cd $DIR
11729         rm -f $file
11730
11731         local save_pattern=$(sysctl -n kernel.core_pattern)
11732         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11733         sysctl -w kernel.core_pattern=$file
11734         sysctl -w kernel.core_uses_pid=0
11735
11736         ulimit -c unlimited
11737         sleep 60 &
11738         SLEEPPID=$!
11739
11740         sleep 1
11741
11742         kill -s 11 $SLEEPPID
11743         wait $SLEEPPID
11744         if [ -e $file ]; then
11745                 size=`stat -c%s $file`
11746                 [ $size -eq 0 ] && error "Fail to create core file $file"
11747         else
11748                 error "Fail to create core file $file"
11749         fi
11750         rm -f $file
11751         sysctl -w kernel.core_pattern=$save_pattern
11752         sysctl -w kernel.core_uses_pid=$save_uses_pid
11753         cd $CDIR
11754 }
11755 run_test 107 "Coredump on SIG"
11756
11757 test_110() {
11758         test_mkdir $DIR/$tdir
11759         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11760         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11761                 error "mkdir with 256 char should fail, but did not"
11762         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11763                 error "create with 255 char failed"
11764         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11765                 error "create with 256 char should fail, but did not"
11766
11767         ls -l $DIR/$tdir
11768         rm -rf $DIR/$tdir
11769 }
11770 run_test 110 "filename length checking"
11771
11772 #
11773 # Purpose: To verify dynamic thread (OSS) creation.
11774 #
11775 test_115() {
11776         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11777         remote_ost_nodsh && skip "remote OST with nodsh"
11778
11779         # Lustre does not stop service threads once they are started.
11780         # Reset number of running threads to default.
11781         stopall
11782         setupall
11783
11784         local OSTIO_pre
11785         local save_params="$TMP/sanity-$TESTNAME.parameters"
11786
11787         # Get ll_ost_io count before I/O
11788         OSTIO_pre=$(do_facet ost1 \
11789                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11790         # Exit if lustre is not running (ll_ost_io not running).
11791         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11792
11793         echo "Starting with $OSTIO_pre threads"
11794         local thread_max=$((OSTIO_pre * 2))
11795         local rpc_in_flight=$((thread_max * 2))
11796         # Number of I/O Process proposed to be started.
11797         local nfiles
11798         local facets=$(get_facets OST)
11799
11800         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11801         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11802
11803         # Set in_flight to $rpc_in_flight
11804         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11805                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11806         nfiles=${rpc_in_flight}
11807         # Set ost thread_max to $thread_max
11808         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11809
11810         # 5 Minutes should be sufficient for max number of OSS
11811         # threads(thread_max) to be created.
11812         local timeout=300
11813
11814         # Start I/O.
11815         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11816         test_mkdir $DIR/$tdir
11817         for i in $(seq $nfiles); do
11818                 local file=$DIR/$tdir/${tfile}-$i
11819                 $LFS setstripe -c -1 -i 0 $file
11820                 ($WTL $file $timeout)&
11821         done
11822
11823         # I/O Started - Wait for thread_started to reach thread_max or report
11824         # error if thread_started is more than thread_max.
11825         echo "Waiting for thread_started to reach thread_max"
11826         local thread_started=0
11827         local end_time=$((SECONDS + timeout))
11828
11829         while [ $SECONDS -le $end_time ] ; do
11830                 echo -n "."
11831                 # Get ost i/o thread_started count.
11832                 thread_started=$(do_facet ost1 \
11833                         "$LCTL get_param \
11834                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11835                 # Break out if thread_started is equal/greater than thread_max
11836                 if [[ $thread_started -ge $thread_max ]]; then
11837                         echo ll_ost_io thread_started $thread_started, \
11838                                 equal/greater than thread_max $thread_max
11839                         break
11840                 fi
11841                 sleep 1
11842         done
11843
11844         # Cleanup - We have the numbers, Kill i/o jobs if running.
11845         jobcount=($(jobs -p))
11846         for i in $(seq 0 $((${#jobcount[@]}-1)))
11847         do
11848                 kill -9 ${jobcount[$i]}
11849                 if [ $? -ne 0 ] ; then
11850                         echo Warning: \
11851                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11852                 fi
11853         done
11854
11855         # Cleanup files left by WTL binary.
11856         for i in $(seq $nfiles); do
11857                 local file=$DIR/$tdir/${tfile}-$i
11858                 rm -rf $file
11859                 if [ $? -ne 0 ] ; then
11860                         echo "Warning: Failed to delete file $file"
11861                 fi
11862         done
11863
11864         restore_lustre_params <$save_params
11865         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11866
11867         # Error out if no new thread has started or Thread started is greater
11868         # than thread max.
11869         if [[ $thread_started -le $OSTIO_pre ||
11870                         $thread_started -gt $thread_max ]]; then
11871                 error "ll_ost_io: thread_started $thread_started" \
11872                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11873                       "No new thread started or thread started greater " \
11874                       "than thread_max."
11875         fi
11876 }
11877 run_test 115 "verify dynamic thread creation===================="
11878
11879 free_min_max () {
11880         wait_delete_completed
11881         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11882         echo "OST kbytes available: ${AVAIL[@]}"
11883         MAXV=${AVAIL[0]}
11884         MAXI=0
11885         MINV=${AVAIL[0]}
11886         MINI=0
11887         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11888                 #echo OST $i: ${AVAIL[i]}kb
11889                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11890                         MAXV=${AVAIL[i]}
11891                         MAXI=$i
11892                 fi
11893                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11894                         MINV=${AVAIL[i]}
11895                         MINI=$i
11896                 fi
11897         done
11898         echo "Min free space: OST $MINI: $MINV"
11899         echo "Max free space: OST $MAXI: $MAXV"
11900 }
11901
11902 test_116a() { # was previously test_116()
11903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11904         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11905         remote_mds_nodsh && skip "remote MDS with nodsh"
11906
11907         echo -n "Free space priority "
11908         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11909                 head -n1
11910         declare -a AVAIL
11911         free_min_max
11912
11913         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11914         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11915         stack_trap simple_cleanup_common
11916
11917         # Check if we need to generate uneven OSTs
11918         test_mkdir -p $DIR/$tdir/OST${MINI}
11919         local FILL=$((MINV / 4))
11920         local DIFF=$((MAXV - MINV))
11921         local DIFF2=$((DIFF * 100 / MINV))
11922
11923         local threshold=$(do_facet $SINGLEMDS \
11924                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11925         threshold=${threshold%%%}
11926         echo -n "Check for uneven OSTs: "
11927         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11928
11929         if [[ $DIFF2 -gt $threshold ]]; then
11930                 echo "ok"
11931                 echo "Don't need to fill OST$MINI"
11932         else
11933                 # generate uneven OSTs. Write 2% over the QOS threshold value
11934                 echo "no"
11935                 DIFF=$((threshold - DIFF2 + 2))
11936                 DIFF2=$((MINV * DIFF / 100))
11937                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11938                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11939                         error "setstripe failed"
11940                 DIFF=$((DIFF2 / 2048))
11941                 i=0
11942                 while [ $i -lt $DIFF ]; do
11943                         i=$((i + 1))
11944                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11945                                 bs=2M count=1 2>/dev/null
11946                         echo -n .
11947                 done
11948                 echo .
11949                 sync
11950                 sleep_maxage
11951                 free_min_max
11952         fi
11953
11954         DIFF=$((MAXV - MINV))
11955         DIFF2=$((DIFF * 100 / MINV))
11956         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11957         if [ $DIFF2 -gt $threshold ]; then
11958                 echo "ok"
11959         else
11960                 skip "QOS imbalance criteria not met"
11961         fi
11962
11963         MINI1=$MINI
11964         MINV1=$MINV
11965         MAXI1=$MAXI
11966         MAXV1=$MAXV
11967
11968         # now fill using QOS
11969         $LFS setstripe -c 1 $DIR/$tdir
11970         FILL=$((FILL / 200))
11971         if [ $FILL -gt 600 ]; then
11972                 FILL=600
11973         fi
11974         echo "writing $FILL files to QOS-assigned OSTs"
11975         i=0
11976         while [ $i -lt $FILL ]; do
11977                 i=$((i + 1))
11978                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11979                         count=1 2>/dev/null
11980                 echo -n .
11981         done
11982         echo "wrote $i 200k files"
11983         sync
11984         sleep_maxage
11985
11986         echo "Note: free space may not be updated, so measurements might be off"
11987         free_min_max
11988         DIFF2=$((MAXV - MINV))
11989         echo "free space delta: orig $DIFF final $DIFF2"
11990         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11991         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11992         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11993         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11994         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11995         if [[ $DIFF -gt 0 ]]; then
11996                 FILL=$((DIFF2 * 100 / DIFF - 100))
11997                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11998         fi
11999
12000         # Figure out which files were written where
12001         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12002                awk '/'$MINI1': / {print $2; exit}')
12003         echo $UUID
12004         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12005         echo "$MINC files created on smaller OST $MINI1"
12006         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12007                awk '/'$MAXI1': / {print $2; exit}')
12008         echo $UUID
12009         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12010         echo "$MAXC files created on larger OST $MAXI1"
12011         if [[ $MINC -gt 0 ]]; then
12012                 FILL=$((MAXC * 100 / MINC - 100))
12013                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12014         fi
12015         [[ $MAXC -gt $MINC ]] ||
12016                 error_ignore LU-9 "stripe QOS didn't balance free space"
12017 }
12018 run_test 116a "stripe QOS: free space balance ==================="
12019
12020 test_116b() { # LU-2093
12021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12022         remote_mds_nodsh && skip "remote MDS with nodsh"
12023
12024 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12025         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12026                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12027         [ -z "$old_rr" ] && skip "no QOS"
12028         do_facet $SINGLEMDS lctl set_param \
12029                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12030         mkdir -p $DIR/$tdir
12031         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12032         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12033         do_facet $SINGLEMDS lctl set_param fail_loc=0
12034         rm -rf $DIR/$tdir
12035         do_facet $SINGLEMDS lctl set_param \
12036                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12037 }
12038 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12039
12040 test_117() # bug 10891
12041 {
12042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12043
12044         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12045         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12046         lctl set_param fail_loc=0x21e
12047         > $DIR/$tfile || error "truncate failed"
12048         lctl set_param fail_loc=0
12049         echo "Truncate succeeded."
12050         rm -f $DIR/$tfile
12051 }
12052 run_test 117 "verify osd extend =========="
12053
12054 NO_SLOW_RESENDCOUNT=4
12055 export OLD_RESENDCOUNT=""
12056 set_resend_count () {
12057         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12058         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12059         lctl set_param -n $PROC_RESENDCOUNT $1
12060         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12061 }
12062
12063 # for reduce test_118* time (b=14842)
12064 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12065
12066 # Reset async IO behavior after error case
12067 reset_async() {
12068         FILE=$DIR/reset_async
12069
12070         # Ensure all OSCs are cleared
12071         $LFS setstripe -c -1 $FILE
12072         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12073         sync
12074         rm $FILE
12075 }
12076
12077 test_118a() #bug 11710
12078 {
12079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12080
12081         reset_async
12082
12083         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12084         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12085         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12086
12087         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12088                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12089                 return 1;
12090         fi
12091         rm -f $DIR/$tfile
12092 }
12093 run_test 118a "verify O_SYNC works =========="
12094
12095 test_118b()
12096 {
12097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12098         remote_ost_nodsh && skip "remote OST with nodsh"
12099
12100         reset_async
12101
12102         #define OBD_FAIL_SRV_ENOENT 0x217
12103         set_nodes_failloc "$(osts_nodes)" 0x217
12104         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12105         RC=$?
12106         set_nodes_failloc "$(osts_nodes)" 0
12107         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12108         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12109                     grep -c writeback)
12110
12111         if [[ $RC -eq 0 ]]; then
12112                 error "Must return error due to dropped pages, rc=$RC"
12113                 return 1;
12114         fi
12115
12116         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12117                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12118                 return 1;
12119         fi
12120
12121         echo "Dirty pages not leaked on ENOENT"
12122
12123         # Due to the above error the OSC will issue all RPCs syncronously
12124         # until a subsequent RPC completes successfully without error.
12125         $MULTIOP $DIR/$tfile Ow4096yc
12126         rm -f $DIR/$tfile
12127
12128         return 0
12129 }
12130 run_test 118b "Reclaim dirty pages on fatal error =========="
12131
12132 test_118c()
12133 {
12134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12135
12136         # for 118c, restore the original resend count, LU-1940
12137         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12138                                 set_resend_count $OLD_RESENDCOUNT
12139         remote_ost_nodsh && skip "remote OST with nodsh"
12140
12141         reset_async
12142
12143         #define OBD_FAIL_OST_EROFS               0x216
12144         set_nodes_failloc "$(osts_nodes)" 0x216
12145
12146         # multiop should block due to fsync until pages are written
12147         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12148         MULTIPID=$!
12149         sleep 1
12150
12151         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12152                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12153         fi
12154
12155         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12156                     grep -c writeback)
12157         if [[ $WRITEBACK -eq 0 ]]; then
12158                 error "No page in writeback, writeback=$WRITEBACK"
12159         fi
12160
12161         set_nodes_failloc "$(osts_nodes)" 0
12162         wait $MULTIPID
12163         RC=$?
12164         if [[ $RC -ne 0 ]]; then
12165                 error "Multiop fsync failed, rc=$RC"
12166         fi
12167
12168         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12169         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12170                     grep -c writeback)
12171         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12172                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12173         fi
12174
12175         rm -f $DIR/$tfile
12176         echo "Dirty pages flushed via fsync on EROFS"
12177         return 0
12178 }
12179 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12180
12181 # continue to use small resend count to reduce test_118* time (b=14842)
12182 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12183
12184 test_118d()
12185 {
12186         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12187         remote_ost_nodsh && skip "remote OST with nodsh"
12188
12189         reset_async
12190
12191         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12192         set_nodes_failloc "$(osts_nodes)" 0x214
12193         # multiop should block due to fsync until pages are written
12194         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12195         MULTIPID=$!
12196         sleep 1
12197
12198         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12199                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12200         fi
12201
12202         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12203                     grep -c writeback)
12204         if [[ $WRITEBACK -eq 0 ]]; then
12205                 error "No page in writeback, writeback=$WRITEBACK"
12206         fi
12207
12208         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12209         set_nodes_failloc "$(osts_nodes)" 0
12210
12211         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12212         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12213                     grep -c writeback)
12214         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12215                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12216         fi
12217
12218         rm -f $DIR/$tfile
12219         echo "Dirty pages gaurenteed flushed via fsync"
12220         return 0
12221 }
12222 run_test 118d "Fsync validation inject a delay of the bulk =========="
12223
12224 test_118f() {
12225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12226
12227         reset_async
12228
12229         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12230         lctl set_param fail_loc=0x8000040a
12231
12232         # Should simulate EINVAL error which is fatal
12233         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12234         RC=$?
12235         if [[ $RC -eq 0 ]]; then
12236                 error "Must return error due to dropped pages, rc=$RC"
12237         fi
12238
12239         lctl set_param fail_loc=0x0
12240
12241         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12242         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12243         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12244                     grep -c writeback)
12245         if [[ $LOCKED -ne 0 ]]; then
12246                 error "Locked pages remain in cache, locked=$LOCKED"
12247         fi
12248
12249         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12250                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12251         fi
12252
12253         rm -f $DIR/$tfile
12254         echo "No pages locked after fsync"
12255
12256         reset_async
12257         return 0
12258 }
12259 run_test 118f "Simulate unrecoverable OSC side error =========="
12260
12261 test_118g() {
12262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12263
12264         reset_async
12265
12266         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12267         lctl set_param fail_loc=0x406
12268
12269         # simulate local -ENOMEM
12270         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12271         RC=$?
12272
12273         lctl set_param fail_loc=0
12274         if [[ $RC -eq 0 ]]; then
12275                 error "Must return error due to dropped pages, rc=$RC"
12276         fi
12277
12278         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12279         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12280         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12281                         grep -c writeback)
12282         if [[ $LOCKED -ne 0 ]]; then
12283                 error "Locked pages remain in cache, locked=$LOCKED"
12284         fi
12285
12286         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12287                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12288         fi
12289
12290         rm -f $DIR/$tfile
12291         echo "No pages locked after fsync"
12292
12293         reset_async
12294         return 0
12295 }
12296 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12297
12298 test_118h() {
12299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12300         remote_ost_nodsh && skip "remote OST with nodsh"
12301
12302         reset_async
12303
12304         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12305         set_nodes_failloc "$(osts_nodes)" 0x20e
12306         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12307         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12308         RC=$?
12309
12310         set_nodes_failloc "$(osts_nodes)" 0
12311         if [[ $RC -eq 0 ]]; then
12312                 error "Must return error due to dropped pages, rc=$RC"
12313         fi
12314
12315         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12316         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12317         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12318                     grep -c writeback)
12319         if [[ $LOCKED -ne 0 ]]; then
12320                 error "Locked pages remain in cache, locked=$LOCKED"
12321         fi
12322
12323         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12324                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12325         fi
12326
12327         rm -f $DIR/$tfile
12328         echo "No pages locked after fsync"
12329
12330         return 0
12331 }
12332 run_test 118h "Verify timeout in handling recoverables errors  =========="
12333
12334 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12335
12336 test_118i() {
12337         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12338         remote_ost_nodsh && skip "remote OST with nodsh"
12339
12340         reset_async
12341
12342         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12343         set_nodes_failloc "$(osts_nodes)" 0x20e
12344
12345         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12346         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12347         PID=$!
12348         sleep 5
12349         set_nodes_failloc "$(osts_nodes)" 0
12350
12351         wait $PID
12352         RC=$?
12353         if [[ $RC -ne 0 ]]; then
12354                 error "got error, but should be not, rc=$RC"
12355         fi
12356
12357         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12358         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12359         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12360         if [[ $LOCKED -ne 0 ]]; then
12361                 error "Locked pages remain in cache, locked=$LOCKED"
12362         fi
12363
12364         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12365                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12366         fi
12367
12368         rm -f $DIR/$tfile
12369         echo "No pages locked after fsync"
12370
12371         return 0
12372 }
12373 run_test 118i "Fix error before timeout in recoverable error  =========="
12374
12375 [ "$SLOW" = "no" ] && set_resend_count 4
12376
12377 test_118j() {
12378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12379         remote_ost_nodsh && skip "remote OST with nodsh"
12380
12381         reset_async
12382
12383         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12384         set_nodes_failloc "$(osts_nodes)" 0x220
12385
12386         # return -EIO from OST
12387         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12388         RC=$?
12389         set_nodes_failloc "$(osts_nodes)" 0x0
12390         if [[ $RC -eq 0 ]]; then
12391                 error "Must return error due to dropped pages, rc=$RC"
12392         fi
12393
12394         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12395         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12396         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12397         if [[ $LOCKED -ne 0 ]]; then
12398                 error "Locked pages remain in cache, locked=$LOCKED"
12399         fi
12400
12401         # in recoverable error on OST we want resend and stay until it finished
12402         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12403                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12404         fi
12405
12406         rm -f $DIR/$tfile
12407         echo "No pages locked after fsync"
12408
12409         return 0
12410 }
12411 run_test 118j "Simulate unrecoverable OST side error =========="
12412
12413 test_118k()
12414 {
12415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12416         remote_ost_nodsh && skip "remote OSTs with nodsh"
12417
12418         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12419         set_nodes_failloc "$(osts_nodes)" 0x20e
12420         test_mkdir $DIR/$tdir
12421
12422         for ((i=0;i<10;i++)); do
12423                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12424                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12425                 SLEEPPID=$!
12426                 sleep 0.500s
12427                 kill $SLEEPPID
12428                 wait $SLEEPPID
12429         done
12430
12431         set_nodes_failloc "$(osts_nodes)" 0
12432         rm -rf $DIR/$tdir
12433 }
12434 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12435
12436 test_118l() # LU-646
12437 {
12438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12439
12440         test_mkdir $DIR/$tdir
12441         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12442         rm -rf $DIR/$tdir
12443 }
12444 run_test 118l "fsync dir"
12445
12446 test_118m() # LU-3066
12447 {
12448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12449
12450         test_mkdir $DIR/$tdir
12451         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12452         rm -rf $DIR/$tdir
12453 }
12454 run_test 118m "fdatasync dir ========="
12455
12456 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12457
12458 test_118n()
12459 {
12460         local begin
12461         local end
12462
12463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12464         remote_ost_nodsh && skip "remote OSTs with nodsh"
12465
12466         # Sleep to avoid a cached response.
12467         #define OBD_STATFS_CACHE_SECONDS 1
12468         sleep 2
12469
12470         # Inject a 10 second delay in the OST_STATFS handler.
12471         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12472         set_nodes_failloc "$(osts_nodes)" 0x242
12473
12474         begin=$SECONDS
12475         stat --file-system $MOUNT > /dev/null
12476         end=$SECONDS
12477
12478         set_nodes_failloc "$(osts_nodes)" 0
12479
12480         if ((end - begin > 20)); then
12481             error "statfs took $((end - begin)) seconds, expected 10"
12482         fi
12483 }
12484 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12485
12486 test_119a() # bug 11737
12487 {
12488         BSIZE=$((512 * 1024))
12489         directio write $DIR/$tfile 0 1 $BSIZE
12490         # We ask to read two blocks, which is more than a file size.
12491         # directio will indicate an error when requested and actual
12492         # sizes aren't equeal (a normal situation in this case) and
12493         # print actual read amount.
12494         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12495         if [ "$NOB" != "$BSIZE" ]; then
12496                 error "read $NOB bytes instead of $BSIZE"
12497         fi
12498         rm -f $DIR/$tfile
12499 }
12500 run_test 119a "Short directIO read must return actual read amount"
12501
12502 test_119b() # bug 11737
12503 {
12504         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12505
12506         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12507         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12508         sync
12509         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12510                 error "direct read failed"
12511         rm -f $DIR/$tfile
12512 }
12513 run_test 119b "Sparse directIO read must return actual read amount"
12514
12515 test_119c() # bug 13099
12516 {
12517         BSIZE=1048576
12518         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12519         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12520         rm -f $DIR/$tfile
12521 }
12522 run_test 119c "Testing for direct read hitting hole"
12523
12524 test_119d() # bug 15950
12525 {
12526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12527
12528         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12529         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12530         BSIZE=1048576
12531         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12532         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12533         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12534         lctl set_param fail_loc=0x40d
12535         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12536         pid_dio=$!
12537         sleep 1
12538         cat $DIR/$tfile > /dev/null &
12539         lctl set_param fail_loc=0
12540         pid_reads=$!
12541         wait $pid_dio
12542         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12543         sleep 2
12544         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12545         error "the read rpcs have not completed in 2s"
12546         rm -f $DIR/$tfile
12547         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12548 }
12549 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12550
12551 test_120a() {
12552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12553         remote_mds_nodsh && skip "remote MDS with nodsh"
12554         test_mkdir -i0 -c1 $DIR/$tdir
12555         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12556                 skip_env "no early lock cancel on server"
12557
12558         lru_resize_disable mdc
12559         lru_resize_disable osc
12560         cancel_lru_locks mdc
12561         # asynchronous object destroy at MDT could cause bl ast to client
12562         cancel_lru_locks osc
12563
12564         stat $DIR/$tdir > /dev/null
12565         can1=$(do_facet mds1 \
12566                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12567                awk '/ldlm_cancel/ {print $2}')
12568         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12569                awk '/ldlm_bl_callback/ {print $2}')
12570         test_mkdir -i0 -c1 $DIR/$tdir/d1
12571         can2=$(do_facet mds1 \
12572                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12573                awk '/ldlm_cancel/ {print $2}')
12574         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12575                awk '/ldlm_bl_callback/ {print $2}')
12576         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12577         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12578         lru_resize_enable mdc
12579         lru_resize_enable osc
12580 }
12581 run_test 120a "Early Lock Cancel: mkdir test"
12582
12583 test_120b() {
12584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12585         remote_mds_nodsh && skip "remote MDS with nodsh"
12586         test_mkdir $DIR/$tdir
12587         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12588                 skip_env "no early lock cancel on server"
12589
12590         lru_resize_disable mdc
12591         lru_resize_disable osc
12592         cancel_lru_locks mdc
12593         stat $DIR/$tdir > /dev/null
12594         can1=$(do_facet $SINGLEMDS \
12595                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12596                awk '/ldlm_cancel/ {print $2}')
12597         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12598                awk '/ldlm_bl_callback/ {print $2}')
12599         touch $DIR/$tdir/f1
12600         can2=$(do_facet $SINGLEMDS \
12601                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12602                awk '/ldlm_cancel/ {print $2}')
12603         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12604                awk '/ldlm_bl_callback/ {print $2}')
12605         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12606         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12607         lru_resize_enable mdc
12608         lru_resize_enable osc
12609 }
12610 run_test 120b "Early Lock Cancel: create test"
12611
12612 test_120c() {
12613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12614         remote_mds_nodsh && skip "remote MDS with nodsh"
12615         test_mkdir -i0 -c1 $DIR/$tdir
12616         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12617                 skip "no early lock cancel on server"
12618
12619         lru_resize_disable mdc
12620         lru_resize_disable osc
12621         test_mkdir -i0 -c1 $DIR/$tdir/d1
12622         test_mkdir -i0 -c1 $DIR/$tdir/d2
12623         touch $DIR/$tdir/d1/f1
12624         cancel_lru_locks mdc
12625         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12626         can1=$(do_facet mds1 \
12627                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12628                awk '/ldlm_cancel/ {print $2}')
12629         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12630                awk '/ldlm_bl_callback/ {print $2}')
12631         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12632         can2=$(do_facet mds1 \
12633                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12634                awk '/ldlm_cancel/ {print $2}')
12635         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12636                awk '/ldlm_bl_callback/ {print $2}')
12637         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12638         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12639         lru_resize_enable mdc
12640         lru_resize_enable osc
12641 }
12642 run_test 120c "Early Lock Cancel: link test"
12643
12644 test_120d() {
12645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12646         remote_mds_nodsh && skip "remote MDS with nodsh"
12647         test_mkdir -i0 -c1 $DIR/$tdir
12648         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12649                 skip_env "no early lock cancel on server"
12650
12651         lru_resize_disable mdc
12652         lru_resize_disable osc
12653         touch $DIR/$tdir
12654         cancel_lru_locks mdc
12655         stat $DIR/$tdir > /dev/null
12656         can1=$(do_facet mds1 \
12657                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12658                awk '/ldlm_cancel/ {print $2}')
12659         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12660                awk '/ldlm_bl_callback/ {print $2}')
12661         chmod a+x $DIR/$tdir
12662         can2=$(do_facet mds1 \
12663                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12664                awk '/ldlm_cancel/ {print $2}')
12665         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12666                awk '/ldlm_bl_callback/ {print $2}')
12667         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12668         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12669         lru_resize_enable mdc
12670         lru_resize_enable osc
12671 }
12672 run_test 120d "Early Lock Cancel: setattr test"
12673
12674 test_120e() {
12675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12676         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12677                 skip_env "no early lock cancel on server"
12678         remote_mds_nodsh && skip "remote MDS with nodsh"
12679
12680         local dlmtrace_set=false
12681
12682         test_mkdir -i0 -c1 $DIR/$tdir
12683         lru_resize_disable mdc
12684         lru_resize_disable osc
12685         ! $LCTL get_param debug | grep -q dlmtrace &&
12686                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12687         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12688         cancel_lru_locks mdc
12689         cancel_lru_locks osc
12690         dd if=$DIR/$tdir/f1 of=/dev/null
12691         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12692         # XXX client can not do early lock cancel of OST lock
12693         # during unlink (LU-4206), so cancel osc lock now.
12694         sleep 2
12695         cancel_lru_locks osc
12696         can1=$(do_facet mds1 \
12697                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12698                awk '/ldlm_cancel/ {print $2}')
12699         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12700                awk '/ldlm_bl_callback/ {print $2}')
12701         unlink $DIR/$tdir/f1
12702         sleep 5
12703         can2=$(do_facet mds1 \
12704                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12705                awk '/ldlm_cancel/ {print $2}')
12706         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12707                awk '/ldlm_bl_callback/ {print $2}')
12708         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12709                 $LCTL dk $TMP/cancel.debug.txt
12710         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12711                 $LCTL dk $TMP/blocking.debug.txt
12712         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12713         lru_resize_enable mdc
12714         lru_resize_enable osc
12715 }
12716 run_test 120e "Early Lock Cancel: unlink test"
12717
12718 test_120f() {
12719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12720         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12721                 skip_env "no early lock cancel on server"
12722         remote_mds_nodsh && skip "remote MDS with nodsh"
12723
12724         test_mkdir -i0 -c1 $DIR/$tdir
12725         lru_resize_disable mdc
12726         lru_resize_disable osc
12727         test_mkdir -i0 -c1 $DIR/$tdir/d1
12728         test_mkdir -i0 -c1 $DIR/$tdir/d2
12729         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12730         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12731         cancel_lru_locks mdc
12732         cancel_lru_locks osc
12733         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12734         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12735         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12736         # XXX client can not do early lock cancel of OST lock
12737         # during rename (LU-4206), so cancel osc lock now.
12738         sleep 2
12739         cancel_lru_locks osc
12740         can1=$(do_facet mds1 \
12741                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12742                awk '/ldlm_cancel/ {print $2}')
12743         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12744                awk '/ldlm_bl_callback/ {print $2}')
12745         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12746         sleep 5
12747         can2=$(do_facet mds1 \
12748                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12749                awk '/ldlm_cancel/ {print $2}')
12750         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12751                awk '/ldlm_bl_callback/ {print $2}')
12752         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12753         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12754         lru_resize_enable mdc
12755         lru_resize_enable osc
12756 }
12757 run_test 120f "Early Lock Cancel: rename test"
12758
12759 test_120g() {
12760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12761         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12762                 skip_env "no early lock cancel on server"
12763         remote_mds_nodsh && skip "remote MDS with nodsh"
12764
12765         lru_resize_disable mdc
12766         lru_resize_disable osc
12767         count=10000
12768         echo create $count files
12769         test_mkdir $DIR/$tdir
12770         cancel_lru_locks mdc
12771         cancel_lru_locks osc
12772         t0=$(date +%s)
12773
12774         can0=$(do_facet $SINGLEMDS \
12775                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12776                awk '/ldlm_cancel/ {print $2}')
12777         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12778                awk '/ldlm_bl_callback/ {print $2}')
12779         createmany -o $DIR/$tdir/f $count
12780         sync
12781         can1=$(do_facet $SINGLEMDS \
12782                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12783                awk '/ldlm_cancel/ {print $2}')
12784         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12785                awk '/ldlm_bl_callback/ {print $2}')
12786         t1=$(date +%s)
12787         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12788         echo rm $count files
12789         rm -r $DIR/$tdir
12790         sync
12791         can2=$(do_facet $SINGLEMDS \
12792                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12793                awk '/ldlm_cancel/ {print $2}')
12794         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12795                awk '/ldlm_bl_callback/ {print $2}')
12796         t2=$(date +%s)
12797         echo total: $count removes in $((t2-t1))
12798         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12799         sleep 2
12800         # wait for commitment of removal
12801         lru_resize_enable mdc
12802         lru_resize_enable osc
12803 }
12804 run_test 120g "Early Lock Cancel: performance test"
12805
12806 test_121() { #bug #10589
12807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12808
12809         rm -rf $DIR/$tfile
12810         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12811 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12812         lctl set_param fail_loc=0x310
12813         cancel_lru_locks osc > /dev/null
12814         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12815         lctl set_param fail_loc=0
12816         [[ $reads -eq $writes ]] ||
12817                 error "read $reads blocks, must be $writes blocks"
12818 }
12819 run_test 121 "read cancel race ========="
12820
12821 test_123a_base() { # was test 123, statahead(bug 11401)
12822         local lsx="$1"
12823
12824         SLOWOK=0
12825         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12826                 log "testing UP system. Performance may be lower than expected."
12827                 SLOWOK=1
12828         fi
12829
12830         rm -rf $DIR/$tdir
12831         test_mkdir $DIR/$tdir
12832         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12833         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12834         MULT=10
12835         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12836                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12837
12838                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12839                 lctl set_param -n llite.*.statahead_max 0
12840                 lctl get_param llite.*.statahead_max
12841                 cancel_lru_locks mdc
12842                 cancel_lru_locks osc
12843                 stime=$(date +%s)
12844                 time $lsx $DIR/$tdir | wc -l
12845                 etime=$(date +%s)
12846                 delta=$((etime - stime))
12847                 log "$lsx $i files without statahead: $delta sec"
12848                 lctl set_param llite.*.statahead_max=$max
12849
12850                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12851                         grep "statahead wrong:" | awk '{print $3}')
12852                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
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_sa=$((etime - stime))
12859                 log "$lsx $i files with statahead: $delta_sa sec"
12860                 lctl get_param -n llite.*.statahead_stats
12861                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12862                         grep "statahead wrong:" | awk '{print $3}')
12863
12864                 [[ $swrong -lt $ewrong ]] &&
12865                         log "statahead was stopped, maybe too many locks held!"
12866                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12867
12868                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12869                         max=$(lctl get_param -n llite.*.statahead_max |
12870                                 head -n 1)
12871                         lctl set_param -n llite.*.statahead_max 0
12872                         lctl get_param llite.*.statahead_max
12873                         cancel_lru_locks mdc
12874                         cancel_lru_locks osc
12875                         stime=$(date +%s)
12876                         time $lsx $DIR/$tdir | wc -l
12877                         etime=$(date +%s)
12878                         delta=$((etime - stime))
12879                         log "$lsx $i files again without statahead: $delta sec"
12880                         lctl set_param llite.*.statahead_max=$max
12881                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12882                                 if [  $SLOWOK -eq 0 ]; then
12883                                         error "$lsx $i files is slower with statahead!"
12884                                 else
12885                                         log "$lsx $i files is slower with statahead!"
12886                                 fi
12887                                 break
12888                         fi
12889                 fi
12890
12891                 [ $delta -gt 20 ] && break
12892                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12893                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12894         done
12895         log "$lsx done"
12896
12897         stime=$(date +%s)
12898         rm -r $DIR/$tdir
12899         sync
12900         etime=$(date +%s)
12901         delta=$((etime - stime))
12902         log "rm -r $DIR/$tdir/: $delta seconds"
12903         log "rm done"
12904         lctl get_param -n llite.*.statahead_stats
12905 }
12906
12907 test_123aa() {
12908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12909
12910         test_123a_base "ls -l"
12911 }
12912 run_test 123aa "verify statahead work"
12913
12914 test_123ab() {
12915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12916
12917         statx_supported || skip_env "Test must be statx() syscall supported"
12918
12919         test_123a_base "$STATX -l"
12920 }
12921 run_test 123ab "verify statahead work by using statx"
12922
12923 test_123ac() {
12924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12925
12926         statx_supported || skip_env "Test must be statx() syscall supported"
12927
12928         local rpcs_before
12929         local rpcs_after
12930         local agl_before
12931         local agl_after
12932
12933         cancel_lru_locks $OSC
12934         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12935         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12936                 awk '/agl.total:/ {print $3}')
12937         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12938         test_123a_base "$STATX --cached=always -D"
12939         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12940                 awk '/agl.total:/ {print $3}')
12941         [ $agl_before -eq $agl_after ] ||
12942                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12943         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12944         [ $rpcs_after -eq $rpcs_before ] ||
12945                 error "$STATX should not send glimpse RPCs to $OSC"
12946 }
12947 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12948
12949 test_123b () { # statahead(bug 15027)
12950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12951
12952         test_mkdir $DIR/$tdir
12953         createmany -o $DIR/$tdir/$tfile-%d 1000
12954
12955         cancel_lru_locks mdc
12956         cancel_lru_locks osc
12957
12958 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12959         lctl set_param fail_loc=0x80000803
12960         ls -lR $DIR/$tdir > /dev/null
12961         log "ls done"
12962         lctl set_param fail_loc=0x0
12963         lctl get_param -n llite.*.statahead_stats
12964         rm -r $DIR/$tdir
12965         sync
12966
12967 }
12968 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12969
12970 test_123c() {
12971         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12972
12973         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12974         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12975         touch $DIR/$tdir.1/{1..3}
12976         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12977
12978         remount_client $MOUNT
12979
12980         $MULTIOP $DIR/$tdir.0 Q
12981
12982         # let statahead to complete
12983         ls -l $DIR/$tdir.0 > /dev/null
12984
12985         testid=$(echo $TESTNAME | tr '_' ' ')
12986         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12987                 error "statahead warning" || true
12988 }
12989 run_test 123c "Can not initialize inode warning on DNE statahead"
12990
12991 test_124a() {
12992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12993         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12994                 skip_env "no lru resize on server"
12995
12996         local NR=2000
12997
12998         test_mkdir $DIR/$tdir
12999
13000         log "create $NR files at $DIR/$tdir"
13001         createmany -o $DIR/$tdir/f $NR ||
13002                 error "failed to create $NR files in $DIR/$tdir"
13003
13004         cancel_lru_locks mdc
13005         ls -l $DIR/$tdir > /dev/null
13006
13007         local NSDIR=""
13008         local LRU_SIZE=0
13009         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13010                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13011                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13012                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13013                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13014                         log "NSDIR=$NSDIR"
13015                         log "NS=$(basename $NSDIR)"
13016                         break
13017                 fi
13018         done
13019
13020         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13021                 skip "Not enough cached locks created!"
13022         fi
13023         log "LRU=$LRU_SIZE"
13024
13025         local SLEEP=30
13026
13027         # We know that lru resize allows one client to hold $LIMIT locks
13028         # for 10h. After that locks begin to be killed by client.
13029         local MAX_HRS=10
13030         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13031         log "LIMIT=$LIMIT"
13032         if [ $LIMIT -lt $LRU_SIZE ]; then
13033                 skip "Limit is too small $LIMIT"
13034         fi
13035
13036         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13037         # killing locks. Some time was spent for creating locks. This means
13038         # that up to the moment of sleep finish we must have killed some of
13039         # them (10-100 locks). This depends on how fast ther were created.
13040         # Many of them were touched in almost the same moment and thus will
13041         # be killed in groups.
13042         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13043
13044         # Use $LRU_SIZE_B here to take into account real number of locks
13045         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13046         local LRU_SIZE_B=$LRU_SIZE
13047         log "LVF=$LVF"
13048         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13049         log "OLD_LVF=$OLD_LVF"
13050         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13051
13052         # Let's make sure that we really have some margin. Client checks
13053         # cached locks every 10 sec.
13054         SLEEP=$((SLEEP+20))
13055         log "Sleep ${SLEEP} sec"
13056         local SEC=0
13057         while ((SEC<$SLEEP)); do
13058                 echo -n "..."
13059                 sleep 5
13060                 SEC=$((SEC+5))
13061                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13062                 echo -n "$LRU_SIZE"
13063         done
13064         echo ""
13065         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13066         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13067
13068         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13069                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13070                 unlinkmany $DIR/$tdir/f $NR
13071                 return
13072         }
13073
13074         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13075         log "unlink $NR files at $DIR/$tdir"
13076         unlinkmany $DIR/$tdir/f $NR
13077 }
13078 run_test 124a "lru resize ======================================="
13079
13080 get_max_pool_limit()
13081 {
13082         local limit=$($LCTL get_param \
13083                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13084         local max=0
13085         for l in $limit; do
13086                 if [[ $l -gt $max ]]; then
13087                         max=$l
13088                 fi
13089         done
13090         echo $max
13091 }
13092
13093 test_124b() {
13094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13095         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13096                 skip_env "no lru resize on server"
13097
13098         LIMIT=$(get_max_pool_limit)
13099
13100         NR=$(($(default_lru_size)*20))
13101         if [[ $NR -gt $LIMIT ]]; then
13102                 log "Limit lock number by $LIMIT locks"
13103                 NR=$LIMIT
13104         fi
13105
13106         IFree=$(mdsrate_inodes_available)
13107         if [ $IFree -lt $NR ]; then
13108                 log "Limit lock number by $IFree inodes"
13109                 NR=$IFree
13110         fi
13111
13112         lru_resize_disable mdc
13113         test_mkdir -p $DIR/$tdir/disable_lru_resize
13114
13115         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13116         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13117         cancel_lru_locks mdc
13118         stime=`date +%s`
13119         PID=""
13120         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13121         PID="$PID $!"
13122         sleep 2
13123         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13124         PID="$PID $!"
13125         sleep 2
13126         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13127         PID="$PID $!"
13128         wait $PID
13129         etime=`date +%s`
13130         nolruresize_delta=$((etime-stime))
13131         log "ls -la time: $nolruresize_delta seconds"
13132         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13133         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13134
13135         lru_resize_enable mdc
13136         test_mkdir -p $DIR/$tdir/enable_lru_resize
13137
13138         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13139         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13140         cancel_lru_locks mdc
13141         stime=`date +%s`
13142         PID=""
13143         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13144         PID="$PID $!"
13145         sleep 2
13146         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13147         PID="$PID $!"
13148         sleep 2
13149         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13150         PID="$PID $!"
13151         wait $PID
13152         etime=`date +%s`
13153         lruresize_delta=$((etime-stime))
13154         log "ls -la time: $lruresize_delta seconds"
13155         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13156
13157         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13158                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13159         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13160                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13161         else
13162                 log "lru resize performs the same with no lru resize"
13163         fi
13164         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13165 }
13166 run_test 124b "lru resize (performance test) ======================="
13167
13168 test_124c() {
13169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13170         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13171                 skip_env "no lru resize on server"
13172
13173         # cache ununsed locks on client
13174         local nr=100
13175         cancel_lru_locks mdc
13176         test_mkdir $DIR/$tdir
13177         createmany -o $DIR/$tdir/f $nr ||
13178                 error "failed to create $nr files in $DIR/$tdir"
13179         ls -l $DIR/$tdir > /dev/null
13180
13181         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13182         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13183         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13184         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13185         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13186
13187         # set lru_max_age to 1 sec
13188         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13189         echo "sleep $((recalc_p * 2)) seconds..."
13190         sleep $((recalc_p * 2))
13191
13192         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13193         # restore lru_max_age
13194         $LCTL set_param -n $nsdir.lru_max_age $max_age
13195         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13196         unlinkmany $DIR/$tdir/f $nr
13197 }
13198 run_test 124c "LRUR cancel very aged locks"
13199
13200 test_124d() {
13201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13202         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13203                 skip_env "no lru resize on server"
13204
13205         # cache ununsed locks on client
13206         local nr=100
13207
13208         lru_resize_disable mdc
13209         stack_trap "lru_resize_enable mdc" EXIT
13210
13211         cancel_lru_locks mdc
13212
13213         # asynchronous object destroy at MDT could cause bl ast to client
13214         test_mkdir $DIR/$tdir
13215         createmany -o $DIR/$tdir/f $nr ||
13216                 error "failed to create $nr files in $DIR/$tdir"
13217         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13218
13219         ls -l $DIR/$tdir > /dev/null
13220
13221         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13222         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13223         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13224         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13225
13226         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13227
13228         # set lru_max_age to 1 sec
13229         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13230         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13231
13232         echo "sleep $((recalc_p * 2)) seconds..."
13233         sleep $((recalc_p * 2))
13234
13235         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13236
13237         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13238 }
13239 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13240
13241 test_125() { # 13358
13242         $LCTL get_param -n llite.*.client_type | grep -q local ||
13243                 skip "must run as local client"
13244         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13245                 skip_env "must have acl enabled"
13246         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13247
13248         test_mkdir $DIR/$tdir
13249         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13250         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13251         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13252 }
13253 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13254
13255 test_126() { # bug 12829/13455
13256         $GSS && skip_env "must run as gss disabled"
13257         $LCTL get_param -n llite.*.client_type | grep -q local ||
13258                 skip "must run as local client"
13259         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13260
13261         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13262         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13263         rm -f $DIR/$tfile
13264         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13265 }
13266 run_test 126 "check that the fsgid provided by the client is taken into account"
13267
13268 test_127a() { # bug 15521
13269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13270         local name count samp unit min max sum sumsq
13271
13272         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13273         echo "stats before reset"
13274         $LCTL get_param osc.*.stats
13275         $LCTL set_param osc.*.stats=0
13276         local fsize=$((2048 * 1024))
13277
13278         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13279         cancel_lru_locks osc
13280         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13281
13282         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13283         stack_trap "rm -f $TMP/$tfile.tmp"
13284         while read name count samp unit min max sum sumsq; do
13285                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13286                 [ ! $min ] && error "Missing min value for $name proc entry"
13287                 eval $name=$count || error "Wrong proc format"
13288
13289                 case $name in
13290                 read_bytes|write_bytes)
13291                         [[ "$unit" =~ "bytes" ]] ||
13292                                 error "unit is not 'bytes': $unit"
13293                         (( $min >= 4096 )) || error "min is too small: $min"
13294                         (( $min <= $fsize )) || error "min is too big: $min"
13295                         (( $max >= 4096 )) || error "max is too small: $max"
13296                         (( $max <= $fsize )) || error "max is too big: $max"
13297                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13298                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13299                                 error "sumsquare is too small: $sumsq"
13300                         (( $sumsq <= $fsize * $fsize )) ||
13301                                 error "sumsquare is too big: $sumsq"
13302                         ;;
13303                 ost_read|ost_write)
13304                         [[ "$unit" =~ "usec" ]] ||
13305                                 error "unit is not 'usec': $unit"
13306                         ;;
13307                 *)      ;;
13308                 esac
13309         done < $DIR/$tfile.tmp
13310
13311         #check that we actually got some stats
13312         [ "$read_bytes" ] || error "Missing read_bytes stats"
13313         [ "$write_bytes" ] || error "Missing write_bytes stats"
13314         [ "$read_bytes" != 0 ] || error "no read done"
13315         [ "$write_bytes" != 0 ] || error "no write done"
13316 }
13317 run_test 127a "verify the client stats are sane"
13318
13319 test_127b() { # bug LU-333
13320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13321         local name count samp unit min max sum sumsq
13322
13323         echo "stats before reset"
13324         $LCTL get_param llite.*.stats
13325         $LCTL set_param llite.*.stats=0
13326
13327         # perform 2 reads and writes so MAX is different from SUM.
13328         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13329         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13330         cancel_lru_locks osc
13331         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13332         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13333
13334         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13335         stack_trap "rm -f $TMP/$tfile.tmp"
13336         while read name count samp unit min max sum sumsq; do
13337                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13338                 eval $name=$count || error "Wrong proc format"
13339
13340                 case $name in
13341                 read_bytes|write_bytes)
13342                         [[ "$unit" =~ "bytes" ]] ||
13343                                 error "unit is not 'bytes': $unit"
13344                         (( $count == 2 )) || error "count is not 2: $count"
13345                         (( $min == $PAGE_SIZE )) ||
13346                                 error "min is not $PAGE_SIZE: $min"
13347                         (( $max == $PAGE_SIZE )) ||
13348                                 error "max is not $PAGE_SIZE: $max"
13349                         (( $sum == $PAGE_SIZE * 2 )) ||
13350                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13351                         ;;
13352                 read|write)
13353                         [[ "$unit" =~ "usec" ]] ||
13354                                 error "unit is not 'usec': $unit"
13355                         ;;
13356                 *)      ;;
13357                 esac
13358         done < $TMP/$tfile.tmp
13359
13360         #check that we actually got some stats
13361         [ "$read_bytes" ] || error "Missing read_bytes stats"
13362         [ "$write_bytes" ] || error "Missing write_bytes stats"
13363         [ "$read_bytes" != 0 ] || error "no read done"
13364         [ "$write_bytes" != 0 ] || error "no write done"
13365 }
13366 run_test 127b "verify the llite client stats are sane"
13367
13368 test_127c() { # LU-12394
13369         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13370         local size
13371         local bsize
13372         local reads
13373         local writes
13374         local count
13375
13376         $LCTL set_param llite.*.extents_stats=1
13377         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13378
13379         # Use two stripes so there is enough space in default config
13380         $LFS setstripe -c 2 $DIR/$tfile
13381
13382         # Extent stats start at 0-4K and go in power of two buckets
13383         # LL_HIST_START = 12 --> 2^12 = 4K
13384         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13385         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13386         # small configs
13387         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13388                 do
13389                 # Write and read, 2x each, second time at a non-zero offset
13390                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13391                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13392                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13393                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13394                 rm -f $DIR/$tfile
13395         done
13396
13397         $LCTL get_param llite.*.extents_stats
13398
13399         count=2
13400         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13401                 do
13402                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13403                                 grep -m 1 $bsize)
13404                 reads=$(echo $bucket | awk '{print $5}')
13405                 writes=$(echo $bucket | awk '{print $9}')
13406                 [ "$reads" -eq $count ] ||
13407                         error "$reads reads in < $bsize bucket, expect $count"
13408                 [ "$writes" -eq $count ] ||
13409                         error "$writes writes in < $bsize bucket, expect $count"
13410         done
13411
13412         # Test mmap write and read
13413         $LCTL set_param llite.*.extents_stats=c
13414         size=512
13415         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13416         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13417         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13418
13419         $LCTL get_param llite.*.extents_stats
13420
13421         count=$(((size*1024) / PAGE_SIZE))
13422
13423         bsize=$((2 * PAGE_SIZE / 1024))K
13424
13425         bucket=$($LCTL get_param -n llite.*.extents_stats |
13426                         grep -m 1 $bsize)
13427         reads=$(echo $bucket | awk '{print $5}')
13428         writes=$(echo $bucket | awk '{print $9}')
13429         # mmap writes fault in the page first, creating an additonal read
13430         [ "$reads" -eq $((2 * count)) ] ||
13431                 error "$reads reads in < $bsize bucket, expect $count"
13432         [ "$writes" -eq $count ] ||
13433                 error "$writes writes in < $bsize bucket, expect $count"
13434 }
13435 run_test 127c "test llite extent stats with regular & mmap i/o"
13436
13437 test_128() { # bug 15212
13438         touch $DIR/$tfile
13439         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13440                 find $DIR/$tfile
13441                 find $DIR/$tfile
13442         EOF
13443
13444         result=$(grep error $TMP/$tfile.log)
13445         rm -f $DIR/$tfile $TMP/$tfile.log
13446         [ -z "$result" ] ||
13447                 error "consecutive find's under interactive lfs failed"
13448 }
13449 run_test 128 "interactive lfs for 2 consecutive find's"
13450
13451 set_dir_limits () {
13452         local mntdev
13453         local canondev
13454         local node
13455
13456         local ldproc=/proc/fs/ldiskfs
13457         local facets=$(get_facets MDS)
13458
13459         for facet in ${facets//,/ }; do
13460                 canondev=$(ldiskfs_canon \
13461                            *.$(convert_facet2label $facet).mntdev $facet)
13462                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13463                         ldproc=/sys/fs/ldiskfs
13464                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13465                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13466         done
13467 }
13468
13469 check_mds_dmesg() {
13470         local facets=$(get_facets MDS)
13471         for facet in ${facets//,/ }; do
13472                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13473         done
13474         return 1
13475 }
13476
13477 test_129() {
13478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13479         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13480                 skip "Need MDS version with at least 2.5.56"
13481         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13482                 skip_env "ldiskfs only test"
13483         fi
13484         remote_mds_nodsh && skip "remote MDS with nodsh"
13485
13486         local ENOSPC=28
13487         local has_warning=false
13488
13489         rm -rf $DIR/$tdir
13490         mkdir -p $DIR/$tdir
13491
13492         # block size of mds1
13493         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13494         set_dir_limits $maxsize $((maxsize * 6 / 8))
13495         stack_trap "set_dir_limits 0 0"
13496         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13497         local dirsize=$(stat -c%s "$DIR/$tdir")
13498         local nfiles=0
13499         while (( $dirsize <= $maxsize )); do
13500                 $MCREATE $DIR/$tdir/file_base_$nfiles
13501                 rc=$?
13502                 # check two errors:
13503                 # ENOSPC for ext4 max_dir_size, which has been used since
13504                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13505                 if (( rc == ENOSPC )); then
13506                         set_dir_limits 0 0
13507                         echo "rc=$rc returned as expected after $nfiles files"
13508
13509                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13510                                 error "create failed w/o dir size limit"
13511
13512                         # messages may be rate limited if test is run repeatedly
13513                         check_mds_dmesg '"is approaching max"' ||
13514                                 echo "warning message should be output"
13515                         check_mds_dmesg '"has reached max"' ||
13516                                 echo "reached message should be output"
13517
13518                         dirsize=$(stat -c%s "$DIR/$tdir")
13519
13520                         [[ $dirsize -ge $maxsize ]] && return 0
13521                         error "dirsize $dirsize < $maxsize after $nfiles files"
13522                 elif (( rc != 0 )); then
13523                         break
13524                 fi
13525                 nfiles=$((nfiles + 1))
13526                 dirsize=$(stat -c%s "$DIR/$tdir")
13527         done
13528
13529         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13530 }
13531 run_test 129 "test directory size limit ========================"
13532
13533 OLDIFS="$IFS"
13534 cleanup_130() {
13535         trap 0
13536         IFS="$OLDIFS"
13537 }
13538
13539 test_130a() {
13540         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13541         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13542
13543         trap cleanup_130 EXIT RETURN
13544
13545         local fm_file=$DIR/$tfile
13546         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13547         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13548                 error "dd failed for $fm_file"
13549
13550         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13551         filefrag -ves $fm_file
13552         RC=$?
13553         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13554                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13555         [ $RC != 0 ] && error "filefrag $fm_file failed"
13556
13557         filefrag_op=$(filefrag -ve -k $fm_file |
13558                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13559         lun=$($LFS getstripe -i $fm_file)
13560
13561         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13562         IFS=$'\n'
13563         tot_len=0
13564         for line in $filefrag_op
13565         do
13566                 frag_lun=`echo $line | cut -d: -f5`
13567                 ext_len=`echo $line | cut -d: -f4`
13568                 if (( $frag_lun != $lun )); then
13569                         cleanup_130
13570                         error "FIEMAP on 1-stripe file($fm_file) failed"
13571                         return
13572                 fi
13573                 (( tot_len += ext_len ))
13574         done
13575
13576         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13577                 cleanup_130
13578                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13579                 return
13580         fi
13581
13582         cleanup_130
13583
13584         echo "FIEMAP on single striped file succeeded"
13585 }
13586 run_test 130a "FIEMAP (1-stripe file)"
13587
13588 test_130b() {
13589         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13590
13591         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13592         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13593
13594         trap cleanup_130 EXIT RETURN
13595
13596         local fm_file=$DIR/$tfile
13597         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13598                         error "setstripe on $fm_file"
13599         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13600                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13601
13602         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13603                 error "dd failed on $fm_file"
13604
13605         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13606         filefrag_op=$(filefrag -ve -k $fm_file |
13607                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13608
13609         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13610                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13611
13612         IFS=$'\n'
13613         tot_len=0
13614         num_luns=1
13615         for line in $filefrag_op
13616         do
13617                 frag_lun=$(echo $line | cut -d: -f5 |
13618                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13619                 ext_len=$(echo $line | cut -d: -f4)
13620                 if (( $frag_lun != $last_lun )); then
13621                         if (( tot_len != 1024 )); then
13622                                 cleanup_130
13623                                 error "FIEMAP on $fm_file failed; returned " \
13624                                 "len $tot_len for OST $last_lun instead of 1024"
13625                                 return
13626                         else
13627                                 (( num_luns += 1 ))
13628                                 tot_len=0
13629                         fi
13630                 fi
13631                 (( tot_len += ext_len ))
13632                 last_lun=$frag_lun
13633         done
13634         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13635                 cleanup_130
13636                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13637                         "luns or wrong len for OST $last_lun"
13638                 return
13639         fi
13640
13641         cleanup_130
13642
13643         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13644 }
13645 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13646
13647 test_130c() {
13648         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13649
13650         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13651         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13652
13653         trap cleanup_130 EXIT RETURN
13654
13655         local fm_file=$DIR/$tfile
13656         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13657         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13658                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13659
13660         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13661                         error "dd failed on $fm_file"
13662
13663         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13664         filefrag_op=$(filefrag -ve -k $fm_file |
13665                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13666
13667         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13668                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13669
13670         IFS=$'\n'
13671         tot_len=0
13672         num_luns=1
13673         for line in $filefrag_op
13674         do
13675                 frag_lun=$(echo $line | cut -d: -f5 |
13676                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13677                 ext_len=$(echo $line | cut -d: -f4)
13678                 if (( $frag_lun != $last_lun )); then
13679                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13680                         if (( logical != 512 )); then
13681                                 cleanup_130
13682                                 error "FIEMAP on $fm_file failed; returned " \
13683                                 "logical start for lun $logical instead of 512"
13684                                 return
13685                         fi
13686                         if (( tot_len != 512 )); then
13687                                 cleanup_130
13688                                 error "FIEMAP on $fm_file failed; returned " \
13689                                 "len $tot_len for OST $last_lun instead of 1024"
13690                                 return
13691                         else
13692                                 (( num_luns += 1 ))
13693                                 tot_len=0
13694                         fi
13695                 fi
13696                 (( tot_len += ext_len ))
13697                 last_lun=$frag_lun
13698         done
13699         if (( num_luns != 2 || tot_len != 512 )); then
13700                 cleanup_130
13701                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13702                         "luns or wrong len for OST $last_lun"
13703                 return
13704         fi
13705
13706         cleanup_130
13707
13708         echo "FIEMAP on 2-stripe file with hole succeeded"
13709 }
13710 run_test 130c "FIEMAP (2-stripe file with hole)"
13711
13712 test_130d() {
13713         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13714
13715         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13716         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13717
13718         trap cleanup_130 EXIT RETURN
13719
13720         local fm_file=$DIR/$tfile
13721         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13722                         error "setstripe on $fm_file"
13723         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13724                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13725
13726         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13727         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13728                 error "dd failed on $fm_file"
13729
13730         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13731         filefrag_op=$(filefrag -ve -k $fm_file |
13732                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13733
13734         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13735                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13736
13737         IFS=$'\n'
13738         tot_len=0
13739         num_luns=1
13740         for line in $filefrag_op
13741         do
13742                 frag_lun=$(echo $line | cut -d: -f5 |
13743                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13744                 ext_len=$(echo $line | cut -d: -f4)
13745                 if (( $frag_lun != $last_lun )); then
13746                         if (( tot_len != 1024 )); then
13747                                 cleanup_130
13748                                 error "FIEMAP on $fm_file failed; returned " \
13749                                 "len $tot_len for OST $last_lun instead of 1024"
13750                                 return
13751                         else
13752                                 (( num_luns += 1 ))
13753                                 tot_len=0
13754                         fi
13755                 fi
13756                 (( tot_len += ext_len ))
13757                 last_lun=$frag_lun
13758         done
13759         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13760                 cleanup_130
13761                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13762                         "luns or wrong len for OST $last_lun"
13763                 return
13764         fi
13765
13766         cleanup_130
13767
13768         echo "FIEMAP on N-stripe file succeeded"
13769 }
13770 run_test 130d "FIEMAP (N-stripe file)"
13771
13772 test_130e() {
13773         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13774
13775         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13776         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13777
13778         trap cleanup_130 EXIT RETURN
13779
13780         local fm_file=$DIR/$tfile
13781         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13782
13783         NUM_BLKS=512
13784         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13785         for ((i = 0; i < $NUM_BLKS; i++)); do
13786                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13787                         conv=notrunc > /dev/null 2>&1
13788         done
13789
13790         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13791         filefrag_op=$(filefrag -ve -k $fm_file |
13792                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13793
13794         last_lun=$(echo $filefrag_op | cut -d: -f5)
13795
13796         IFS=$'\n'
13797         tot_len=0
13798         num_luns=1
13799         for line in $filefrag_op; do
13800                 frag_lun=$(echo $line | cut -d: -f5)
13801                 ext_len=$(echo $line | cut -d: -f4)
13802                 if [[ "$frag_lun" != "$last_lun" ]]; then
13803                         if (( tot_len != $EXPECTED_LEN )); then
13804                                 cleanup_130
13805                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13806                         else
13807                                 (( num_luns += 1 ))
13808                                 tot_len=0
13809                         fi
13810                 fi
13811                 (( tot_len += ext_len ))
13812                 last_lun=$frag_lun
13813         done
13814         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13815                 cleanup_130
13816                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13817         fi
13818
13819         echo "FIEMAP with continuation calls succeeded"
13820 }
13821 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13822
13823 test_130f() {
13824         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13825         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13826
13827         local fm_file=$DIR/$tfile
13828         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13829                 error "multiop create with lov_delay_create on $fm_file"
13830
13831         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13832         filefrag_extents=$(filefrag -vek $fm_file |
13833                            awk '/extents? found/ { print $2 }')
13834         if [[ "$filefrag_extents" != "0" ]]; then
13835                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13836         fi
13837
13838         rm -f $fm_file
13839 }
13840 run_test 130f "FIEMAP (unstriped file)"
13841
13842 test_130g() {
13843         local file=$DIR/$tfile
13844         local nr=$((OSTCOUNT * 100))
13845
13846         $LFS setstripe -C $nr $file ||
13847                 error "failed to setstripe -C $nr $file"
13848
13849         dd if=/dev/zero of=$file count=$nr bs=1M
13850         sync
13851         nr=$($LFS getstripe -c $file)
13852
13853         local extents=$(filefrag -v $file |
13854                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13855
13856         echo "filefrag list $extents extents in file with stripecount $nr"
13857         if (( extents < nr )); then
13858                 $LFS getstripe $file
13859                 filefrag -v $file
13860                 error "filefrag printed $extents < $nr extents"
13861         fi
13862
13863         rm -f $file
13864 }
13865 run_test 130g "FIEMAP (overstripe file)"
13866
13867 # Test for writev/readv
13868 test_131a() {
13869         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13870                 error "writev test failed"
13871         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13872                 error "readv failed"
13873         rm -f $DIR/$tfile
13874 }
13875 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13876
13877 test_131b() {
13878         local fsize=$((524288 + 1048576 + 1572864))
13879         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13880                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13881                         error "append writev test failed"
13882
13883         ((fsize += 1572864 + 1048576))
13884         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13885                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13886                         error "append writev test failed"
13887         rm -f $DIR/$tfile
13888 }
13889 run_test 131b "test append writev"
13890
13891 test_131c() {
13892         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13893         error "NOT PASS"
13894 }
13895 run_test 131c "test read/write on file w/o objects"
13896
13897 test_131d() {
13898         rwv -f $DIR/$tfile -w -n 1 1572864
13899         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13900         if [ "$NOB" != 1572864 ]; then
13901                 error "Short read filed: read $NOB bytes instead of 1572864"
13902         fi
13903         rm -f $DIR/$tfile
13904 }
13905 run_test 131d "test short read"
13906
13907 test_131e() {
13908         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13909         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13910         error "read hitting hole failed"
13911         rm -f $DIR/$tfile
13912 }
13913 run_test 131e "test read hitting hole"
13914
13915 check_stats() {
13916         local facet=$1
13917         local op=$2
13918         local want=${3:-0}
13919         local res
13920
13921         case $facet in
13922         mds*) res=$(do_facet $facet \
13923                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13924                  ;;
13925         ost*) res=$(do_facet $facet \
13926                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13927                  ;;
13928         *) error "Wrong facet '$facet'" ;;
13929         esac
13930         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13931         # if the argument $3 is zero, it means any stat increment is ok.
13932         if [[ $want -gt 0 ]]; then
13933                 local count=$(echo $res | awk '{ print $2 }')
13934                 [[ $count -ne $want ]] &&
13935                         error "The $op counter on $facet is $count, not $want"
13936         fi
13937 }
13938
13939 test_133a() {
13940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13941         remote_ost_nodsh && skip "remote OST with nodsh"
13942         remote_mds_nodsh && skip "remote MDS with nodsh"
13943         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13944                 skip_env "MDS doesn't support rename stats"
13945
13946         local testdir=$DIR/${tdir}/stats_testdir
13947
13948         mkdir -p $DIR/${tdir}
13949
13950         # clear stats.
13951         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13952         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13953
13954         # verify mdt stats first.
13955         mkdir ${testdir} || error "mkdir failed"
13956         check_stats $SINGLEMDS "mkdir" 1
13957         touch ${testdir}/${tfile} || error "touch failed"
13958         check_stats $SINGLEMDS "open" 1
13959         check_stats $SINGLEMDS "close" 1
13960         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13961                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13962                 check_stats $SINGLEMDS "mknod" 2
13963         }
13964         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13965         check_stats $SINGLEMDS "unlink" 1
13966         rm -f ${testdir}/${tfile} || error "file remove failed"
13967         check_stats $SINGLEMDS "unlink" 2
13968
13969         # remove working dir and check mdt stats again.
13970         rmdir ${testdir} || error "rmdir failed"
13971         check_stats $SINGLEMDS "rmdir" 1
13972
13973         local testdir1=$DIR/${tdir}/stats_testdir1
13974         mkdir -p ${testdir}
13975         mkdir -p ${testdir1}
13976         touch ${testdir1}/test1
13977         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13978         check_stats $SINGLEMDS "crossdir_rename" 1
13979
13980         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13981         check_stats $SINGLEMDS "samedir_rename" 1
13982
13983         rm -rf $DIR/${tdir}
13984 }
13985 run_test 133a "Verifying MDT stats ========================================"
13986
13987 test_133b() {
13988         local res
13989
13990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13991         remote_ost_nodsh && skip "remote OST with nodsh"
13992         remote_mds_nodsh && skip "remote MDS with nodsh"
13993
13994         local testdir=$DIR/${tdir}/stats_testdir
13995
13996         mkdir -p ${testdir} || error "mkdir failed"
13997         touch ${testdir}/${tfile} || error "touch failed"
13998         cancel_lru_locks mdc
13999
14000         # clear stats.
14001         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14002         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14003
14004         # extra mdt stats verification.
14005         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14006         check_stats $SINGLEMDS "setattr" 1
14007         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14008         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14009         then            # LU-1740
14010                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14011                 check_stats $SINGLEMDS "getattr" 1
14012         fi
14013         rm -rf $DIR/${tdir}
14014
14015         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14016         # so the check below is not reliable
14017         [ $MDSCOUNT -eq 1 ] || return 0
14018
14019         # Sleep to avoid a cached response.
14020         #define OBD_STATFS_CACHE_SECONDS 1
14021         sleep 2
14022         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14023         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14024         $LFS df || error "lfs failed"
14025         check_stats $SINGLEMDS "statfs" 1
14026
14027         # check aggregated statfs (LU-10018)
14028         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14029                 return 0
14030         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14031                 return 0
14032         sleep 2
14033         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14034         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14035         df $DIR
14036         check_stats $SINGLEMDS "statfs" 1
14037
14038         # We want to check that the client didn't send OST_STATFS to
14039         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14040         # extra care is needed here.
14041         if remote_mds; then
14042                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14043                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14044
14045                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14046                 [ "$res" ] && error "OST got STATFS"
14047         fi
14048
14049         return 0
14050 }
14051 run_test 133b "Verifying extra MDT stats =================================="
14052
14053 test_133c() {
14054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14055         remote_ost_nodsh && skip "remote OST with nodsh"
14056         remote_mds_nodsh && skip "remote MDS with nodsh"
14057
14058         local testdir=$DIR/$tdir/stats_testdir
14059
14060         test_mkdir -p $testdir
14061
14062         # verify obdfilter stats.
14063         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14064         sync
14065         cancel_lru_locks osc
14066         wait_delete_completed
14067
14068         # clear stats.
14069         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14070         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14071
14072         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14073                 error "dd failed"
14074         sync
14075         cancel_lru_locks osc
14076         check_stats ost1 "write" 1
14077
14078         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14079         check_stats ost1 "read" 1
14080
14081         > $testdir/$tfile || error "truncate failed"
14082         check_stats ost1 "punch" 1
14083
14084         rm -f $testdir/$tfile || error "file remove failed"
14085         wait_delete_completed
14086         check_stats ost1 "destroy" 1
14087
14088         rm -rf $DIR/$tdir
14089 }
14090 run_test 133c "Verifying OST stats ========================================"
14091
14092 order_2() {
14093         local value=$1
14094         local orig=$value
14095         local order=1
14096
14097         while [ $value -ge 2 ]; do
14098                 order=$((order*2))
14099                 value=$((value/2))
14100         done
14101
14102         if [ $orig -gt $order ]; then
14103                 order=$((order*2))
14104         fi
14105         echo $order
14106 }
14107
14108 size_in_KMGT() {
14109     local value=$1
14110     local size=('K' 'M' 'G' 'T');
14111     local i=0
14112     local size_string=$value
14113
14114     while [ $value -ge 1024 ]; do
14115         if [ $i -gt 3 ]; then
14116             #T is the biggest unit we get here, if that is bigger,
14117             #just return XXXT
14118             size_string=${value}T
14119             break
14120         fi
14121         value=$((value >> 10))
14122         if [ $value -lt 1024 ]; then
14123             size_string=${value}${size[$i]}
14124             break
14125         fi
14126         i=$((i + 1))
14127     done
14128
14129     echo $size_string
14130 }
14131
14132 get_rename_size() {
14133         local size=$1
14134         local context=${2:-.}
14135         local sample=$(do_facet $SINGLEMDS $LCTL \
14136                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14137                 grep -A1 $context |
14138                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14139         echo $sample
14140 }
14141
14142 test_133d() {
14143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14144         remote_ost_nodsh && skip "remote OST with nodsh"
14145         remote_mds_nodsh && skip "remote MDS with nodsh"
14146         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14147                 skip_env "MDS doesn't support rename stats"
14148
14149         local testdir1=$DIR/${tdir}/stats_testdir1
14150         local testdir2=$DIR/${tdir}/stats_testdir2
14151         mkdir -p $DIR/${tdir}
14152
14153         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14154
14155         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14156         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14157
14158         createmany -o $testdir1/test 512 || error "createmany failed"
14159
14160         # check samedir rename size
14161         mv ${testdir1}/test0 ${testdir1}/test_0
14162
14163         local testdir1_size=$(ls -l $DIR/${tdir} |
14164                 awk '/stats_testdir1/ {print $5}')
14165         local testdir2_size=$(ls -l $DIR/${tdir} |
14166                 awk '/stats_testdir2/ {print $5}')
14167
14168         testdir1_size=$(order_2 $testdir1_size)
14169         testdir2_size=$(order_2 $testdir2_size)
14170
14171         testdir1_size=$(size_in_KMGT $testdir1_size)
14172         testdir2_size=$(size_in_KMGT $testdir2_size)
14173
14174         echo "source rename dir size: ${testdir1_size}"
14175         echo "target rename dir size: ${testdir2_size}"
14176
14177         local cmd="do_facet $SINGLEMDS $LCTL "
14178         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14179
14180         eval $cmd || error "$cmd failed"
14181         local samedir=$($cmd | grep 'same_dir')
14182         local same_sample=$(get_rename_size $testdir1_size)
14183         [ -z "$samedir" ] && error "samedir_rename_size count error"
14184         [[ $same_sample -eq 1 ]] ||
14185                 error "samedir_rename_size error $same_sample"
14186         echo "Check same dir rename stats success"
14187
14188         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14189
14190         # check crossdir rename size
14191         mv ${testdir1}/test_0 ${testdir2}/test_0
14192
14193         testdir1_size=$(ls -l $DIR/${tdir} |
14194                 awk '/stats_testdir1/ {print $5}')
14195         testdir2_size=$(ls -l $DIR/${tdir} |
14196                 awk '/stats_testdir2/ {print $5}')
14197
14198         testdir1_size=$(order_2 $testdir1_size)
14199         testdir2_size=$(order_2 $testdir2_size)
14200
14201         testdir1_size=$(size_in_KMGT $testdir1_size)
14202         testdir2_size=$(size_in_KMGT $testdir2_size)
14203
14204         echo "source rename dir size: ${testdir1_size}"
14205         echo "target rename dir size: ${testdir2_size}"
14206
14207         eval $cmd || error "$cmd failed"
14208         local crossdir=$($cmd | grep 'crossdir')
14209         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14210         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14211         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14212         [[ $src_sample -eq 1 ]] ||
14213                 error "crossdir_rename_size error $src_sample"
14214         [[ $tgt_sample -eq 1 ]] ||
14215                 error "crossdir_rename_size error $tgt_sample"
14216         echo "Check cross dir rename stats success"
14217         rm -rf $DIR/${tdir}
14218 }
14219 run_test 133d "Verifying rename_stats ========================================"
14220
14221 test_133e() {
14222         remote_mds_nodsh && skip "remote MDS with nodsh"
14223         remote_ost_nodsh && skip "remote OST with nodsh"
14224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14225
14226         local testdir=$DIR/${tdir}/stats_testdir
14227         local ctr f0 f1 bs=32768 count=42 sum
14228
14229         mkdir -p ${testdir} || error "mkdir failed"
14230
14231         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14232
14233         for ctr in {write,read}_bytes; do
14234                 sync
14235                 cancel_lru_locks osc
14236
14237                 do_facet ost1 $LCTL set_param -n \
14238                         "obdfilter.*.exports.clear=clear"
14239
14240                 if [ $ctr = write_bytes ]; then
14241                         f0=/dev/zero
14242                         f1=${testdir}/${tfile}
14243                 else
14244                         f0=${testdir}/${tfile}
14245                         f1=/dev/null
14246                 fi
14247
14248                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14249                         error "dd failed"
14250                 sync
14251                 cancel_lru_locks osc
14252
14253                 sum=$(do_facet ost1 $LCTL get_param \
14254                         "obdfilter.*.exports.*.stats" |
14255                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14256                                 $1 == ctr { sum += $7 }
14257                                 END { printf("%0.0f", sum) }')
14258
14259                 if ((sum != bs * count)); then
14260                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14261                 fi
14262         done
14263
14264         rm -rf $DIR/${tdir}
14265 }
14266 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14267
14268 test_133f() {
14269         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14270                 skip "too old lustre for get_param -R ($facet_ver)"
14271
14272         # verifying readability.
14273         $LCTL get_param -R '*' &> /dev/null
14274
14275         # Verifing writability with badarea_io.
14276         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14277         local skipped_params='force_lbug|changelog_mask|daemon_file'
14278         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14279                 egrep -v "$skipped_params" |
14280                 xargs -n 1 find $proc_dirs -name |
14281                 xargs -n 1 badarea_io ||
14282                 error "client badarea_io failed"
14283
14284         # remount the FS in case writes/reads /proc break the FS
14285         cleanup || error "failed to unmount"
14286         setup || error "failed to setup"
14287 }
14288 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14289
14290 test_133g() {
14291         remote_mds_nodsh && skip "remote MDS with nodsh"
14292         remote_ost_nodsh && skip "remote OST with nodsh"
14293
14294         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14295         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14296         local facet
14297         for facet in mds1 ost1; do
14298                 local facet_ver=$(lustre_version_code $facet)
14299                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14300                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14301                 else
14302                         log "$facet: too old lustre for get_param -R"
14303                 fi
14304                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14305                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14306                                 tr -d = | egrep -v $skipped_params |
14307                                 xargs -n 1 find $proc_dirs -name |
14308                                 xargs -n 1 badarea_io" ||
14309                                         error "$facet badarea_io failed"
14310                 else
14311                         skip_noexit "$facet: too old lustre for get_param -R"
14312                 fi
14313         done
14314
14315         # remount the FS in case writes/reads /proc break the FS
14316         cleanup || error "failed to unmount"
14317         setup || error "failed to setup"
14318 }
14319 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14320
14321 test_133h() {
14322         remote_mds_nodsh && skip "remote MDS with nodsh"
14323         remote_ost_nodsh && skip "remote OST with nodsh"
14324         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14325                 skip "Need MDS version at least 2.9.54"
14326
14327         local facet
14328         for facet in client mds1 ost1; do
14329                 # Get the list of files that are missing the terminating newline
14330                 local plist=$(do_facet $facet
14331                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14332                 local ent
14333                 for ent in $plist; do
14334                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14335                                 awk -v FS='\v' -v RS='\v\v' \
14336                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14337                                         print FILENAME}'" 2>/dev/null)
14338                         [ -z $missing ] || {
14339                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14340                                 error "file does not end with newline: $facet-$ent"
14341                         }
14342                 done
14343         done
14344 }
14345 run_test 133h "Proc files should end with newlines"
14346
14347 test_134a() {
14348         remote_mds_nodsh && skip "remote MDS with nodsh"
14349         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14350                 skip "Need MDS version at least 2.7.54"
14351
14352         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14353         cancel_lru_locks mdc
14354
14355         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14356         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14357         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14358
14359         local nr=1000
14360         createmany -o $DIR/$tdir/f $nr ||
14361                 error "failed to create $nr files in $DIR/$tdir"
14362         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14363
14364         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14365         do_facet mds1 $LCTL set_param fail_loc=0x327
14366         do_facet mds1 $LCTL set_param fail_val=500
14367         touch $DIR/$tdir/m
14368
14369         echo "sleep 10 seconds ..."
14370         sleep 10
14371         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14372
14373         do_facet mds1 $LCTL set_param fail_loc=0
14374         do_facet mds1 $LCTL set_param fail_val=0
14375         [ $lck_cnt -lt $unused ] ||
14376                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14377
14378         rm $DIR/$tdir/m
14379         unlinkmany $DIR/$tdir/f $nr
14380 }
14381 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14382
14383 test_134b() {
14384         remote_mds_nodsh && skip "remote MDS with nodsh"
14385         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14386                 skip "Need MDS version at least 2.7.54"
14387
14388         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14389         cancel_lru_locks mdc
14390
14391         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14392                         ldlm.lock_reclaim_threshold_mb)
14393         # disable reclaim temporarily
14394         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14395
14396         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14397         do_facet mds1 $LCTL set_param fail_loc=0x328
14398         do_facet mds1 $LCTL set_param fail_val=500
14399
14400         $LCTL set_param debug=+trace
14401
14402         local nr=600
14403         createmany -o $DIR/$tdir/f $nr &
14404         local create_pid=$!
14405
14406         echo "Sleep $TIMEOUT seconds ..."
14407         sleep $TIMEOUT
14408         if ! ps -p $create_pid  > /dev/null 2>&1; then
14409                 do_facet mds1 $LCTL set_param fail_loc=0
14410                 do_facet mds1 $LCTL set_param fail_val=0
14411                 do_facet mds1 $LCTL set_param \
14412                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14413                 error "createmany finished incorrectly!"
14414         fi
14415         do_facet mds1 $LCTL set_param fail_loc=0
14416         do_facet mds1 $LCTL set_param fail_val=0
14417         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14418         wait $create_pid || return 1
14419
14420         unlinkmany $DIR/$tdir/f $nr
14421 }
14422 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14423
14424 test_135() {
14425         remote_mds_nodsh && skip "remote MDS with nodsh"
14426         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14427                 skip "Need MDS version at least 2.13.50"
14428         local fname
14429
14430         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14431
14432 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14433         #set only one record at plain llog
14434         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14435
14436         #fill already existed plain llog each 64767
14437         #wrapping whole catalog
14438         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14439
14440         createmany -o $DIR/$tdir/$tfile_ 64700
14441         for (( i = 0; i < 64700; i = i + 2 ))
14442         do
14443                 rm $DIR/$tdir/$tfile_$i &
14444                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14445                 local pid=$!
14446                 wait $pid
14447         done
14448
14449         #waiting osp synchronization
14450         wait_delete_completed
14451 }
14452 run_test 135 "Race catalog processing"
14453
14454 test_136() {
14455         remote_mds_nodsh && skip "remote MDS with nodsh"
14456         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14457                 skip "Need MDS version at least 2.13.50"
14458         local fname
14459
14460         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14461         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14462         #set only one record at plain llog
14463 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14464         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14465
14466         #fill already existed 2 plain llogs each 64767
14467         #wrapping whole catalog
14468         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14469         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14470         wait_delete_completed
14471
14472         createmany -o $DIR/$tdir/$tfile_ 10
14473         sleep 25
14474
14475         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14476         for (( i = 0; i < 10; i = i + 3 ))
14477         do
14478                 rm $DIR/$tdir/$tfile_$i &
14479                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14480                 local pid=$!
14481                 wait $pid
14482                 sleep 7
14483                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14484         done
14485
14486         #waiting osp synchronization
14487         wait_delete_completed
14488 }
14489 run_test 136 "Race catalog processing 2"
14490
14491 test_140() { #bug-17379
14492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14493
14494         test_mkdir $DIR/$tdir
14495         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14496         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14497
14498         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14499         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14500         local i=0
14501         while i=$((i + 1)); do
14502                 test_mkdir $i
14503                 cd $i || error "Changing to $i"
14504                 ln -s ../stat stat || error "Creating stat symlink"
14505                 # Read the symlink until ELOOP present,
14506                 # not LBUGing the system is considered success,
14507                 # we didn't overrun the stack.
14508                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14509                 if [ $ret -ne 0 ]; then
14510                         if [ $ret -eq 40 ]; then
14511                                 break  # -ELOOP
14512                         else
14513                                 error "Open stat symlink"
14514                                         return
14515                         fi
14516                 fi
14517         done
14518         i=$((i - 1))
14519         echo "The symlink depth = $i"
14520         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14521                 error "Invalid symlink depth"
14522
14523         # Test recursive symlink
14524         ln -s symlink_self symlink_self
14525         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14526         echo "open symlink_self returns $ret"
14527         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14528 }
14529 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14530
14531 test_150a() {
14532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14533
14534         local TF="$TMP/$tfile"
14535
14536         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14537         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14538         cp $TF $DIR/$tfile
14539         cancel_lru_locks $OSC
14540         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14541         remount_client $MOUNT
14542         df -P $MOUNT
14543         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14544
14545         $TRUNCATE $TF 6000
14546         $TRUNCATE $DIR/$tfile 6000
14547         cancel_lru_locks $OSC
14548         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14549
14550         echo "12345" >>$TF
14551         echo "12345" >>$DIR/$tfile
14552         cancel_lru_locks $OSC
14553         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14554
14555         echo "12345" >>$TF
14556         echo "12345" >>$DIR/$tfile
14557         cancel_lru_locks $OSC
14558         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14559 }
14560 run_test 150a "truncate/append tests"
14561
14562 test_150b() {
14563         check_set_fallocate_or_skip
14564
14565         touch $DIR/$tfile
14566         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14567         check_fallocate $DIR/$tfile || error "fallocate failed"
14568 }
14569 run_test 150b "Verify fallocate (prealloc) functionality"
14570
14571 test_150bb() {
14572         check_set_fallocate_or_skip
14573
14574         touch $DIR/$tfile
14575         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14576         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14577         > $DIR/$tfile
14578         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14579         # precomputed md5sum for 20MB of zeroes
14580         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14581         local sum=($(md5sum $DIR/$tfile))
14582
14583         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14584
14585         check_set_fallocate 1
14586
14587         > $DIR/$tfile
14588         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14589         sum=($(md5sum $DIR/$tfile))
14590
14591         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14592 }
14593 run_test 150bb "Verify fallocate modes both zero space"
14594
14595 test_150c() {
14596         check_set_fallocate_or_skip
14597         local striping="-c2"
14598
14599         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14600         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14601         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14602         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14603         local want=$((OSTCOUNT * 1048576))
14604
14605         # Must allocate all requested space, not more than 5% extra
14606         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14607                 error "bytes $bytes is not $want"
14608
14609         rm -f $DIR/$tfile
14610
14611         echo "verify fallocate on PFL file"
14612
14613         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14614
14615         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14616                 error "Create $DIR/$tfile failed"
14617         fallocate -l $((1048576 * 512)) $DIR/$tfile ||
14618                         error "fallocate failed"
14619         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14620         want=$((512 * 1048576))
14621
14622         # Must allocate all requested space, not more than 5% extra
14623         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14624                 error "bytes $bytes is not $want"
14625 }
14626 run_test 150c "Verify fallocate Size and Blocks"
14627
14628 test_150d() {
14629         check_set_fallocate_or_skip
14630         local striping="-c2"
14631
14632         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14633
14634         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14635         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14636                 error "setstripe failed"
14637         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14638         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14639         local want=$((OSTCOUNT * 1048576))
14640
14641         # Must allocate all requested space, not more than 5% extra
14642         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14643                 error "bytes $bytes is not $want"
14644 }
14645 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14646
14647 test_150e() {
14648         check_set_fallocate_or_skip
14649
14650         echo "df before:"
14651         $LFS df
14652         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14653         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14654                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14655
14656         # Find OST with Minimum Size
14657         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14658                        sort -un | head -1)
14659
14660         # Get 100MB per OST of the available space to reduce run time
14661         # else 60% of the available space if we are running SLOW tests
14662         if [ $SLOW == "no" ]; then
14663                 local space=$((1024 * 100 * OSTCOUNT))
14664         else
14665                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14666         fi
14667
14668         fallocate -l${space}k $DIR/$tfile ||
14669                 error "fallocate ${space}k $DIR/$tfile failed"
14670         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14671
14672         # get size immediately after fallocate. This should be correctly
14673         # updated
14674         local size=$(stat -c '%s' $DIR/$tfile)
14675         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14676
14677         # Sleep for a while for statfs to get updated. And not pull from cache.
14678         sleep 2
14679
14680         echo "df after fallocate:"
14681         $LFS df
14682
14683         (( size / 1024 == space )) || error "size $size != requested $space"
14684         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14685                 error "used $used < space $space"
14686
14687         rm $DIR/$tfile || error "rm failed"
14688         sync
14689         wait_delete_completed
14690
14691         echo "df after unlink:"
14692         $LFS df
14693 }
14694 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14695
14696 test_150f() {
14697         local size
14698         local blocks
14699         local want_size_before=20480 # in bytes
14700         local want_blocks_before=40 # 512 sized blocks
14701         local want_blocks_after=24  # 512 sized blocks
14702         local length=$(((want_blocks_before - want_blocks_after) * 512))
14703
14704         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14705                 skip "need at least 2.14.0 for fallocate punch"
14706
14707         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14708                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14709         fi
14710
14711         check_set_fallocate_or_skip
14712         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14713
14714         [[ "x$DOM" == "xyes" ]] &&
14715                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14716
14717         echo "Verify fallocate punch: Range within the file range"
14718         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14719                 error "dd failed for bs 4096 and count 5"
14720
14721         # Call fallocate with punch range which is within the file range
14722         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
14723                 error "fallocate failed: offset 4096 and length $length"
14724         # client must see changes immediately after fallocate
14725         size=$(stat -c '%s' $DIR/$tfile)
14726         blocks=$(stat -c '%b' $DIR/$tfile)
14727
14728         # Verify punch worked.
14729         (( blocks == want_blocks_after )) ||
14730                 error "punch failed: blocks $blocks != $want_blocks_after"
14731
14732         (( size == want_size_before )) ||
14733                 error "punch failed: size $size != $want_size_before"
14734
14735         # Verify there is hole in file
14736         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14737         # precomputed md5sum
14738         local expect="4a9a834a2db02452929c0a348273b4aa"
14739
14740         cksum=($(md5sum $DIR/$tfile))
14741         [[ "${cksum[0]}" == "$expect" ]] ||
14742                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14743
14744         # Start second sub-case for fallocate punch.
14745         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14746         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14747                 error "dd failed for bs 4096 and count 5"
14748
14749         # Punch range less than block size will have no change in block count
14750         want_blocks_after=40  # 512 sized blocks
14751
14752         # Punch overlaps two blocks and less than blocksize
14753         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
14754                 error "fallocate failed: offset 4000 length 3000"
14755         size=$(stat -c '%s' $DIR/$tfile)
14756         blocks=$(stat -c '%b' $DIR/$tfile)
14757
14758         # Verify punch worked.
14759         (( blocks == want_blocks_after )) ||
14760                 error "punch failed: blocks $blocks != $want_blocks_after"
14761
14762         (( size == want_size_before )) ||
14763                 error "punch failed: size $size != $want_size_before"
14764
14765         # Verify if range is really zero'ed out. We expect Zeros.
14766         # precomputed md5sum
14767         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14768         cksum=($(md5sum $DIR/$tfile))
14769         [[ "${cksum[0]}" == "$expect" ]] ||
14770                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14771 }
14772 run_test 150f "Verify fallocate punch functionality"
14773
14774 test_150g() {
14775         local space
14776         local size
14777         local blocks
14778         local blocks_after
14779         local size_after
14780         local BS=4096 # Block size in bytes
14781
14782         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14783                 skip "need at least 2.14.0 for fallocate punch"
14784
14785         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14786                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14787         fi
14788
14789         check_set_fallocate_or_skip
14790         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14791
14792         if [[ "x$DOM" == "xyes" ]]; then
14793                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
14794                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
14795         else
14796                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14797                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14798         fi
14799
14800         # Get 100MB per OST of the available space to reduce run time
14801         # else 60% of the available space if we are running SLOW tests
14802         if [ $SLOW == "no" ]; then
14803                 space=$((1024 * 100 * OSTCOUNT))
14804         else
14805                 # Find OST with Minimum Size
14806                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14807                         sort -un | head -1)
14808                 echo "min size OST: $space"
14809                 space=$(((space * 60)/100 * OSTCOUNT))
14810         fi
14811         # space in 1k units, round to 4k blocks
14812         local blkcount=$((space * 1024 / $BS))
14813
14814         echo "Verify fallocate punch: Very large Range"
14815         fallocate -l${space}k $DIR/$tfile ||
14816                 error "fallocate ${space}k $DIR/$tfile failed"
14817         # write 1M at the end, start and in the middle
14818         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14819                 error "dd failed: bs $BS count 256"
14820         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14821                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14822         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14823                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14824
14825         # Gather stats.
14826         size=$(stat -c '%s' $DIR/$tfile)
14827
14828         # gather punch length.
14829         local punch_size=$((size - (BS * 2)))
14830
14831         echo "punch_size = $punch_size"
14832         echo "size - punch_size: $((size - punch_size))"
14833         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14834
14835         # Call fallocate to punch all except 2 blocks. We leave the
14836         # first and the last block
14837         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14838         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14839                 error "fallocate failed: offset $BS length $punch_size"
14840
14841         size_after=$(stat -c '%s' $DIR/$tfile)
14842         blocks_after=$(stat -c '%b' $DIR/$tfile)
14843
14844         # Verify punch worked.
14845         # Size should be kept
14846         (( size == size_after )) ||
14847                 error "punch failed: size $size != $size_after"
14848
14849         # two 4k data blocks to remain plus possible 1 extra extent block
14850         (( blocks_after <= ((BS / 512) * 3) )) ||
14851                 error "too many blocks remains: $blocks_after"
14852
14853         # Verify that file has hole between the first and the last blocks
14854         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14855         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14856
14857         echo "Hole at [$hole_start, $hole_end)"
14858         (( hole_start == BS )) ||
14859                 error "no hole at offset $BS after punch"
14860
14861         (( hole_end == BS + punch_size )) ||
14862                 error "data at offset $hole_end < $((BS + punch_size))"
14863 }
14864 run_test 150g "Verify fallocate punch on large range"
14865
14866 #LU-2902 roc_hit was not able to read all values from lproc
14867 function roc_hit_init() {
14868         local list=$(comma_list $(osts_nodes))
14869         local dir=$DIR/$tdir-check
14870         local file=$dir/$tfile
14871         local BEFORE
14872         local AFTER
14873         local idx
14874
14875         test_mkdir $dir
14876         #use setstripe to do a write to every ost
14877         for i in $(seq 0 $((OSTCOUNT-1))); do
14878                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14879                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14880                 idx=$(printf %04x $i)
14881                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14882                         awk '$1 == "cache_access" {sum += $7}
14883                                 END { printf("%0.0f", sum) }')
14884
14885                 cancel_lru_locks osc
14886                 cat $file >/dev/null
14887
14888                 AFTER=$(get_osd_param $list *OST*$idx stats |
14889                         awk '$1 == "cache_access" {sum += $7}
14890                                 END { printf("%0.0f", sum) }')
14891
14892                 echo BEFORE:$BEFORE AFTER:$AFTER
14893                 if ! let "AFTER - BEFORE == 4"; then
14894                         rm -rf $dir
14895                         error "roc_hit is not safe to use"
14896                 fi
14897                 rm $file
14898         done
14899
14900         rm -rf $dir
14901 }
14902
14903 function roc_hit() {
14904         local list=$(comma_list $(osts_nodes))
14905         echo $(get_osd_param $list '' stats |
14906                 awk '$1 == "cache_hit" {sum += $7}
14907                         END { printf("%0.0f", sum) }')
14908 }
14909
14910 function set_cache() {
14911         local on=1
14912
14913         if [ "$2" == "off" ]; then
14914                 on=0;
14915         fi
14916         local list=$(comma_list $(osts_nodes))
14917         set_osd_param $list '' $1_cache_enable $on
14918
14919         cancel_lru_locks osc
14920 }
14921
14922 test_151() {
14923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14924         remote_ost_nodsh && skip "remote OST with nodsh"
14925
14926         local CPAGES=3
14927         local list=$(comma_list $(osts_nodes))
14928
14929         # check whether obdfilter is cache capable at all
14930         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14931                 skip "not cache-capable obdfilter"
14932         fi
14933
14934         # check cache is enabled on all obdfilters
14935         if get_osd_param $list '' read_cache_enable | grep 0; then
14936                 skip "oss cache is disabled"
14937         fi
14938
14939         set_osd_param $list '' writethrough_cache_enable 1
14940
14941         # check write cache is enabled on all obdfilters
14942         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14943                 skip "oss write cache is NOT enabled"
14944         fi
14945
14946         roc_hit_init
14947
14948         #define OBD_FAIL_OBD_NO_LRU  0x609
14949         do_nodes $list $LCTL set_param fail_loc=0x609
14950
14951         # pages should be in the case right after write
14952         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14953                 error "dd failed"
14954
14955         local BEFORE=$(roc_hit)
14956         cancel_lru_locks osc
14957         cat $DIR/$tfile >/dev/null
14958         local AFTER=$(roc_hit)
14959
14960         do_nodes $list $LCTL set_param fail_loc=0
14961
14962         if ! let "AFTER - BEFORE == CPAGES"; then
14963                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
14964         fi
14965
14966         cancel_lru_locks osc
14967         # invalidates OST cache
14968         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
14969         set_osd_param $list '' read_cache_enable 0
14970         cat $DIR/$tfile >/dev/null
14971
14972         # now data shouldn't be found in the cache
14973         BEFORE=$(roc_hit)
14974         cancel_lru_locks osc
14975         cat $DIR/$tfile >/dev/null
14976         AFTER=$(roc_hit)
14977         if let "AFTER - BEFORE != 0"; then
14978                 error "IN CACHE: before: $BEFORE, after: $AFTER"
14979         fi
14980
14981         set_osd_param $list '' read_cache_enable 1
14982         rm -f $DIR/$tfile
14983 }
14984 run_test 151 "test cache on oss and controls ==============================="
14985
14986 test_152() {
14987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14988
14989         local TF="$TMP/$tfile"
14990
14991         # simulate ENOMEM during write
14992 #define OBD_FAIL_OST_NOMEM      0x226
14993         lctl set_param fail_loc=0x80000226
14994         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14995         cp $TF $DIR/$tfile
14996         sync || error "sync failed"
14997         lctl set_param fail_loc=0
14998
14999         # discard client's cache
15000         cancel_lru_locks osc
15001
15002         # simulate ENOMEM during read
15003         lctl set_param fail_loc=0x80000226
15004         cmp $TF $DIR/$tfile || error "cmp failed"
15005         lctl set_param fail_loc=0
15006
15007         rm -f $TF
15008 }
15009 run_test 152 "test read/write with enomem ============================"
15010
15011 test_153() {
15012         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15013 }
15014 run_test 153 "test if fdatasync does not crash ======================="
15015
15016 dot_lustre_fid_permission_check() {
15017         local fid=$1
15018         local ffid=$MOUNT/.lustre/fid/$fid
15019         local test_dir=$2
15020
15021         echo "stat fid $fid"
15022         stat $ffid > /dev/null || error "stat $ffid failed."
15023         echo "touch fid $fid"
15024         touch $ffid || error "touch $ffid failed."
15025         echo "write to fid $fid"
15026         cat /etc/hosts > $ffid || error "write $ffid failed."
15027         echo "read fid $fid"
15028         diff /etc/hosts $ffid || error "read $ffid failed."
15029         echo "append write to fid $fid"
15030         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15031         echo "rename fid $fid"
15032         mv $ffid $test_dir/$tfile.1 &&
15033                 error "rename $ffid to $tfile.1 should fail."
15034         touch $test_dir/$tfile.1
15035         mv $test_dir/$tfile.1 $ffid &&
15036                 error "rename $tfile.1 to $ffid should fail."
15037         rm -f $test_dir/$tfile.1
15038         echo "truncate fid $fid"
15039         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15040         echo "link fid $fid"
15041         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15042         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15043                 echo "setfacl fid $fid"
15044                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
15045                 echo "getfacl fid $fid"
15046                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
15047         fi
15048         echo "unlink fid $fid"
15049         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15050         echo "mknod fid $fid"
15051         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15052
15053         fid=[0xf00000400:0x1:0x0]
15054         ffid=$MOUNT/.lustre/fid/$fid
15055
15056         echo "stat non-exist fid $fid"
15057         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15058         echo "write to non-exist fid $fid"
15059         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15060         echo "link new fid $fid"
15061         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15062
15063         mkdir -p $test_dir/$tdir
15064         touch $test_dir/$tdir/$tfile
15065         fid=$($LFS path2fid $test_dir/$tdir)
15066         rc=$?
15067         [ $rc -ne 0 ] &&
15068                 error "error: could not get fid for $test_dir/$dir/$tfile."
15069
15070         ffid=$MOUNT/.lustre/fid/$fid
15071
15072         echo "ls $fid"
15073         ls $ffid > /dev/null || error "ls $ffid failed."
15074         echo "touch $fid/$tfile.1"
15075         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15076
15077         echo "touch $MOUNT/.lustre/fid/$tfile"
15078         touch $MOUNT/.lustre/fid/$tfile && \
15079                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15080
15081         echo "setxattr to $MOUNT/.lustre/fid"
15082         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15083
15084         echo "listxattr for $MOUNT/.lustre/fid"
15085         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15086
15087         echo "delxattr from $MOUNT/.lustre/fid"
15088         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15089
15090         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15091         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15092                 error "touch invalid fid should fail."
15093
15094         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15095         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15096                 error "touch non-normal fid should fail."
15097
15098         echo "rename $tdir to $MOUNT/.lustre/fid"
15099         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15100                 error "rename to $MOUNT/.lustre/fid should fail."
15101
15102         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15103         then            # LU-3547
15104                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15105                 local new_obf_mode=777
15106
15107                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15108                 chmod $new_obf_mode $DIR/.lustre/fid ||
15109                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15110
15111                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15112                 [ $obf_mode -eq $new_obf_mode ] ||
15113                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15114
15115                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15116                 chmod $old_obf_mode $DIR/.lustre/fid ||
15117                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15118         fi
15119
15120         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15121         fid=$($LFS path2fid $test_dir/$tfile-2)
15122
15123         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15124         then # LU-5424
15125                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15126                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15127                         error "create lov data thru .lustre failed"
15128         fi
15129         echo "cp /etc/passwd $test_dir/$tfile-2"
15130         cp /etc/passwd $test_dir/$tfile-2 ||
15131                 error "copy to $test_dir/$tfile-2 failed."
15132         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15133         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15134                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15135
15136         rm -rf $test_dir/tfile.lnk
15137         rm -rf $test_dir/$tfile-2
15138 }
15139
15140 test_154A() {
15141         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15142                 skip "Need MDS version at least 2.4.1"
15143
15144         local tf=$DIR/$tfile
15145         touch $tf
15146
15147         local fid=$($LFS path2fid $tf)
15148         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15149
15150         # check that we get the same pathname back
15151         local rootpath
15152         local found
15153         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15154                 echo "$rootpath $fid"
15155                 found=$($LFS fid2path $rootpath "$fid")
15156                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15157                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15158         done
15159
15160         # check wrong root path format
15161         rootpath=$MOUNT"_wrong"
15162         found=$($LFS fid2path $rootpath "$fid")
15163         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15164 }
15165 run_test 154A "lfs path2fid and fid2path basic checks"
15166
15167 test_154B() {
15168         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15169                 skip "Need MDS version at least 2.4.1"
15170
15171         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15172         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15173         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15174         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15175
15176         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15177         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15178
15179         # check that we get the same pathname
15180         echo "PFID: $PFID, name: $name"
15181         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15182         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15183         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15184                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15185
15186         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15187 }
15188 run_test 154B "verify the ll_decode_linkea tool"
15189
15190 test_154a() {
15191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15192         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15193         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15194                 skip "Need MDS version at least 2.2.51"
15195         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15196
15197         cp /etc/hosts $DIR/$tfile
15198
15199         fid=$($LFS path2fid $DIR/$tfile)
15200         rc=$?
15201         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15202
15203         dot_lustre_fid_permission_check "$fid" $DIR ||
15204                 error "dot lustre permission check $fid failed"
15205
15206         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15207
15208         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15209
15210         touch $MOUNT/.lustre/file &&
15211                 error "creation is not allowed under .lustre"
15212
15213         mkdir $MOUNT/.lustre/dir &&
15214                 error "mkdir is not allowed under .lustre"
15215
15216         rm -rf $DIR/$tfile
15217 }
15218 run_test 154a "Open-by-FID"
15219
15220 test_154b() {
15221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15222         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15223         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15224         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15225                 skip "Need MDS version at least 2.2.51"
15226
15227         local remote_dir=$DIR/$tdir/remote_dir
15228         local MDTIDX=1
15229         local rc=0
15230
15231         mkdir -p $DIR/$tdir
15232         $LFS mkdir -i $MDTIDX $remote_dir ||
15233                 error "create remote directory failed"
15234
15235         cp /etc/hosts $remote_dir/$tfile
15236
15237         fid=$($LFS path2fid $remote_dir/$tfile)
15238         rc=$?
15239         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15240
15241         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15242                 error "dot lustre permission check $fid failed"
15243         rm -rf $DIR/$tdir
15244 }
15245 run_test 154b "Open-by-FID for remote directory"
15246
15247 test_154c() {
15248         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15249                 skip "Need MDS version at least 2.4.1"
15250
15251         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15252         local FID1=$($LFS path2fid $DIR/$tfile.1)
15253         local FID2=$($LFS path2fid $DIR/$tfile.2)
15254         local FID3=$($LFS path2fid $DIR/$tfile.3)
15255
15256         local N=1
15257         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15258                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15259                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15260                 local want=FID$N
15261                 [ "$FID" = "${!want}" ] ||
15262                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15263                 N=$((N + 1))
15264         done
15265
15266         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15267         do
15268                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15269                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15270                 N=$((N + 1))
15271         done
15272 }
15273 run_test 154c "lfs path2fid and fid2path multiple arguments"
15274
15275 test_154d() {
15276         remote_mds_nodsh && skip "remote MDS with nodsh"
15277         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15278                 skip "Need MDS version at least 2.5.53"
15279
15280         if remote_mds; then
15281                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15282         else
15283                 nid="0@lo"
15284         fi
15285         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15286         local fd
15287         local cmd
15288
15289         rm -f $DIR/$tfile
15290         touch $DIR/$tfile
15291
15292         local fid=$($LFS path2fid $DIR/$tfile)
15293         # Open the file
15294         fd=$(free_fd)
15295         cmd="exec $fd<$DIR/$tfile"
15296         eval $cmd
15297         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15298         echo "$fid_list" | grep "$fid"
15299         rc=$?
15300
15301         cmd="exec $fd>/dev/null"
15302         eval $cmd
15303         if [ $rc -ne 0 ]; then
15304                 error "FID $fid not found in open files list $fid_list"
15305         fi
15306 }
15307 run_test 154d "Verify open file fid"
15308
15309 test_154e()
15310 {
15311         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15312                 skip "Need MDS version at least 2.6.50"
15313
15314         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15315                 error ".lustre returned by readdir"
15316         fi
15317 }
15318 run_test 154e ".lustre is not returned by readdir"
15319
15320 test_154f() {
15321         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15322
15323         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15324         mkdir_on_mdt0 $DIR/$tdir
15325         # test dirs inherit from its stripe
15326         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15327         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15328         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15329         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15330         touch $DIR/f
15331
15332         # get fid of parents
15333         local FID0=$($LFS path2fid $DIR/$tdir)
15334         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15335         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15336         local FID3=$($LFS path2fid $DIR)
15337
15338         # check that path2fid --parents returns expected <parent_fid>/name
15339         # 1) test for a directory (single parent)
15340         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15341         [ "$parent" == "$FID0/foo1" ] ||
15342                 error "expected parent: $FID0/foo1, got: $parent"
15343
15344         # 2) test for a file with nlink > 1 (multiple parents)
15345         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15346         echo "$parent" | grep -F "$FID1/$tfile" ||
15347                 error "$FID1/$tfile not returned in parent list"
15348         echo "$parent" | grep -F "$FID2/link" ||
15349                 error "$FID2/link not returned in parent list"
15350
15351         # 3) get parent by fid
15352         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15353         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15354         echo "$parent" | grep -F "$FID1/$tfile" ||
15355                 error "$FID1/$tfile not returned in parent list (by fid)"
15356         echo "$parent" | grep -F "$FID2/link" ||
15357                 error "$FID2/link not returned in parent list (by fid)"
15358
15359         # 4) test for entry in root directory
15360         parent=$($LFS path2fid --parents $DIR/f)
15361         echo "$parent" | grep -F "$FID3/f" ||
15362                 error "$FID3/f not returned in parent list"
15363
15364         # 5) test it on root directory
15365         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15366                 error "$MOUNT should not have parents"
15367
15368         # enable xattr caching and check that linkea is correctly updated
15369         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15370         save_lustre_params client "llite.*.xattr_cache" > $save
15371         lctl set_param llite.*.xattr_cache 1
15372
15373         # 6.1) linkea update on rename
15374         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15375
15376         # get parents by fid
15377         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15378         # foo1 should no longer be returned in parent list
15379         echo "$parent" | grep -F "$FID1" &&
15380                 error "$FID1 should no longer be in parent list"
15381         # the new path should appear
15382         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15383                 error "$FID2/$tfile.moved is not in parent list"
15384
15385         # 6.2) linkea update on unlink
15386         rm -f $DIR/$tdir/foo2/link
15387         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15388         # foo2/link should no longer be returned in parent list
15389         echo "$parent" | grep -F "$FID2/link" &&
15390                 error "$FID2/link should no longer be in parent list"
15391         true
15392
15393         rm -f $DIR/f
15394         restore_lustre_params < $save
15395         rm -f $save
15396 }
15397 run_test 154f "get parent fids by reading link ea"
15398
15399 test_154g()
15400 {
15401         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15402         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15403            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15404                 skip "Need MDS version at least 2.6.92"
15405
15406         mkdir_on_mdt0 $DIR/$tdir
15407         llapi_fid_test -d $DIR/$tdir
15408 }
15409 run_test 154g "various llapi FID tests"
15410
15411 test_155_small_load() {
15412     local temp=$TMP/$tfile
15413     local file=$DIR/$tfile
15414
15415     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15416         error "dd of=$temp bs=6096 count=1 failed"
15417     cp $temp $file
15418     cancel_lru_locks $OSC
15419     cmp $temp $file || error "$temp $file differ"
15420
15421     $TRUNCATE $temp 6000
15422     $TRUNCATE $file 6000
15423     cmp $temp $file || error "$temp $file differ (truncate1)"
15424
15425     echo "12345" >>$temp
15426     echo "12345" >>$file
15427     cmp $temp $file || error "$temp $file differ (append1)"
15428
15429     echo "12345" >>$temp
15430     echo "12345" >>$file
15431     cmp $temp $file || error "$temp $file differ (append2)"
15432
15433     rm -f $temp $file
15434     true
15435 }
15436
15437 test_155_big_load() {
15438         remote_ost_nodsh && skip "remote OST with nodsh"
15439
15440         local temp=$TMP/$tfile
15441         local file=$DIR/$tfile
15442
15443         free_min_max
15444         local cache_size=$(do_facet ost$((MAXI+1)) \
15445                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15446         local large_file_size=$((cache_size * 2))
15447
15448         echo "OSS cache size: $cache_size KB"
15449         echo "Large file size: $large_file_size KB"
15450
15451         [ $MAXV -le $large_file_size ] &&
15452                 skip_env "max available OST size needs > $large_file_size KB"
15453
15454         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15455
15456         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15457                 error "dd of=$temp bs=$large_file_size count=1k failed"
15458         cp $temp $file
15459         ls -lh $temp $file
15460         cancel_lru_locks osc
15461         cmp $temp $file || error "$temp $file differ"
15462
15463         rm -f $temp $file
15464         true
15465 }
15466
15467 save_writethrough() {
15468         local facets=$(get_facets OST)
15469
15470         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15471 }
15472
15473 test_155a() {
15474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15475
15476         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15477
15478         save_writethrough $p
15479
15480         set_cache read on
15481         set_cache writethrough on
15482         test_155_small_load
15483         restore_lustre_params < $p
15484         rm -f $p
15485 }
15486 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15487
15488 test_155b() {
15489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15490
15491         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15492
15493         save_writethrough $p
15494
15495         set_cache read on
15496         set_cache writethrough off
15497         test_155_small_load
15498         restore_lustre_params < $p
15499         rm -f $p
15500 }
15501 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15502
15503 test_155c() {
15504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15505
15506         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15507
15508         save_writethrough $p
15509
15510         set_cache read off
15511         set_cache writethrough on
15512         test_155_small_load
15513         restore_lustre_params < $p
15514         rm -f $p
15515 }
15516 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15517
15518 test_155d() {
15519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15520
15521         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15522
15523         save_writethrough $p
15524
15525         set_cache read off
15526         set_cache writethrough off
15527         test_155_small_load
15528         restore_lustre_params < $p
15529         rm -f $p
15530 }
15531 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15532
15533 test_155e() {
15534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15535
15536         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15537
15538         save_writethrough $p
15539
15540         set_cache read on
15541         set_cache writethrough on
15542         test_155_big_load
15543         restore_lustre_params < $p
15544         rm -f $p
15545 }
15546 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15547
15548 test_155f() {
15549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15550
15551         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15552
15553         save_writethrough $p
15554
15555         set_cache read on
15556         set_cache writethrough off
15557         test_155_big_load
15558         restore_lustre_params < $p
15559         rm -f $p
15560 }
15561 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15562
15563 test_155g() {
15564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15565
15566         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15567
15568         save_writethrough $p
15569
15570         set_cache read off
15571         set_cache writethrough on
15572         test_155_big_load
15573         restore_lustre_params < $p
15574         rm -f $p
15575 }
15576 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15577
15578 test_155h() {
15579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15580
15581         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15582
15583         save_writethrough $p
15584
15585         set_cache read off
15586         set_cache writethrough off
15587         test_155_big_load
15588         restore_lustre_params < $p
15589         rm -f $p
15590 }
15591 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15592
15593 test_156() {
15594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15595         remote_ost_nodsh && skip "remote OST with nodsh"
15596         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15597                 skip "stats not implemented on old servers"
15598         [ "$ost1_FSTYPE" = "zfs" ] &&
15599                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15600
15601         local CPAGES=3
15602         local BEFORE
15603         local AFTER
15604         local file="$DIR/$tfile"
15605         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15606
15607         save_writethrough $p
15608         roc_hit_init
15609
15610         log "Turn on read and write cache"
15611         set_cache read on
15612         set_cache writethrough on
15613
15614         log "Write data and read it back."
15615         log "Read should be satisfied from the cache."
15616         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15617         BEFORE=$(roc_hit)
15618         cancel_lru_locks osc
15619         cat $file >/dev/null
15620         AFTER=$(roc_hit)
15621         if ! let "AFTER - BEFORE == CPAGES"; then
15622                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15623         else
15624                 log "cache hits: before: $BEFORE, after: $AFTER"
15625         fi
15626
15627         log "Read again; it should be satisfied from the cache."
15628         BEFORE=$AFTER
15629         cancel_lru_locks osc
15630         cat $file >/dev/null
15631         AFTER=$(roc_hit)
15632         if ! let "AFTER - BEFORE == CPAGES"; then
15633                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15634         else
15635                 log "cache hits:: before: $BEFORE, after: $AFTER"
15636         fi
15637
15638         log "Turn off the read cache and turn on the write cache"
15639         set_cache read off
15640         set_cache writethrough on
15641
15642         log "Read again; it should be satisfied from the cache."
15643         BEFORE=$(roc_hit)
15644         cancel_lru_locks osc
15645         cat $file >/dev/null
15646         AFTER=$(roc_hit)
15647         if ! let "AFTER - BEFORE == CPAGES"; then
15648                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15649         else
15650                 log "cache hits:: before: $BEFORE, after: $AFTER"
15651         fi
15652
15653         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15654                 # > 2.12.56 uses pagecache if cached
15655                 log "Read again; it should not be satisfied from the cache."
15656                 BEFORE=$AFTER
15657                 cancel_lru_locks osc
15658                 cat $file >/dev/null
15659                 AFTER=$(roc_hit)
15660                 if ! let "AFTER - BEFORE == 0"; then
15661                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15662                 else
15663                         log "cache hits:: before: $BEFORE, after: $AFTER"
15664                 fi
15665         fi
15666
15667         log "Write data and read it back."
15668         log "Read should be satisfied from the cache."
15669         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15670         BEFORE=$(roc_hit)
15671         cancel_lru_locks osc
15672         cat $file >/dev/null
15673         AFTER=$(roc_hit)
15674         if ! let "AFTER - BEFORE == CPAGES"; then
15675                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15676         else
15677                 log "cache hits:: before: $BEFORE, after: $AFTER"
15678         fi
15679
15680         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15681                 # > 2.12.56 uses pagecache if cached
15682                 log "Read again; it should not be satisfied from the cache."
15683                 BEFORE=$AFTER
15684                 cancel_lru_locks osc
15685                 cat $file >/dev/null
15686                 AFTER=$(roc_hit)
15687                 if ! let "AFTER - BEFORE == 0"; then
15688                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15689                 else
15690                         log "cache hits:: before: $BEFORE, after: $AFTER"
15691                 fi
15692         fi
15693
15694         log "Turn off read and write cache"
15695         set_cache read off
15696         set_cache writethrough off
15697
15698         log "Write data and read it back"
15699         log "It should not be satisfied from the cache."
15700         rm -f $file
15701         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15702         cancel_lru_locks osc
15703         BEFORE=$(roc_hit)
15704         cat $file >/dev/null
15705         AFTER=$(roc_hit)
15706         if ! let "AFTER - BEFORE == 0"; then
15707                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15708         else
15709                 log "cache hits:: before: $BEFORE, after: $AFTER"
15710         fi
15711
15712         log "Turn on the read cache and turn off the write cache"
15713         set_cache read on
15714         set_cache writethrough off
15715
15716         log "Write data and read it back"
15717         log "It should not be satisfied from the cache."
15718         rm -f $file
15719         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15720         BEFORE=$(roc_hit)
15721         cancel_lru_locks osc
15722         cat $file >/dev/null
15723         AFTER=$(roc_hit)
15724         if ! let "AFTER - BEFORE == 0"; then
15725                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15726         else
15727                 log "cache hits:: before: $BEFORE, after: $AFTER"
15728         fi
15729
15730         log "Read again; it should be satisfied from the cache."
15731         BEFORE=$(roc_hit)
15732         cancel_lru_locks osc
15733         cat $file >/dev/null
15734         AFTER=$(roc_hit)
15735         if ! let "AFTER - BEFORE == CPAGES"; then
15736                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15737         else
15738                 log "cache hits:: before: $BEFORE, after: $AFTER"
15739         fi
15740
15741         restore_lustre_params < $p
15742         rm -f $p $file
15743 }
15744 run_test 156 "Verification of tunables"
15745
15746 test_160a() {
15747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15748         remote_mds_nodsh && skip "remote MDS with nodsh"
15749         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15750                 skip "Need MDS version at least 2.2.0"
15751
15752         changelog_register || error "changelog_register failed"
15753         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15754         changelog_users $SINGLEMDS | grep -q $cl_user ||
15755                 error "User $cl_user not found in changelog_users"
15756
15757         mkdir_on_mdt0 $DIR/$tdir
15758
15759         # change something
15760         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15761         changelog_clear 0 || error "changelog_clear failed"
15762         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15763         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15764         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15765         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15766         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15767         rm $DIR/$tdir/pics/desktop.jpg
15768
15769         echo "verifying changelog mask"
15770         changelog_chmask "-MKDIR"
15771         changelog_chmask "-CLOSE"
15772
15773         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15774         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15775
15776         changelog_chmask "+MKDIR"
15777         changelog_chmask "+CLOSE"
15778
15779         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15780         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15781
15782         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15783         CLOSES=$(changelog_dump | grep -c "CLOSE")
15784         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15785         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15786
15787         # verify contents
15788         echo "verifying target fid"
15789         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15790         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15791         [ "$fidc" == "$fidf" ] ||
15792                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15793         echo "verifying parent fid"
15794         # The FID returned from the Changelog may be the directory shard on
15795         # a different MDT, and not the FID returned by path2fid on the parent.
15796         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15797         # since this is what will matter when recreating this file in the tree.
15798         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15799         local pathp=$($LFS fid2path $MOUNT "$fidp")
15800         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15801                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15802
15803         echo "getting records for $cl_user"
15804         changelog_users $SINGLEMDS
15805         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15806         local nclr=3
15807         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15808                 error "changelog_clear failed"
15809         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15810         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15811         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15812                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15813
15814         local min0_rec=$(changelog_users $SINGLEMDS |
15815                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15816         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15817                           awk '{ print $1; exit; }')
15818
15819         changelog_dump | tail -n 5
15820         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15821         [ $first_rec == $((min0_rec + 1)) ] ||
15822                 error "first index should be $min0_rec + 1 not $first_rec"
15823
15824         # LU-3446 changelog index reset on MDT restart
15825         local cur_rec1=$(changelog_users $SINGLEMDS |
15826                          awk '/^current.index:/ { print $NF }')
15827         changelog_clear 0 ||
15828                 error "clear all changelog records for $cl_user failed"
15829         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15830         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15831                 error "Fail to start $SINGLEMDS"
15832         local cur_rec2=$(changelog_users $SINGLEMDS |
15833                          awk '/^current.index:/ { print $NF }')
15834         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15835         [ $cur_rec1 == $cur_rec2 ] ||
15836                 error "current index should be $cur_rec1 not $cur_rec2"
15837
15838         echo "verifying users from this test are deregistered"
15839         changelog_deregister || error "changelog_deregister failed"
15840         changelog_users $SINGLEMDS | grep -q $cl_user &&
15841                 error "User '$cl_user' still in changelog_users"
15842
15843         # lctl get_param -n mdd.*.changelog_users
15844         # current_index: 144
15845         # ID    index (idle seconds)
15846         # cl3   144   (2) mask=<list>
15847         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15848                 # this is the normal case where all users were deregistered
15849                 # make sure no new records are added when no users are present
15850                 local last_rec1=$(changelog_users $SINGLEMDS |
15851                                   awk '/^current.index:/ { print $NF }')
15852                 touch $DIR/$tdir/chloe
15853                 local last_rec2=$(changelog_users $SINGLEMDS |
15854                                   awk '/^current.index:/ { print $NF }')
15855                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15856                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15857         else
15858                 # any changelog users must be leftovers from a previous test
15859                 changelog_users $SINGLEMDS
15860                 echo "other changelog users; can't verify off"
15861         fi
15862 }
15863 run_test 160a "changelog sanity"
15864
15865 test_160b() { # LU-3587
15866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15867         remote_mds_nodsh && skip "remote MDS with nodsh"
15868         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15869                 skip "Need MDS version at least 2.2.0"
15870
15871         changelog_register || error "changelog_register failed"
15872         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15873         changelog_users $SINGLEMDS | grep -q $cl_user ||
15874                 error "User '$cl_user' not found in changelog_users"
15875
15876         local longname1=$(str_repeat a 255)
15877         local longname2=$(str_repeat b 255)
15878
15879         cd $DIR
15880         echo "creating very long named file"
15881         touch $longname1 || error "create of '$longname1' failed"
15882         echo "renaming very long named file"
15883         mv $longname1 $longname2
15884
15885         changelog_dump | grep RENME | tail -n 5
15886         rm -f $longname2
15887 }
15888 run_test 160b "Verify that very long rename doesn't crash in changelog"
15889
15890 test_160c() {
15891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15892         remote_mds_nodsh && skip "remote MDS with nodsh"
15893
15894         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15895                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15896                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15897                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15898
15899         local rc=0
15900
15901         # Registration step
15902         changelog_register || error "changelog_register failed"
15903
15904         rm -rf $DIR/$tdir
15905         mkdir -p $DIR/$tdir
15906         $MCREATE $DIR/$tdir/foo_160c
15907         changelog_chmask "-TRUNC"
15908         $TRUNCATE $DIR/$tdir/foo_160c 200
15909         changelog_chmask "+TRUNC"
15910         $TRUNCATE $DIR/$tdir/foo_160c 199
15911         changelog_dump | tail -n 5
15912         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15913         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15914 }
15915 run_test 160c "verify that changelog log catch the truncate event"
15916
15917 test_160d() {
15918         remote_mds_nodsh && skip "remote MDS with nodsh"
15919         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15921         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15922                 skip "Need MDS version at least 2.7.60"
15923
15924         # Registration step
15925         changelog_register || error "changelog_register failed"
15926
15927         mkdir -p $DIR/$tdir/migrate_dir
15928         changelog_clear 0 || error "changelog_clear failed"
15929
15930         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15931         changelog_dump | tail -n 5
15932         local migrates=$(changelog_dump | grep -c "MIGRT")
15933         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15934 }
15935 run_test 160d "verify that changelog log catch the migrate event"
15936
15937 test_160e() {
15938         remote_mds_nodsh && skip "remote MDS with nodsh"
15939
15940         # Create a user
15941         changelog_register || error "changelog_register failed"
15942
15943         local MDT0=$(facet_svc $SINGLEMDS)
15944         local rc
15945
15946         # No user (expect fail)
15947         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
15948         rc=$?
15949         if [ $rc -eq 0 ]; then
15950                 error "Should fail without user"
15951         elif [ $rc -ne 4 ]; then
15952                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
15953         fi
15954
15955         # Delete a future user (expect fail)
15956         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
15957         rc=$?
15958         if [ $rc -eq 0 ]; then
15959                 error "Deleted non-existant user cl77"
15960         elif [ $rc -ne 2 ]; then
15961                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
15962         fi
15963
15964         # Clear to a bad index (1 billion should be safe)
15965         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
15966         rc=$?
15967
15968         if [ $rc -eq 0 ]; then
15969                 error "Successfully cleared to invalid CL index"
15970         elif [ $rc -ne 22 ]; then
15971                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
15972         fi
15973 }
15974 run_test 160e "changelog negative testing (should return errors)"
15975
15976 test_160f() {
15977         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15978         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15979                 skip "Need MDS version at least 2.10.56"
15980
15981         local mdts=$(comma_list $(mdts_nodes))
15982
15983         # Create a user
15984         changelog_register || error "first changelog_register failed"
15985         changelog_register || error "second changelog_register failed"
15986         local cl_users
15987         declare -A cl_user1
15988         declare -A cl_user2
15989         local user_rec1
15990         local user_rec2
15991         local i
15992
15993         # generate some changelog records to accumulate on each MDT
15994         # use all_char because created files should be evenly distributed
15995         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15996                 error "test_mkdir $tdir failed"
15997         log "$(date +%s): creating first files"
15998         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15999                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16000                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16001         done
16002
16003         # check changelogs have been generated
16004         local start=$SECONDS
16005         local idle_time=$((MDSCOUNT * 5 + 5))
16006         local nbcl=$(changelog_dump | wc -l)
16007         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16008
16009         for param in "changelog_max_idle_time=$idle_time" \
16010                      "changelog_gc=1" \
16011                      "changelog_min_gc_interval=2" \
16012                      "changelog_min_free_cat_entries=3"; do
16013                 local MDT0=$(facet_svc $SINGLEMDS)
16014                 local var="${param%=*}"
16015                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16016
16017                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16018                 do_nodes $mdts $LCTL set_param mdd.*.$param
16019         done
16020
16021         # force cl_user2 to be idle (1st part), but also cancel the
16022         # cl_user1 records so that it is not evicted later in the test.
16023         local sleep1=$((idle_time / 2))
16024         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16025         sleep $sleep1
16026
16027         # simulate changelog catalog almost full
16028         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16029         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16030
16031         for i in $(seq $MDSCOUNT); do
16032                 cl_users=(${CL_USERS[mds$i]})
16033                 cl_user1[mds$i]="${cl_users[0]}"
16034                 cl_user2[mds$i]="${cl_users[1]}"
16035
16036                 [ -n "${cl_user1[mds$i]}" ] ||
16037                         error "mds$i: no user registered"
16038                 [ -n "${cl_user2[mds$i]}" ] ||
16039                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16040
16041                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16042                 [ -n "$user_rec1" ] ||
16043                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16044                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16045                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16046                 [ -n "$user_rec2" ] ||
16047                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16048                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16049                      "$user_rec1 + 2 == $user_rec2"
16050                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16051                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16052                               "$user_rec1 + 2, but is $user_rec2"
16053                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16054                 [ -n "$user_rec2" ] ||
16055                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16056                 [ $user_rec1 == $user_rec2 ] ||
16057                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16058                               "$user_rec1, but is $user_rec2"
16059         done
16060
16061         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16062         local sleep2=$((idle_time - (SECONDS - start) + 1))
16063         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16064         sleep $sleep2
16065
16066         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16067         # cl_user1 should be OK because it recently processed records.
16068         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16069         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16070                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16071                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16072         done
16073
16074         # ensure gc thread is done
16075         for i in $(mdts_nodes); do
16076                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16077                         error "$i: GC-thread not done"
16078         done
16079
16080         local first_rec
16081         for (( i = 1; i <= MDSCOUNT; i++ )); do
16082                 # check cl_user1 still registered
16083                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16084                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16085                 # check cl_user2 unregistered
16086                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16087                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16088
16089                 # check changelogs are present and starting at $user_rec1 + 1
16090                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16091                 [ -n "$user_rec1" ] ||
16092                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16093                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16094                             awk '{ print $1; exit; }')
16095
16096                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16097                 [ $((user_rec1 + 1)) == $first_rec ] ||
16098                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16099         done
16100 }
16101 run_test 160f "changelog garbage collect (timestamped users)"
16102
16103 test_160g() {
16104         remote_mds_nodsh && skip "remote MDS with nodsh"
16105         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16106                 skip "Need MDS version at least 2.14.55"
16107
16108         local mdts=$(comma_list $(mdts_nodes))
16109
16110         # Create a user
16111         changelog_register || error "first changelog_register failed"
16112         changelog_register || error "second changelog_register failed"
16113         local cl_users
16114         declare -A cl_user1
16115         declare -A cl_user2
16116         local user_rec1
16117         local user_rec2
16118         local i
16119
16120         # generate some changelog records to accumulate on each MDT
16121         # use all_char because created files should be evenly distributed
16122         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16123                 error "test_mkdir $tdir failed"
16124         for ((i = 0; i < MDSCOUNT; i++)); do
16125                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16126                         error "create $DIR/$tdir/d$i.1 failed"
16127         done
16128
16129         # check changelogs have been generated
16130         local nbcl=$(changelog_dump | wc -l)
16131         (( $nbcl > 0 )) || error "no changelogs found"
16132
16133         # reduce the max_idle_indexes value to make sure we exceed it
16134         for param in "changelog_max_idle_indexes=2" \
16135                      "changelog_gc=1" \
16136                      "changelog_min_gc_interval=2"; do
16137                 local MDT0=$(facet_svc $SINGLEMDS)
16138                 local var="${param%=*}"
16139                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16140
16141                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16142                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16143                         error "unable to set mdd.*.$param"
16144         done
16145
16146         local start=$SECONDS
16147         for i in $(seq $MDSCOUNT); do
16148                 cl_users=(${CL_USERS[mds$i]})
16149                 cl_user1[mds$i]="${cl_users[0]}"
16150                 cl_user2[mds$i]="${cl_users[1]}"
16151
16152                 [ -n "${cl_user1[mds$i]}" ] ||
16153                         error "mds$i: user1 is not registered"
16154                 [ -n "${cl_user2[mds$i]}" ] ||
16155                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16156
16157                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16158                 [ -n "$user_rec1" ] ||
16159                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16160                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16161                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16162                 [ -n "$user_rec2" ] ||
16163                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16164                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16165                      "$user_rec1 + 2 == $user_rec2"
16166                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16167                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16168                               "expected $user_rec1 + 2, but is $user_rec2"
16169                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16170                 [ -n "$user_rec2" ] ||
16171                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16172                 [ $user_rec1 == $user_rec2 ] ||
16173                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16174                               "expected $user_rec1, but is $user_rec2"
16175         done
16176
16177         # ensure we are past the previous changelog_min_gc_interval set above
16178         local sleep2=$((start + 2 - SECONDS))
16179         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16180         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16181         # cl_user1 should be OK because it recently processed records.
16182         for ((i = 0; i < MDSCOUNT; i++)); do
16183                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16184                         error "create $DIR/$tdir/d$i.3 failed"
16185         done
16186
16187         # ensure gc thread is done
16188         for i in $(mdts_nodes); do
16189                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16190                         error "$i: GC-thread not done"
16191         done
16192
16193         local first_rec
16194         for (( i = 1; i <= MDSCOUNT; i++ )); do
16195                 # check cl_user1 still registered
16196                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16197                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16198                 # check cl_user2 unregistered
16199                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16200                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16201
16202                 # check changelogs are present and starting at $user_rec1 + 1
16203                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16204                 [ -n "$user_rec1" ] ||
16205                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16206                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16207                             awk '{ print $1; exit; }')
16208
16209                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16210                 [ $((user_rec1 + 1)) == $first_rec ] ||
16211                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16212         done
16213 }
16214 run_test 160g "changelog garbage collect on idle records"
16215
16216 test_160h() {
16217         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16218         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16219                 skip "Need MDS version at least 2.10.56"
16220
16221         local mdts=$(comma_list $(mdts_nodes))
16222
16223         # Create a user
16224         changelog_register || error "first changelog_register failed"
16225         changelog_register || error "second changelog_register failed"
16226         local cl_users
16227         declare -A cl_user1
16228         declare -A cl_user2
16229         local user_rec1
16230         local user_rec2
16231         local i
16232
16233         # generate some changelog records to accumulate on each MDT
16234         # use all_char because created files should be evenly distributed
16235         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16236                 error "test_mkdir $tdir failed"
16237         for ((i = 0; i < MDSCOUNT; i++)); do
16238                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16239                         error "create $DIR/$tdir/d$i.1 failed"
16240         done
16241
16242         # check changelogs have been generated
16243         local nbcl=$(changelog_dump | wc -l)
16244         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16245
16246         for param in "changelog_max_idle_time=10" \
16247                      "changelog_gc=1" \
16248                      "changelog_min_gc_interval=2"; do
16249                 local MDT0=$(facet_svc $SINGLEMDS)
16250                 local var="${param%=*}"
16251                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16252
16253                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16254                 do_nodes $mdts $LCTL set_param mdd.*.$param
16255         done
16256
16257         # force cl_user2 to be idle (1st part)
16258         sleep 9
16259
16260         for i in $(seq $MDSCOUNT); do
16261                 cl_users=(${CL_USERS[mds$i]})
16262                 cl_user1[mds$i]="${cl_users[0]}"
16263                 cl_user2[mds$i]="${cl_users[1]}"
16264
16265                 [ -n "${cl_user1[mds$i]}" ] ||
16266                         error "mds$i: no user registered"
16267                 [ -n "${cl_user2[mds$i]}" ] ||
16268                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16269
16270                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16271                 [ -n "$user_rec1" ] ||
16272                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16273                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16274                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16275                 [ -n "$user_rec2" ] ||
16276                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16277                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16278                      "$user_rec1 + 2 == $user_rec2"
16279                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16280                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16281                               "$user_rec1 + 2, but is $user_rec2"
16282                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16283                 [ -n "$user_rec2" ] ||
16284                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16285                 [ $user_rec1 == $user_rec2 ] ||
16286                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16287                               "$user_rec1, but is $user_rec2"
16288         done
16289
16290         # force cl_user2 to be idle (2nd part) and to reach
16291         # changelog_max_idle_time
16292         sleep 2
16293
16294         # force each GC-thread start and block then
16295         # one per MDT/MDD, set fail_val accordingly
16296         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16297         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16298
16299         # generate more changelogs to trigger fail_loc
16300         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16301                 error "create $DIR/$tdir/${tfile}bis failed"
16302
16303         # stop MDT to stop GC-thread, should be done in back-ground as it will
16304         # block waiting for the thread to be released and exit
16305         declare -A stop_pids
16306         for i in $(seq $MDSCOUNT); do
16307                 stop mds$i &
16308                 stop_pids[mds$i]=$!
16309         done
16310
16311         for i in $(mdts_nodes); do
16312                 local facet
16313                 local nb=0
16314                 local facets=$(facets_up_on_host $i)
16315
16316                 for facet in ${facets//,/ }; do
16317                         if [[ $facet == mds* ]]; then
16318                                 nb=$((nb + 1))
16319                         fi
16320                 done
16321                 # ensure each MDS's gc threads are still present and all in "R"
16322                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16323                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16324                         error "$i: expected $nb GC-thread"
16325                 wait_update $i \
16326                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16327                         "R" 20 ||
16328                         error "$i: GC-thread not found in R-state"
16329                 # check umounts of each MDT on MDS have reached kthread_stop()
16330                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16331                         error "$i: expected $nb umount"
16332                 wait_update $i \
16333                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16334                         error "$i: umount not found in D-state"
16335         done
16336
16337         # release all GC-threads
16338         do_nodes $mdts $LCTL set_param fail_loc=0
16339
16340         # wait for MDT stop to complete
16341         for i in $(seq $MDSCOUNT); do
16342                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16343         done
16344
16345         # XXX
16346         # may try to check if any orphan changelog records are present
16347         # via ldiskfs/zfs and llog_reader...
16348
16349         # re-start/mount MDTs
16350         for i in $(seq $MDSCOUNT); do
16351                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16352                         error "Fail to start mds$i"
16353         done
16354
16355         local first_rec
16356         for i in $(seq $MDSCOUNT); do
16357                 # check cl_user1 still registered
16358                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16359                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16360                 # check cl_user2 unregistered
16361                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16362                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16363
16364                 # check changelogs are present and starting at $user_rec1 + 1
16365                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16366                 [ -n "$user_rec1" ] ||
16367                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16368                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16369                             awk '{ print $1; exit; }')
16370
16371                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16372                 [ $((user_rec1 + 1)) == $first_rec ] ||
16373                         error "mds$i: first index should be $user_rec1 + 1, " \
16374                               "but is $first_rec"
16375         done
16376 }
16377 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16378               "during mount"
16379
16380 test_160i() {
16381
16382         local mdts=$(comma_list $(mdts_nodes))
16383
16384         changelog_register || error "first changelog_register failed"
16385
16386         # generate some changelog records to accumulate on each MDT
16387         # use all_char because created files should be evenly distributed
16388         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16389                 error "test_mkdir $tdir failed"
16390         for ((i = 0; i < MDSCOUNT; i++)); do
16391                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16392                         error "create $DIR/$tdir/d$i.1 failed"
16393         done
16394
16395         # check changelogs have been generated
16396         local nbcl=$(changelog_dump | wc -l)
16397         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16398
16399         # simulate race between register and unregister
16400         # XXX as fail_loc is set per-MDS, with DNE configs the race
16401         # simulation will only occur for one MDT per MDS and for the
16402         # others the normal race scenario will take place
16403         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16404         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16405         do_nodes $mdts $LCTL set_param fail_val=1
16406
16407         # unregister 1st user
16408         changelog_deregister &
16409         local pid1=$!
16410         # wait some time for deregister work to reach race rdv
16411         sleep 2
16412         # register 2nd user
16413         changelog_register || error "2nd user register failed"
16414
16415         wait $pid1 || error "1st user deregister failed"
16416
16417         local i
16418         local last_rec
16419         declare -A LAST_REC
16420         for i in $(seq $MDSCOUNT); do
16421                 if changelog_users mds$i | grep "^cl"; then
16422                         # make sure new records are added with one user present
16423                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16424                                           awk '/^current.index:/ { print $NF }')
16425                 else
16426                         error "mds$i has no user registered"
16427                 fi
16428         done
16429
16430         # generate more changelog records to accumulate on each MDT
16431         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16432                 error "create $DIR/$tdir/${tfile}bis failed"
16433
16434         for i in $(seq $MDSCOUNT); do
16435                 last_rec=$(changelog_users $SINGLEMDS |
16436                            awk '/^current.index:/ { print $NF }')
16437                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16438                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16439                         error "changelogs are off on mds$i"
16440         done
16441 }
16442 run_test 160i "changelog user register/unregister race"
16443
16444 test_160j() {
16445         remote_mds_nodsh && skip "remote MDS with nodsh"
16446         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16447                 skip "Need MDS version at least 2.12.56"
16448
16449         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16450         stack_trap "umount $MOUNT2" EXIT
16451
16452         changelog_register || error "first changelog_register failed"
16453         stack_trap "changelog_deregister" EXIT
16454
16455         # generate some changelog
16456         # use all_char because created files should be evenly distributed
16457         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16458                 error "mkdir $tdir failed"
16459         for ((i = 0; i < MDSCOUNT; i++)); do
16460                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16461                         error "create $DIR/$tdir/d$i.1 failed"
16462         done
16463
16464         # open the changelog device
16465         exec 3>/dev/changelog-$FSNAME-MDT0000
16466         stack_trap "exec 3>&-" EXIT
16467         exec 4</dev/changelog-$FSNAME-MDT0000
16468         stack_trap "exec 4<&-" EXIT
16469
16470         # umount the first lustre mount
16471         umount $MOUNT
16472         stack_trap "mount_client $MOUNT" EXIT
16473
16474         # read changelog, which may or may not fail, but should not crash
16475         cat <&4 >/dev/null
16476
16477         # clear changelog
16478         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16479         changelog_users $SINGLEMDS | grep -q $cl_user ||
16480                 error "User $cl_user not found in changelog_users"
16481
16482         printf 'clear:'$cl_user':0' >&3
16483 }
16484 run_test 160j "client can be umounted while its chanangelog is being used"
16485
16486 test_160k() {
16487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16488         remote_mds_nodsh && skip "remote MDS with nodsh"
16489
16490         mkdir -p $DIR/$tdir/1/1
16491
16492         changelog_register || error "changelog_register failed"
16493         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16494
16495         changelog_users $SINGLEMDS | grep -q $cl_user ||
16496                 error "User '$cl_user' not found in changelog_users"
16497 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16498         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16499         rmdir $DIR/$tdir/1/1 & sleep 1
16500         mkdir $DIR/$tdir/2
16501         touch $DIR/$tdir/2/2
16502         rm -rf $DIR/$tdir/2
16503
16504         wait
16505         sleep 4
16506
16507         changelog_dump | grep rmdir || error "rmdir not recorded"
16508 }
16509 run_test 160k "Verify that changelog records are not lost"
16510
16511 # Verifies that a file passed as a parameter has recently had an operation
16512 # performed on it that has generated an MTIME changelog which contains the
16513 # correct parent FID. As files might reside on a different MDT from the
16514 # parent directory in DNE configurations, the FIDs are translated to paths
16515 # before being compared, which should be identical
16516 compare_mtime_changelog() {
16517         local file="${1}"
16518         local mdtidx
16519         local mtime
16520         local cl_fid
16521         local pdir
16522         local dir
16523
16524         mdtidx=$($LFS getstripe --mdt-index $file)
16525         mdtidx=$(printf "%04x" $mdtidx)
16526
16527         # Obtain the parent FID from the MTIME changelog
16528         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16529         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16530
16531         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16532         [ -z "$cl_fid" ] && error "parent FID not present"
16533
16534         # Verify that the path for the parent FID is the same as the path for
16535         # the test directory
16536         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16537
16538         dir=$(dirname $1)
16539
16540         [[ "${pdir%/}" == "$dir" ]] ||
16541                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16542 }
16543
16544 test_160l() {
16545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16546
16547         remote_mds_nodsh && skip "remote MDS with nodsh"
16548         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16549                 skip "Need MDS version at least 2.13.55"
16550
16551         local cl_user
16552
16553         changelog_register || error "changelog_register failed"
16554         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16555
16556         changelog_users $SINGLEMDS | grep -q $cl_user ||
16557                 error "User '$cl_user' not found in changelog_users"
16558
16559         # Clear some types so that MTIME changelogs are generated
16560         changelog_chmask "-CREAT"
16561         changelog_chmask "-CLOSE"
16562
16563         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16564
16565         # Test CL_MTIME during setattr
16566         touch $DIR/$tdir/$tfile
16567         compare_mtime_changelog $DIR/$tdir/$tfile
16568
16569         # Test CL_MTIME during close
16570         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16571         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16572 }
16573 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16574
16575 test_160m() {
16576         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16577         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16578                 skip "Need MDS version at least 2.14.51"
16579         local cl_users
16580         local cl_user1
16581         local cl_user2
16582         local pid1
16583
16584         # Create a user
16585         changelog_register || error "first changelog_register failed"
16586         changelog_register || error "second changelog_register failed"
16587
16588         cl_users=(${CL_USERS[mds1]})
16589         cl_user1="${cl_users[0]}"
16590         cl_user2="${cl_users[1]}"
16591         # generate some changelog records to accumulate on MDT0
16592         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16593         createmany -m $DIR/$tdir/$tfile 50 ||
16594                 error "create $DIR/$tdir/$tfile failed"
16595         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16596         rm -f $DIR/$tdir
16597
16598         # check changelogs have been generated
16599         local nbcl=$(changelog_dump | wc -l)
16600         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16601
16602 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16603         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16604
16605         __changelog_clear mds1 $cl_user1 +10
16606         __changelog_clear mds1 $cl_user2 0 &
16607         pid1=$!
16608         sleep 2
16609         __changelog_clear mds1 $cl_user1 0 ||
16610                 error "fail to cancel record for $cl_user1"
16611         wait $pid1
16612         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16613 }
16614 run_test 160m "Changelog clear race"
16615
16616 test_160n() {
16617         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16618         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16619                 skip "Need MDS version at least 2.14.51"
16620         local cl_users
16621         local cl_user1
16622         local cl_user2
16623         local pid1
16624         local first_rec
16625         local last_rec=0
16626
16627         # Create a user
16628         changelog_register || error "first changelog_register failed"
16629
16630         cl_users=(${CL_USERS[mds1]})
16631         cl_user1="${cl_users[0]}"
16632
16633         # generate some changelog records to accumulate on MDT0
16634         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16635         first_rec=$(changelog_users $SINGLEMDS |
16636                         awk '/^current.index:/ { print $NF }')
16637         while (( last_rec < (( first_rec + 65000)) )); do
16638                 createmany -m $DIR/$tdir/$tfile 10000 ||
16639                         error "create $DIR/$tdir/$tfile failed"
16640
16641                 for i in $(seq 0 10000); do
16642                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16643                                 > /dev/null
16644                 done
16645
16646                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16647                         error "unlinkmany failed unlink"
16648                 last_rec=$(changelog_users $SINGLEMDS |
16649                         awk '/^current.index:/ { print $NF }')
16650                 echo last record $last_rec
16651                 (( last_rec == 0 )) && error "no changelog found"
16652         done
16653
16654 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16655         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16656
16657         __changelog_clear mds1 $cl_user1 0 &
16658         pid1=$!
16659         sleep 2
16660         __changelog_clear mds1 $cl_user1 0 ||
16661                 error "fail to cancel record for $cl_user1"
16662         wait $pid1
16663         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16664 }
16665 run_test 160n "Changelog destroy race"
16666
16667 test_160o() {
16668         local mdt="$(facet_svc $SINGLEMDS)"
16669
16670         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16671         remote_mds_nodsh && skip "remote MDS with nodsh"
16672         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16673                 skip "Need MDS version at least 2.14.52"
16674
16675         changelog_register --user test_160o -m unlnk+close+open ||
16676                 error "changelog_register failed"
16677
16678         do_facet $SINGLEMDS $LCTL --device $mdt \
16679                                 changelog_register -u "Tt3_-#" &&
16680                 error "bad symbols in name should fail"
16681
16682         do_facet $SINGLEMDS $LCTL --device $mdt \
16683                                 changelog_register -u test_160o &&
16684                 error "the same name registration should fail"
16685
16686         do_facet $SINGLEMDS $LCTL --device $mdt \
16687                         changelog_register -u test_160toolongname &&
16688                 error "too long name registration should fail"
16689
16690         changelog_chmask "MARK+HSM"
16691         lctl get_param mdd.*.changelog*mask
16692         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16693         changelog_users $SINGLEMDS | grep -q $cl_user ||
16694                 error "User $cl_user not found in changelog_users"
16695         #verify username
16696         echo $cl_user | grep -q test_160o ||
16697                 error "User $cl_user has no specific name 'test160o'"
16698
16699         # change something
16700         changelog_clear 0 || error "changelog_clear failed"
16701         # generate some changelog records to accumulate on MDT0
16702         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16703         touch $DIR/$tdir/$tfile                 # open 1
16704
16705         OPENS=$(changelog_dump | grep -c "OPEN")
16706         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16707
16708         # must be no MKDIR it wasn't set as user mask
16709         MKDIR=$(changelog_dump | grep -c "MKDIR")
16710         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16711
16712         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16713                                 mdd.$mdt.changelog_current_mask -n)
16714         # register maskless user
16715         changelog_register || error "changelog_register failed"
16716         # effective mask should be not changed because it is not minimal
16717         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16718                                 mdd.$mdt.changelog_current_mask -n)
16719         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16720         # set server mask to minimal value
16721         changelog_chmask "MARK"
16722         # check effective mask again, should be treated as DEFMASK now
16723         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16724                                 mdd.$mdt.changelog_current_mask -n)
16725         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16726
16727         do_facet $SINGLEMDS $LCTL --device $mdt \
16728                                 changelog_deregister -u test_160o ||
16729                 error "cannot deregister by name"
16730 }
16731 run_test 160o "changelog user name and mask"
16732
16733 test_160p() {
16734         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16735         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16736                 skip "Need MDS version at least 2.14.51"
16737         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16738         local cl_users
16739         local cl_user1
16740         local entry_count
16741
16742         # Create a user
16743         changelog_register || error "first changelog_register failed"
16744
16745         cl_users=(${CL_USERS[mds1]})
16746         cl_user1="${cl_users[0]}"
16747
16748         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16749         createmany -m $DIR/$tdir/$tfile 50 ||
16750                 error "create $DIR/$tdir/$tfile failed"
16751         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16752         rm -rf $DIR/$tdir
16753
16754         # check changelogs have been generated
16755         entry_count=$(changelog_dump | wc -l)
16756         ((entry_count != 0)) || error "no changelog entries found"
16757
16758         # remove changelog_users and check that orphan entries are removed
16759         stop mds1
16760         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $(mdsdevname 1)"
16761         start mds1 || error "cannot start mdt"
16762         entry_count=$(changelog_dump | wc -l)
16763         ((entry_count == 0)) ||
16764                 error "found $entry_count changelog entries, expected none"
16765 }
16766 run_test 160p "Changelog orphan cleanup with no users"
16767
16768 test_160q() {
16769         local mdt="$(facet_svc $SINGLEMDS)"
16770         local clu
16771
16772         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16773         remote_mds_nodsh && skip "remote MDS with nodsh"
16774         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16775                 skip "Need MDS version at least 2.14.54"
16776
16777         # set server mask to minimal value like server init does
16778         changelog_chmask "MARK"
16779         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16780                 error "changelog_register failed"
16781         # check effective mask again, should be treated as DEFMASK now
16782         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16783                                 mdd.$mdt.changelog_current_mask -n)
16784         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
16785                 error "changelog_deregister failed"
16786         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16787 }
16788 run_test 160q "changelog effective mask is DEFMASK if not set"
16789
16790 test_160s() {
16791         remote_mds_nodsh && skip "remote MDS with nodsh"
16792         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
16793                 skip "Need MDS version at least 2.14.55"
16794
16795         local mdts=$(comma_list $(mdts_nodes))
16796
16797         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
16798         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
16799                                        fail_val=$((24 * 3600 * 10))
16800
16801         # Create a user which is 10 days old
16802         changelog_register || error "first changelog_register failed"
16803         local cl_users
16804         declare -A cl_user1
16805         local i
16806
16807         # generate some changelog records to accumulate on each MDT
16808         # use all_char because created files should be evenly distributed
16809         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16810                 error "test_mkdir $tdir failed"
16811         for ((i = 0; i < MDSCOUNT; i++)); do
16812                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16813                         error "create $DIR/$tdir/d$i.1 failed"
16814         done
16815
16816         # check changelogs have been generated
16817         local nbcl=$(changelog_dump | wc -l)
16818         (( nbcl > 0 )) || error "no changelogs found"
16819
16820         # reduce the max_idle_indexes value to make sure we exceed it
16821         for param in "changelog_max_idle_indexes=2097446912" \
16822                      "changelog_max_idle_time=2592000" \
16823                      "changelog_gc=1" \
16824                      "changelog_min_gc_interval=2"; do
16825                 local MDT0=$(facet_svc $SINGLEMDS)
16826                 local var="${param%=*}"
16827                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16828
16829                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16830                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16831                         error "unable to set mdd.*.$param"
16832         done
16833
16834         local start=$SECONDS
16835         for i in $(seq $MDSCOUNT); do
16836                 cl_users=(${CL_USERS[mds$i]})
16837                 cl_user1[mds$i]="${cl_users[0]}"
16838
16839                 [[ -n "${cl_user1[mds$i]}" ]] ||
16840                         error "mds$i: no user registered"
16841         done
16842
16843         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
16844         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
16845
16846         # ensure we are past the previous changelog_min_gc_interval set above
16847         local sleep2=$((start + 2 - SECONDS))
16848         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16849
16850         # Generate one more changelog to trigger GC
16851         for ((i = 0; i < MDSCOUNT; i++)); do
16852                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
16853                         error "create $DIR/$tdir/d$i.3 failed"
16854         done
16855
16856         # ensure gc thread is done
16857         for node in $(mdts_nodes); do
16858                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
16859                         error "$node: GC-thread not done"
16860         done
16861
16862         do_nodes $mdts $LCTL set_param fail_loc=0
16863
16864         for (( i = 1; i <= MDSCOUNT; i++ )); do
16865                 # check cl_user1 is purged
16866                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
16867                         error "mds$i: User ${cl_user1[mds$i]} is registered"
16868         done
16869         return 0
16870 }
16871 run_test 160s "changelog garbage collect on idle records * time"
16872
16873 test_161a() {
16874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16875
16876         test_mkdir -c1 $DIR/$tdir
16877         cp /etc/hosts $DIR/$tdir/$tfile
16878         test_mkdir -c1 $DIR/$tdir/foo1
16879         test_mkdir -c1 $DIR/$tdir/foo2
16880         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16881         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16882         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16883         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16884         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16885         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16886                 $LFS fid2path $DIR $FID
16887                 error "bad link ea"
16888         fi
16889         # middle
16890         rm $DIR/$tdir/foo2/zachary
16891         # last
16892         rm $DIR/$tdir/foo2/thor
16893         # first
16894         rm $DIR/$tdir/$tfile
16895         # rename
16896         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16897         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16898                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16899         rm $DIR/$tdir/foo2/maggie
16900
16901         # overflow the EA
16902         local longname=$tfile.avg_len_is_thirty_two_
16903         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16904                 error_noexit 'failed to unlink many hardlinks'" EXIT
16905         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16906                 error "failed to hardlink many files"
16907         links=$($LFS fid2path $DIR $FID | wc -l)
16908         echo -n "${links}/1000 links in link EA"
16909         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16910 }
16911 run_test 161a "link ea sanity"
16912
16913 test_161b() {
16914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16915         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16916
16917         local MDTIDX=1
16918         local remote_dir=$DIR/$tdir/remote_dir
16919
16920         mkdir -p $DIR/$tdir
16921         $LFS mkdir -i $MDTIDX $remote_dir ||
16922                 error "create remote directory failed"
16923
16924         cp /etc/hosts $remote_dir/$tfile
16925         mkdir -p $remote_dir/foo1
16926         mkdir -p $remote_dir/foo2
16927         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16928         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16929         ln $remote_dir/$tfile $remote_dir/foo1/luna
16930         ln $remote_dir/$tfile $remote_dir/foo2/thor
16931
16932         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16933                      tr -d ']')
16934         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16935                 $LFS fid2path $DIR $FID
16936                 error "bad link ea"
16937         fi
16938         # middle
16939         rm $remote_dir/foo2/zachary
16940         # last
16941         rm $remote_dir/foo2/thor
16942         # first
16943         rm $remote_dir/$tfile
16944         # rename
16945         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16946         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16947         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16948                 $LFS fid2path $DIR $FID
16949                 error "bad link rename"
16950         fi
16951         rm $remote_dir/foo2/maggie
16952
16953         # overflow the EA
16954         local longname=filename_avg_len_is_thirty_two_
16955         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
16956                 error "failed to hardlink many files"
16957         links=$($LFS fid2path $DIR $FID | wc -l)
16958         echo -n "${links}/1000 links in link EA"
16959         [[ ${links} -gt 60 ]] ||
16960                 error "expected at least 60 links in link EA"
16961         unlinkmany $remote_dir/foo2/$longname 1000 ||
16962         error "failed to unlink many hardlinks"
16963 }
16964 run_test 161b "link ea sanity under remote directory"
16965
16966 test_161c() {
16967         remote_mds_nodsh && skip "remote MDS with nodsh"
16968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16969         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
16970                 skip "Need MDS version at least 2.1.5"
16971
16972         # define CLF_RENAME_LAST 0x0001
16973         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
16974         changelog_register || error "changelog_register failed"
16975
16976         rm -rf $DIR/$tdir
16977         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
16978         touch $DIR/$tdir/foo_161c
16979         touch $DIR/$tdir/bar_161c
16980         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16981         changelog_dump | grep RENME | tail -n 5
16982         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16983         changelog_clear 0 || error "changelog_clear failed"
16984         if [ x$flags != "x0x1" ]; then
16985                 error "flag $flags is not 0x1"
16986         fi
16987
16988         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
16989         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
16990         touch $DIR/$tdir/foo_161c
16991         touch $DIR/$tdir/bar_161c
16992         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16993         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16994         changelog_dump | grep RENME | tail -n 5
16995         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16996         changelog_clear 0 || error "changelog_clear failed"
16997         if [ x$flags != "x0x0" ]; then
16998                 error "flag $flags is not 0x0"
16999         fi
17000         echo "rename overwrite a target having nlink > 1," \
17001                 "changelog record has flags of $flags"
17002
17003         # rename doesn't overwrite a target (changelog flag 0x0)
17004         touch $DIR/$tdir/foo_161c
17005         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17006         changelog_dump | grep RENME | tail -n 5
17007         flags=$(changelog_dump | grep RENME | tail -1 | 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 doesn't overwrite a target," \
17013                 "changelog record has flags of $flags"
17014
17015         # define CLF_UNLINK_LAST 0x0001
17016         # unlink a file having nlink = 1 (changelog flag 0x1)
17017         rm -f $DIR/$tdir/foo2_161c
17018         changelog_dump | grep UNLNK | tail -n 5
17019         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17020         changelog_clear 0 || error "changelog_clear failed"
17021         if [ x$flags != "x0x1" ]; then
17022                 error "flag $flags is not 0x1"
17023         fi
17024         echo "unlink a file having nlink = 1," \
17025                 "changelog record has flags of $flags"
17026
17027         # unlink a file having nlink > 1 (changelog flag 0x0)
17028         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17029         rm -f $DIR/$tdir/foobar_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 != "x0x0" ]; then
17034                 error "flag $flags is not 0x0"
17035         fi
17036         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17037 }
17038 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17039
17040 test_161d() {
17041         remote_mds_nodsh && skip "remote MDS with nodsh"
17042         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17043
17044         local pid
17045         local fid
17046
17047         changelog_register || error "changelog_register failed"
17048
17049         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17050         # interfer with $MOUNT/.lustre/fid/ access
17051         mkdir $DIR/$tdir
17052         [[ $? -eq 0 ]] || error "mkdir failed"
17053
17054         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17055         $LCTL set_param fail_loc=0x8000140c
17056         # 5s pause
17057         $LCTL set_param fail_val=5
17058
17059         # create file
17060         echo foofoo > $DIR/$tdir/$tfile &
17061         pid=$!
17062
17063         # wait for create to be delayed
17064         sleep 2
17065
17066         ps -p $pid
17067         [[ $? -eq 0 ]] || error "create should be blocked"
17068
17069         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17070         stack_trap "rm -f $tempfile"
17071         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17072         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17073         # some delay may occur during ChangeLog publishing and file read just
17074         # above, that could allow file write to happen finally
17075         [[ -s $tempfile ]] && echo "file should be empty"
17076
17077         $LCTL set_param fail_loc=0
17078
17079         wait $pid
17080         [[ $? -eq 0 ]] || error "create failed"
17081 }
17082 run_test 161d "create with concurrent .lustre/fid access"
17083
17084 check_path() {
17085         local expected="$1"
17086         shift
17087         local fid="$2"
17088
17089         local path
17090         path=$($LFS fid2path "$@")
17091         local rc=$?
17092
17093         if [ $rc -ne 0 ]; then
17094                 error "path looked up of '$expected' failed: rc=$rc"
17095         elif [ "$path" != "$expected" ]; then
17096                 error "path looked up '$path' instead of '$expected'"
17097         else
17098                 echo "FID '$fid' resolves to path '$path' as expected"
17099         fi
17100 }
17101
17102 test_162a() { # was test_162
17103         test_mkdir -p -c1 $DIR/$tdir/d2
17104         touch $DIR/$tdir/d2/$tfile
17105         touch $DIR/$tdir/d2/x1
17106         touch $DIR/$tdir/d2/x2
17107         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17108         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17109         # regular file
17110         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17111         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17112
17113         # softlink
17114         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17115         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17116         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17117
17118         # softlink to wrong file
17119         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17120         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17121         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17122
17123         # hardlink
17124         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17125         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17126         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17127         # fid2path dir/fsname should both work
17128         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17129         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17130
17131         # hardlink count: check that there are 2 links
17132         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17133         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17134
17135         # hardlink indexing: remove the first link
17136         rm $DIR/$tdir/d2/p/q/r/hlink
17137         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17138 }
17139 run_test 162a "path lookup sanity"
17140
17141 test_162b() {
17142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17143         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17144
17145         mkdir $DIR/$tdir
17146         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17147                                 error "create striped dir failed"
17148
17149         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17150                                         tail -n 1 | awk '{print $2}')
17151         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17152
17153         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17154         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17155
17156         # regular file
17157         for ((i=0;i<5;i++)); do
17158                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17159                         error "get fid for f$i failed"
17160                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17161
17162                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17163                         error "get fid for d$i failed"
17164                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17165         done
17166
17167         return 0
17168 }
17169 run_test 162b "striped directory path lookup sanity"
17170
17171 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17172 test_162c() {
17173         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17174                 skip "Need MDS version at least 2.7.51"
17175
17176         local lpath=$tdir.local
17177         local rpath=$tdir.remote
17178
17179         test_mkdir $DIR/$lpath
17180         test_mkdir $DIR/$rpath
17181
17182         for ((i = 0; i <= 101; i++)); do
17183                 lpath="$lpath/$i"
17184                 mkdir $DIR/$lpath
17185                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17186                         error "get fid for local directory $DIR/$lpath failed"
17187                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17188
17189                 rpath="$rpath/$i"
17190                 test_mkdir $DIR/$rpath
17191                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17192                         error "get fid for remote directory $DIR/$rpath failed"
17193                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17194         done
17195
17196         return 0
17197 }
17198 run_test 162c "fid2path works with paths 100 or more directories deep"
17199
17200 oalr_event_count() {
17201         local event="${1}"
17202         local trace="${2}"
17203
17204         awk -v name="${FSNAME}-OST0000" \
17205             -v event="${event}" \
17206             '$1 == "TRACE" && $2 == event && $3 == name' \
17207             "${trace}" |
17208         wc -l
17209 }
17210
17211 oalr_expect_event_count() {
17212         local event="${1}"
17213         local trace="${2}"
17214         local expect="${3}"
17215         local count
17216
17217         count=$(oalr_event_count "${event}" "${trace}")
17218         if ((count == expect)); then
17219                 return 0
17220         fi
17221
17222         error_noexit "${event} event count was '${count}', expected ${expect}"
17223         cat "${trace}" >&2
17224         exit 1
17225 }
17226
17227 cleanup_165() {
17228         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17229         stop ost1
17230         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17231 }
17232
17233 setup_165() {
17234         sync # Flush previous IOs so we can count log entries.
17235         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17236         stack_trap cleanup_165 EXIT
17237 }
17238
17239 test_165a() {
17240         local trace="/tmp/${tfile}.trace"
17241         local rc
17242         local count
17243
17244         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17245                 skip "OFD access log unsupported"
17246
17247         setup_165
17248         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17249         sleep 5
17250
17251         do_facet ost1 ofd_access_log_reader --list
17252         stop ost1
17253
17254         do_facet ost1 killall -TERM ofd_access_log_reader
17255         wait
17256         rc=$?
17257
17258         if ((rc != 0)); then
17259                 error "ofd_access_log_reader exited with rc = '${rc}'"
17260         fi
17261
17262         # Parse trace file for discovery events:
17263         oalr_expect_event_count alr_log_add "${trace}" 1
17264         oalr_expect_event_count alr_log_eof "${trace}" 1
17265         oalr_expect_event_count alr_log_free "${trace}" 1
17266 }
17267 run_test 165a "ofd access log discovery"
17268
17269 test_165b() {
17270         local trace="/tmp/${tfile}.trace"
17271         local file="${DIR}/${tfile}"
17272         local pfid1
17273         local pfid2
17274         local -a entry
17275         local rc
17276         local count
17277         local size
17278         local flags
17279
17280         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17281                 skip "OFD access log unsupported"
17282
17283         setup_165
17284         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17285         sleep 5
17286
17287         do_facet ost1 ofd_access_log_reader --list
17288
17289         lfs setstripe -c 1 -i 0 "${file}"
17290         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17291                 error "cannot create '${file}'"
17292
17293         sleep 5
17294         do_facet ost1 killall -TERM ofd_access_log_reader
17295         wait
17296         rc=$?
17297
17298         if ((rc != 0)); then
17299                 error "ofd_access_log_reader exited with rc = '${rc}'"
17300         fi
17301
17302         oalr_expect_event_count alr_log_entry "${trace}" 1
17303
17304         pfid1=$($LFS path2fid "${file}")
17305
17306         # 1     2             3   4    5     6   7    8    9     10
17307         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17308         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17309
17310         echo "entry = '${entry[*]}'" >&2
17311
17312         pfid2=${entry[4]}
17313         if [[ "${pfid1}" != "${pfid2}" ]]; then
17314                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17315         fi
17316
17317         size=${entry[8]}
17318         if ((size != 1048576)); then
17319                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17320         fi
17321
17322         flags=${entry[10]}
17323         if [[ "${flags}" != "w" ]]; then
17324                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17325         fi
17326
17327         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17328         sleep 5
17329
17330         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17331                 error "cannot read '${file}'"
17332         sleep 5
17333
17334         do_facet ost1 killall -TERM ofd_access_log_reader
17335         wait
17336         rc=$?
17337
17338         if ((rc != 0)); then
17339                 error "ofd_access_log_reader exited with rc = '${rc}'"
17340         fi
17341
17342         oalr_expect_event_count alr_log_entry "${trace}" 1
17343
17344         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17345         echo "entry = '${entry[*]}'" >&2
17346
17347         pfid2=${entry[4]}
17348         if [[ "${pfid1}" != "${pfid2}" ]]; then
17349                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17350         fi
17351
17352         size=${entry[8]}
17353         if ((size != 524288)); then
17354                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17355         fi
17356
17357         flags=${entry[10]}
17358         if [[ "${flags}" != "r" ]]; then
17359                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17360         fi
17361 }
17362 run_test 165b "ofd access log entries are produced and consumed"
17363
17364 test_165c() {
17365         local trace="/tmp/${tfile}.trace"
17366         local file="${DIR}/${tdir}/${tfile}"
17367
17368         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17369                 skip "OFD access log unsupported"
17370
17371         test_mkdir "${DIR}/${tdir}"
17372
17373         setup_165
17374         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17375         sleep 5
17376
17377         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17378
17379         # 4096 / 64 = 64. Create twice as many entries.
17380         for ((i = 0; i < 128; i++)); do
17381                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17382                         error "cannot create file"
17383         done
17384
17385         sync
17386
17387         do_facet ost1 killall -TERM ofd_access_log_reader
17388         wait
17389         rc=$?
17390         if ((rc != 0)); then
17391                 error "ofd_access_log_reader exited with rc = '${rc}'"
17392         fi
17393
17394         unlinkmany  "${file}-%d" 128
17395 }
17396 run_test 165c "full ofd access logs do not block IOs"
17397
17398 oal_get_read_count() {
17399         local stats="$1"
17400
17401         # STATS lustre-OST0001 alr_read_count 1
17402
17403         do_facet ost1 cat "${stats}" |
17404         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17405              END { print count; }'
17406 }
17407
17408 oal_expect_read_count() {
17409         local stats="$1"
17410         local count
17411         local expect="$2"
17412
17413         # Ask ofd_access_log_reader to write stats.
17414         do_facet ost1 killall -USR1 ofd_access_log_reader
17415
17416         # Allow some time for things to happen.
17417         sleep 1
17418
17419         count=$(oal_get_read_count "${stats}")
17420         if ((count == expect)); then
17421                 return 0
17422         fi
17423
17424         error_noexit "bad read count, got ${count}, expected ${expect}"
17425         do_facet ost1 cat "${stats}" >&2
17426         exit 1
17427 }
17428
17429 test_165d() {
17430         local stats="/tmp/${tfile}.stats"
17431         local file="${DIR}/${tdir}/${tfile}"
17432         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17433
17434         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17435                 skip "OFD access log unsupported"
17436
17437         test_mkdir "${DIR}/${tdir}"
17438
17439         setup_165
17440         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17441         sleep 5
17442
17443         lfs setstripe -c 1 -i 0 "${file}"
17444
17445         do_facet ost1 lctl set_param "${param}=rw"
17446         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17447                 error "cannot create '${file}'"
17448         oal_expect_read_count "${stats}" 1
17449
17450         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17451                 error "cannot read '${file}'"
17452         oal_expect_read_count "${stats}" 2
17453
17454         do_facet ost1 lctl set_param "${param}=r"
17455         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17456                 error "cannot create '${file}'"
17457         oal_expect_read_count "${stats}" 2
17458
17459         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17460                 error "cannot read '${file}'"
17461         oal_expect_read_count "${stats}" 3
17462
17463         do_facet ost1 lctl set_param "${param}=w"
17464         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17465                 error "cannot create '${file}'"
17466         oal_expect_read_count "${stats}" 4
17467
17468         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17469                 error "cannot read '${file}'"
17470         oal_expect_read_count "${stats}" 4
17471
17472         do_facet ost1 lctl set_param "${param}=0"
17473         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17474                 error "cannot create '${file}'"
17475         oal_expect_read_count "${stats}" 4
17476
17477         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17478                 error "cannot read '${file}'"
17479         oal_expect_read_count "${stats}" 4
17480
17481         do_facet ost1 killall -TERM ofd_access_log_reader
17482         wait
17483         rc=$?
17484         if ((rc != 0)); then
17485                 error "ofd_access_log_reader exited with rc = '${rc}'"
17486         fi
17487 }
17488 run_test 165d "ofd_access_log mask works"
17489
17490 test_165e() {
17491         local stats="/tmp/${tfile}.stats"
17492         local file0="${DIR}/${tdir}-0/${tfile}"
17493         local file1="${DIR}/${tdir}-1/${tfile}"
17494
17495         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17496                 skip "OFD access log unsupported"
17497
17498         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17499
17500         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17501         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17502
17503         lfs setstripe -c 1 -i 0 "${file0}"
17504         lfs setstripe -c 1 -i 0 "${file1}"
17505
17506         setup_165
17507         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17508         sleep 5
17509
17510         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17511                 error "cannot create '${file0}'"
17512         sync
17513         oal_expect_read_count "${stats}" 0
17514
17515         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17516                 error "cannot create '${file1}'"
17517         sync
17518         oal_expect_read_count "${stats}" 1
17519
17520         do_facet ost1 killall -TERM ofd_access_log_reader
17521         wait
17522         rc=$?
17523         if ((rc != 0)); then
17524                 error "ofd_access_log_reader exited with rc = '${rc}'"
17525         fi
17526 }
17527 run_test 165e "ofd_access_log MDT index filter works"
17528
17529 test_165f() {
17530         local trace="/tmp/${tfile}.trace"
17531         local rc
17532         local count
17533
17534         setup_165
17535         do_facet ost1 timeout 60 ofd_access_log_reader \
17536                 --exit-on-close --debug=- --trace=- > "${trace}" &
17537         sleep 5
17538         stop ost1
17539
17540         wait
17541         rc=$?
17542
17543         if ((rc != 0)); then
17544                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17545                 cat "${trace}"
17546                 exit 1
17547         fi
17548 }
17549 run_test 165f "ofd_access_log_reader --exit-on-close works"
17550
17551 test_169() {
17552         # do directio so as not to populate the page cache
17553         log "creating a 10 Mb file"
17554         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17555                 error "multiop failed while creating a file"
17556         log "starting reads"
17557         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17558         log "truncating the file"
17559         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17560                 error "multiop failed while truncating the file"
17561         log "killing dd"
17562         kill %+ || true # reads might have finished
17563         echo "wait until dd is finished"
17564         wait
17565         log "removing the temporary file"
17566         rm -rf $DIR/$tfile || error "tmp file removal failed"
17567 }
17568 run_test 169 "parallel read and truncate should not deadlock"
17569
17570 test_170() {
17571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17572
17573         $LCTL clear     # bug 18514
17574         $LCTL debug_daemon start $TMP/${tfile}_log_good
17575         touch $DIR/$tfile
17576         $LCTL debug_daemon stop
17577         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17578                 error "sed failed to read log_good"
17579
17580         $LCTL debug_daemon start $TMP/${tfile}_log_good
17581         rm -rf $DIR/$tfile
17582         $LCTL debug_daemon stop
17583
17584         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17585                error "lctl df log_bad failed"
17586
17587         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17588         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17589
17590         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17591         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17592
17593         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17594                 error "bad_line good_line1 good_line2 are empty"
17595
17596         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17597         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17598         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17599
17600         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17601         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17602         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17603
17604         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17605                 error "bad_line_new good_line_new are empty"
17606
17607         local expected_good=$((good_line1 + good_line2*2))
17608
17609         rm -f $TMP/${tfile}*
17610         # LU-231, short malformed line may not be counted into bad lines
17611         if [ $bad_line -ne $bad_line_new ] &&
17612                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17613                 error "expected $bad_line bad lines, but got $bad_line_new"
17614                 return 1
17615         fi
17616
17617         if [ $expected_good -ne $good_line_new ]; then
17618                 error "expected $expected_good good lines, but got $good_line_new"
17619                 return 2
17620         fi
17621         true
17622 }
17623 run_test 170 "test lctl df to handle corrupted log ====================="
17624
17625 test_171() { # bug20592
17626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17627
17628         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17629         $LCTL set_param fail_loc=0x50e
17630         $LCTL set_param fail_val=3000
17631         multiop_bg_pause $DIR/$tfile O_s || true
17632         local MULTIPID=$!
17633         kill -USR1 $MULTIPID
17634         # cause log dump
17635         sleep 3
17636         wait $MULTIPID
17637         if dmesg | grep "recursive fault"; then
17638                 error "caught a recursive fault"
17639         fi
17640         $LCTL set_param fail_loc=0
17641         true
17642 }
17643 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17644
17645 # it would be good to share it with obdfilter-survey/iokit-libecho code
17646 setup_obdecho_osc () {
17647         local rc=0
17648         local ost_nid=$1
17649         local obdfilter_name=$2
17650         echo "Creating new osc for $obdfilter_name on $ost_nid"
17651         # make sure we can find loopback nid
17652         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17653
17654         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17655                            ${obdfilter_name}_osc_UUID || rc=2; }
17656         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17657                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17658         return $rc
17659 }
17660
17661 cleanup_obdecho_osc () {
17662         local obdfilter_name=$1
17663         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17664         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17665         return 0
17666 }
17667
17668 obdecho_test() {
17669         local OBD=$1
17670         local node=$2
17671         local pages=${3:-64}
17672         local rc=0
17673         local id
17674
17675         local count=10
17676         local obd_size=$(get_obd_size $node $OBD)
17677         local page_size=$(get_page_size $node)
17678         if [[ -n "$obd_size" ]]; then
17679                 local new_count=$((obd_size / (pages * page_size / 1024)))
17680                 [[ $new_count -ge $count ]] || count=$new_count
17681         fi
17682
17683         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17684         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17685                            rc=2; }
17686         if [ $rc -eq 0 ]; then
17687             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17688             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17689         fi
17690         echo "New object id is $id"
17691         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17692                            rc=4; }
17693         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17694                            "test_brw $count w v $pages $id" || rc=4; }
17695         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17696                            rc=4; }
17697         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17698                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17699         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17700                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17701         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17702         return $rc
17703 }
17704
17705 test_180a() {
17706         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17707
17708         if ! [ -d /sys/fs/lustre/echo_client ] &&
17709            ! module_loaded obdecho; then
17710                 load_module obdecho/obdecho &&
17711                         stack_trap "rmmod obdecho" EXIT ||
17712                         error "unable to load obdecho on client"
17713         fi
17714
17715         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17716         local host=$($LCTL get_param -n osc.$osc.import |
17717                      awk '/current_connection:/ { print $2 }' )
17718         local target=$($LCTL get_param -n osc.$osc.import |
17719                        awk '/target:/ { print $2 }' )
17720         target=${target%_UUID}
17721
17722         if [ -n "$target" ]; then
17723                 setup_obdecho_osc $host $target &&
17724                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17725                         { error "obdecho setup failed with $?"; return; }
17726
17727                 obdecho_test ${target}_osc client ||
17728                         error "obdecho_test failed on ${target}_osc"
17729         else
17730                 $LCTL get_param osc.$osc.import
17731                 error "there is no osc.$osc.import target"
17732         fi
17733 }
17734 run_test 180a "test obdecho on osc"
17735
17736 test_180b() {
17737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17738         remote_ost_nodsh && skip "remote OST with nodsh"
17739
17740         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17741                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17742                 error "failed to load module obdecho"
17743
17744         local target=$(do_facet ost1 $LCTL dl |
17745                        awk '/obdfilter/ { print $4; exit; }')
17746
17747         if [ -n "$target" ]; then
17748                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17749         else
17750                 do_facet ost1 $LCTL dl
17751                 error "there is no obdfilter target on ost1"
17752         fi
17753 }
17754 run_test 180b "test obdecho directly on obdfilter"
17755
17756 test_180c() { # LU-2598
17757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17758         remote_ost_nodsh && skip "remote OST with nodsh"
17759         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17760                 skip "Need MDS version at least 2.4.0"
17761
17762         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17763                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17764                 error "failed to load module obdecho"
17765
17766         local target=$(do_facet ost1 $LCTL dl |
17767                        awk '/obdfilter/ { print $4; exit; }')
17768
17769         if [ -n "$target" ]; then
17770                 local pages=16384 # 64MB bulk I/O RPC size
17771
17772                 obdecho_test "$target" ost1 "$pages" ||
17773                         error "obdecho_test with pages=$pages failed with $?"
17774         else
17775                 do_facet ost1 $LCTL dl
17776                 error "there is no obdfilter target on ost1"
17777         fi
17778 }
17779 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17780
17781 test_181() { # bug 22177
17782         test_mkdir $DIR/$tdir
17783         # create enough files to index the directory
17784         createmany -o $DIR/$tdir/foobar 4000
17785         # print attributes for debug purpose
17786         lsattr -d .
17787         # open dir
17788         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17789         MULTIPID=$!
17790         # remove the files & current working dir
17791         unlinkmany $DIR/$tdir/foobar 4000
17792         rmdir $DIR/$tdir
17793         kill -USR1 $MULTIPID
17794         wait $MULTIPID
17795         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17796         return 0
17797 }
17798 run_test 181 "Test open-unlinked dir ========================"
17799
17800 test_182() {
17801         local fcount=1000
17802         local tcount=10
17803
17804         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17805
17806         $LCTL set_param mdc.*.rpc_stats=clear
17807
17808         for (( i = 0; i < $tcount; i++ )) ; do
17809                 mkdir $DIR/$tdir/$i
17810         done
17811
17812         for (( i = 0; i < $tcount; i++ )) ; do
17813                 createmany -o $DIR/$tdir/$i/f- $fcount &
17814         done
17815         wait
17816
17817         for (( i = 0; i < $tcount; i++ )) ; do
17818                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17819         done
17820         wait
17821
17822         $LCTL get_param mdc.*.rpc_stats
17823
17824         rm -rf $DIR/$tdir
17825 }
17826 run_test 182 "Test parallel modify metadata operations ================"
17827
17828 test_183() { # LU-2275
17829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17830         remote_mds_nodsh && skip "remote MDS with nodsh"
17831         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17832                 skip "Need MDS version at least 2.3.56"
17833
17834         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17835         echo aaa > $DIR/$tdir/$tfile
17836
17837 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17838         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17839
17840         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17841         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17842
17843         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17844
17845         # Flush negative dentry cache
17846         touch $DIR/$tdir/$tfile
17847
17848         # We are not checking for any leaked references here, they'll
17849         # become evident next time we do cleanup with module unload.
17850         rm -rf $DIR/$tdir
17851 }
17852 run_test 183 "No crash or request leak in case of strange dispositions ========"
17853
17854 # test suite 184 is for LU-2016, LU-2017
17855 test_184a() {
17856         check_swap_layouts_support
17857
17858         dir0=$DIR/$tdir/$testnum
17859         test_mkdir -p -c1 $dir0
17860         ref1=/etc/passwd
17861         ref2=/etc/group
17862         file1=$dir0/f1
17863         file2=$dir0/f2
17864         $LFS setstripe -c1 $file1
17865         cp $ref1 $file1
17866         $LFS setstripe -c2 $file2
17867         cp $ref2 $file2
17868         gen1=$($LFS getstripe -g $file1)
17869         gen2=$($LFS getstripe -g $file2)
17870
17871         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17872         gen=$($LFS getstripe -g $file1)
17873         [[ $gen1 != $gen ]] ||
17874                 error "Layout generation on $file1 does not change"
17875         gen=$($LFS getstripe -g $file2)
17876         [[ $gen2 != $gen ]] ||
17877                 error "Layout generation on $file2 does not change"
17878
17879         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17880         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17881
17882         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17883 }
17884 run_test 184a "Basic layout swap"
17885
17886 test_184b() {
17887         check_swap_layouts_support
17888
17889         dir0=$DIR/$tdir/$testnum
17890         mkdir -p $dir0 || error "creating dir $dir0"
17891         file1=$dir0/f1
17892         file2=$dir0/f2
17893         file3=$dir0/f3
17894         dir1=$dir0/d1
17895         dir2=$dir0/d2
17896         mkdir $dir1 $dir2
17897         $LFS setstripe -c1 $file1
17898         $LFS setstripe -c2 $file2
17899         $LFS setstripe -c1 $file3
17900         chown $RUNAS_ID $file3
17901         gen1=$($LFS getstripe -g $file1)
17902         gen2=$($LFS getstripe -g $file2)
17903
17904         $LFS swap_layouts $dir1 $dir2 &&
17905                 error "swap of directories layouts should fail"
17906         $LFS swap_layouts $dir1 $file1 &&
17907                 error "swap of directory and file layouts should fail"
17908         $RUNAS $LFS swap_layouts $file1 $file2 &&
17909                 error "swap of file we cannot write should fail"
17910         $LFS swap_layouts $file1 $file3 &&
17911                 error "swap of file with different owner should fail"
17912         /bin/true # to clear error code
17913 }
17914 run_test 184b "Forbidden layout swap (will generate errors)"
17915
17916 test_184c() {
17917         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
17918         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
17919         check_swap_layouts_support
17920         check_swap_layout_no_dom $DIR
17921
17922         local dir0=$DIR/$tdir/$testnum
17923         mkdir -p $dir0 || error "creating dir $dir0"
17924
17925         local ref1=$dir0/ref1
17926         local ref2=$dir0/ref2
17927         local file1=$dir0/file1
17928         local file2=$dir0/file2
17929         # create a file large enough for the concurrent test
17930         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
17931         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
17932         echo "ref file size: ref1($(stat -c %s $ref1))," \
17933              "ref2($(stat -c %s $ref2))"
17934
17935         cp $ref2 $file2
17936         dd if=$ref1 of=$file1 bs=16k &
17937         local DD_PID=$!
17938
17939         # Make sure dd starts to copy file, but wait at most 5 seconds
17940         local loops=0
17941         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
17942
17943         $LFS swap_layouts $file1 $file2
17944         local rc=$?
17945         wait $DD_PID
17946         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
17947         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
17948
17949         # how many bytes copied before swapping layout
17950         local copied=$(stat -c %s $file2)
17951         local remaining=$(stat -c %s $ref1)
17952         remaining=$((remaining - copied))
17953         echo "Copied $copied bytes before swapping layout..."
17954
17955         cmp -n $copied $file1 $ref2 | grep differ &&
17956                 error "Content mismatch [0, $copied) of ref2 and file1"
17957         cmp -n $copied $file2 $ref1 ||
17958                 error "Content mismatch [0, $copied) of ref1 and file2"
17959         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
17960                 error "Content mismatch [$copied, EOF) of ref1 and file1"
17961
17962         # clean up
17963         rm -f $ref1 $ref2 $file1 $file2
17964 }
17965 run_test 184c "Concurrent write and layout swap"
17966
17967 test_184d() {
17968         check_swap_layouts_support
17969         check_swap_layout_no_dom $DIR
17970         [ -z "$(which getfattr 2>/dev/null)" ] &&
17971                 skip_env "no getfattr command"
17972
17973         local file1=$DIR/$tdir/$tfile-1
17974         local file2=$DIR/$tdir/$tfile-2
17975         local file3=$DIR/$tdir/$tfile-3
17976         local lovea1
17977         local lovea2
17978
17979         mkdir -p $DIR/$tdir
17980         touch $file1 || error "create $file1 failed"
17981         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17982                 error "create $file2 failed"
17983         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17984                 error "create $file3 failed"
17985         lovea1=$(get_layout_param $file1)
17986
17987         $LFS swap_layouts $file2 $file3 ||
17988                 error "swap $file2 $file3 layouts failed"
17989         $LFS swap_layouts $file1 $file2 ||
17990                 error "swap $file1 $file2 layouts failed"
17991
17992         lovea2=$(get_layout_param $file2)
17993         echo "$lovea1"
17994         echo "$lovea2"
17995         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
17996
17997         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17998         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
17999 }
18000 run_test 184d "allow stripeless layouts swap"
18001
18002 test_184e() {
18003         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18004                 skip "Need MDS version at least 2.6.94"
18005         check_swap_layouts_support
18006         check_swap_layout_no_dom $DIR
18007         [ -z "$(which getfattr 2>/dev/null)" ] &&
18008                 skip_env "no getfattr command"
18009
18010         local file1=$DIR/$tdir/$tfile-1
18011         local file2=$DIR/$tdir/$tfile-2
18012         local file3=$DIR/$tdir/$tfile-3
18013         local lovea
18014
18015         mkdir -p $DIR/$tdir
18016         touch $file1 || error "create $file1 failed"
18017         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18018                 error "create $file2 failed"
18019         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18020                 error "create $file3 failed"
18021
18022         $LFS swap_layouts $file1 $file2 ||
18023                 error "swap $file1 $file2 layouts failed"
18024
18025         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18026         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18027
18028         echo 123 > $file1 || error "Should be able to write into $file1"
18029
18030         $LFS swap_layouts $file1 $file3 ||
18031                 error "swap $file1 $file3 layouts failed"
18032
18033         echo 123 > $file1 || error "Should be able to write into $file1"
18034
18035         rm -rf $file1 $file2 $file3
18036 }
18037 run_test 184e "Recreate layout after stripeless layout swaps"
18038
18039 test_184f() {
18040         # Create a file with name longer than sizeof(struct stat) ==
18041         # 144 to see if we can get chars from the file name to appear
18042         # in the returned striping. Note that 'f' == 0x66.
18043         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18044
18045         mkdir -p $DIR/$tdir
18046         mcreate $DIR/$tdir/$file
18047         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18048                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18049         fi
18050 }
18051 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18052
18053 test_185() { # LU-2441
18054         # LU-3553 - no volatile file support in old servers
18055         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18056                 skip "Need MDS version at least 2.3.60"
18057
18058         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18059         touch $DIR/$tdir/spoo
18060         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18061         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18062                 error "cannot create/write a volatile file"
18063         [ "$FILESET" == "" ] &&
18064         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18065                 error "FID is still valid after close"
18066
18067         multiop_bg_pause $DIR/$tdir vVw4096_c
18068         local multi_pid=$!
18069
18070         local OLD_IFS=$IFS
18071         IFS=":"
18072         local fidv=($fid)
18073         IFS=$OLD_IFS
18074         # assume that the next FID for this client is sequential, since stdout
18075         # is unfortunately eaten by multiop_bg_pause
18076         local n=$((${fidv[1]} + 1))
18077         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18078         if [ "$FILESET" == "" ]; then
18079                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18080                         error "FID is missing before close"
18081         fi
18082         kill -USR1 $multi_pid
18083         # 1 second delay, so if mtime change we will see it
18084         sleep 1
18085         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18086         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18087 }
18088 run_test 185 "Volatile file support"
18089
18090 function create_check_volatile() {
18091         local idx=$1
18092         local tgt
18093
18094         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18095         local PID=$!
18096         sleep 1
18097         local FID=$(cat /tmp/${tfile}.fid)
18098         [ "$FID" == "" ] && error "can't get FID for volatile"
18099         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18100         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18101         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18102         kill -USR1 $PID
18103         wait
18104         sleep 1
18105         cancel_lru_locks mdc # flush opencache
18106         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18107         return 0
18108 }
18109
18110 test_185a(){
18111         # LU-12516 - volatile creation via .lustre
18112         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18113                 skip "Need MDS version at least 2.3.55"
18114
18115         create_check_volatile 0
18116         [ $MDSCOUNT -lt 2 ] && return 0
18117
18118         # DNE case
18119         create_check_volatile 1
18120
18121         return 0
18122 }
18123 run_test 185a "Volatile file creation in .lustre/fid/"
18124
18125 test_187a() {
18126         remote_mds_nodsh && skip "remote MDS with nodsh"
18127         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18128                 skip "Need MDS version at least 2.3.0"
18129
18130         local dir0=$DIR/$tdir/$testnum
18131         mkdir -p $dir0 || error "creating dir $dir0"
18132
18133         local file=$dir0/file1
18134         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18135         local dv1=$($LFS data_version $file)
18136         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18137         local dv2=$($LFS data_version $file)
18138         [[ $dv1 != $dv2 ]] ||
18139                 error "data version did not change on write $dv1 == $dv2"
18140
18141         # clean up
18142         rm -f $file1
18143 }
18144 run_test 187a "Test data version change"
18145
18146 test_187b() {
18147         remote_mds_nodsh && skip "remote MDS with nodsh"
18148         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18149                 skip "Need MDS version at least 2.3.0"
18150
18151         local dir0=$DIR/$tdir/$testnum
18152         mkdir -p $dir0 || error "creating dir $dir0"
18153
18154         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18155         [[ ${DV[0]} != ${DV[1]} ]] ||
18156                 error "data version did not change on write"\
18157                       " ${DV[0]} == ${DV[1]}"
18158
18159         # clean up
18160         rm -f $file1
18161 }
18162 run_test 187b "Test data version change on volatile file"
18163
18164 test_200() {
18165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18166         remote_mgs_nodsh && skip "remote MGS with nodsh"
18167         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18168
18169         local POOL=${POOL:-cea1}
18170         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18171         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18172         # Pool OST targets
18173         local first_ost=0
18174         local last_ost=$(($OSTCOUNT - 1))
18175         local ost_step=2
18176         local ost_list=$(seq $first_ost $ost_step $last_ost)
18177         local ost_range="$first_ost $last_ost $ost_step"
18178         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18179         local file_dir=$POOL_ROOT/file_tst
18180         local subdir=$test_path/subdir
18181         local rc=0
18182
18183         while : ; do
18184                 # former test_200a test_200b
18185                 pool_add $POOL                          || { rc=$? ; break; }
18186                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18187                 # former test_200c test_200d
18188                 mkdir -p $test_path
18189                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18190                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18191                 mkdir -p $subdir
18192                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18193                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18194                                                         || { rc=$? ; break; }
18195                 # former test_200e test_200f
18196                 local files=$((OSTCOUNT*3))
18197                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18198                                                         || { rc=$? ; break; }
18199                 pool_create_files $POOL $file_dir $files "$ost_list" \
18200                                                         || { rc=$? ; break; }
18201                 # former test_200g test_200h
18202                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18203                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18204
18205                 # former test_201a test_201b test_201c
18206                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18207
18208                 local f=$test_path/$tfile
18209                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18210                 pool_remove $POOL $f                    || { rc=$? ; break; }
18211                 break
18212         done
18213
18214         destroy_test_pools
18215
18216         return $rc
18217 }
18218 run_test 200 "OST pools"
18219
18220 # usage: default_attr <count | size | offset>
18221 default_attr() {
18222         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18223 }
18224
18225 # usage: check_default_stripe_attr
18226 check_default_stripe_attr() {
18227         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18228         case $1 in
18229         --stripe-count|-c)
18230                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18231         --stripe-size|-S)
18232                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18233         --stripe-index|-i)
18234                 EXPECTED=-1;;
18235         *)
18236                 error "unknown getstripe attr '$1'"
18237         esac
18238
18239         [ $ACTUAL == $EXPECTED ] ||
18240                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18241 }
18242
18243 test_204a() {
18244         test_mkdir $DIR/$tdir
18245         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18246
18247         check_default_stripe_attr --stripe-count
18248         check_default_stripe_attr --stripe-size
18249         check_default_stripe_attr --stripe-index
18250 }
18251 run_test 204a "Print default stripe attributes"
18252
18253 test_204b() {
18254         test_mkdir $DIR/$tdir
18255         $LFS setstripe --stripe-count 1 $DIR/$tdir
18256
18257         check_default_stripe_attr --stripe-size
18258         check_default_stripe_attr --stripe-index
18259 }
18260 run_test 204b "Print default stripe size and offset"
18261
18262 test_204c() {
18263         test_mkdir $DIR/$tdir
18264         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18265
18266         check_default_stripe_attr --stripe-count
18267         check_default_stripe_attr --stripe-index
18268 }
18269 run_test 204c "Print default stripe count and offset"
18270
18271 test_204d() {
18272         test_mkdir $DIR/$tdir
18273         $LFS setstripe --stripe-index 0 $DIR/$tdir
18274
18275         check_default_stripe_attr --stripe-count
18276         check_default_stripe_attr --stripe-size
18277 }
18278 run_test 204d "Print default stripe count and size"
18279
18280 test_204e() {
18281         test_mkdir $DIR/$tdir
18282         $LFS setstripe -d $DIR/$tdir
18283
18284         check_default_stripe_attr --stripe-count --raw
18285         check_default_stripe_attr --stripe-size --raw
18286         check_default_stripe_attr --stripe-index --raw
18287 }
18288 run_test 204e "Print raw stripe attributes"
18289
18290 test_204f() {
18291         test_mkdir $DIR/$tdir
18292         $LFS setstripe --stripe-count 1 $DIR/$tdir
18293
18294         check_default_stripe_attr --stripe-size --raw
18295         check_default_stripe_attr --stripe-index --raw
18296 }
18297 run_test 204f "Print raw stripe size and offset"
18298
18299 test_204g() {
18300         test_mkdir $DIR/$tdir
18301         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18302
18303         check_default_stripe_attr --stripe-count --raw
18304         check_default_stripe_attr --stripe-index --raw
18305 }
18306 run_test 204g "Print raw stripe count and offset"
18307
18308 test_204h() {
18309         test_mkdir $DIR/$tdir
18310         $LFS setstripe --stripe-index 0 $DIR/$tdir
18311
18312         check_default_stripe_attr --stripe-count --raw
18313         check_default_stripe_attr --stripe-size --raw
18314 }
18315 run_test 204h "Print raw stripe count and size"
18316
18317 # Figure out which job scheduler is being used, if any,
18318 # or use a fake one
18319 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18320         JOBENV=SLURM_JOB_ID
18321 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18322         JOBENV=LSB_JOBID
18323 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18324         JOBENV=PBS_JOBID
18325 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18326         JOBENV=LOADL_STEP_ID
18327 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18328         JOBENV=JOB_ID
18329 else
18330         $LCTL list_param jobid_name > /dev/null 2>&1
18331         if [ $? -eq 0 ]; then
18332                 JOBENV=nodelocal
18333         else
18334                 JOBENV=FAKE_JOBID
18335         fi
18336 fi
18337 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18338
18339 verify_jobstats() {
18340         local cmd=($1)
18341         shift
18342         local facets="$@"
18343
18344 # we don't really need to clear the stats for this test to work, since each
18345 # command has a unique jobid, but it makes debugging easier if needed.
18346 #       for facet in $facets; do
18347 #               local dev=$(convert_facet2label $facet)
18348 #               # clear old jobstats
18349 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18350 #       done
18351
18352         # use a new JobID for each test, or we might see an old one
18353         [ "$JOBENV" = "FAKE_JOBID" ] &&
18354                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18355
18356         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18357
18358         [ "$JOBENV" = "nodelocal" ] && {
18359                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18360                 $LCTL set_param jobid_name=$FAKE_JOBID
18361                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18362         }
18363
18364         log "Test: ${cmd[*]}"
18365         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18366
18367         if [ $JOBENV = "FAKE_JOBID" ]; then
18368                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18369         else
18370                 ${cmd[*]}
18371         fi
18372
18373         # all files are created on OST0000
18374         for facet in $facets; do
18375                 local stats="*.$(convert_facet2label $facet).job_stats"
18376
18377                 # strip out libtool wrappers for in-tree executables
18378                 if (( $(do_facet $facet lctl get_param $stats |
18379                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18380                         do_facet $facet lctl get_param $stats
18381                         error "No jobstats for $JOBVAL found on $facet::$stats"
18382                 fi
18383         done
18384 }
18385
18386 jobstats_set() {
18387         local new_jobenv=$1
18388
18389         set_persistent_param_and_check client "jobid_var" \
18390                 "$FSNAME.sys.jobid_var" $new_jobenv
18391 }
18392
18393 test_205a() { # Job stats
18394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18395         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18396                 skip "Need MDS version with at least 2.7.1"
18397         remote_mgs_nodsh && skip "remote MGS with nodsh"
18398         remote_mds_nodsh && skip "remote MDS with nodsh"
18399         remote_ost_nodsh && skip "remote OST with nodsh"
18400         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18401                 skip "Server doesn't support jobstats"
18402         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18403
18404         local old_jobenv=$($LCTL get_param -n jobid_var)
18405         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18406
18407         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18408                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18409         else
18410                 stack_trap "do_facet mgs $PERM_CMD \
18411                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18412         fi
18413         changelog_register
18414
18415         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18416                                 mdt.*.job_cleanup_interval | head -n 1)
18417         local new_interval=5
18418         do_facet $SINGLEMDS \
18419                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18420         stack_trap "do_facet $SINGLEMDS \
18421                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18422         local start=$SECONDS
18423
18424         local cmd
18425         # mkdir
18426         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18427         verify_jobstats "$cmd" "$SINGLEMDS"
18428         # rmdir
18429         cmd="rmdir $DIR/$tdir"
18430         verify_jobstats "$cmd" "$SINGLEMDS"
18431         # mkdir on secondary MDT
18432         if [ $MDSCOUNT -gt 1 ]; then
18433                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18434                 verify_jobstats "$cmd" "mds2"
18435         fi
18436         # mknod
18437         cmd="mknod $DIR/$tfile c 1 3"
18438         verify_jobstats "$cmd" "$SINGLEMDS"
18439         # unlink
18440         cmd="rm -f $DIR/$tfile"
18441         verify_jobstats "$cmd" "$SINGLEMDS"
18442         # create all files on OST0000 so verify_jobstats can find OST stats
18443         # open & close
18444         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18445         verify_jobstats "$cmd" "$SINGLEMDS"
18446         # setattr
18447         cmd="touch $DIR/$tfile"
18448         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18449         # write
18450         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18451         verify_jobstats "$cmd" "ost1"
18452         # read
18453         cancel_lru_locks osc
18454         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18455         verify_jobstats "$cmd" "ost1"
18456         # truncate
18457         cmd="$TRUNCATE $DIR/$tfile 0"
18458         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18459         # rename
18460         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18461         verify_jobstats "$cmd" "$SINGLEMDS"
18462         # jobstats expiry - sleep until old stats should be expired
18463         local left=$((new_interval + 5 - (SECONDS - start)))
18464         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18465                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18466                         "0" $left
18467         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18468         verify_jobstats "$cmd" "$SINGLEMDS"
18469         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18470             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18471
18472         # Ensure that jobid are present in changelog (if supported by MDS)
18473         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18474                 changelog_dump | tail -10
18475                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18476                 [ $jobids -eq 9 ] ||
18477                         error "Wrong changelog jobid count $jobids != 9"
18478
18479                 # LU-5862
18480                 JOBENV="disable"
18481                 jobstats_set $JOBENV
18482                 touch $DIR/$tfile
18483                 changelog_dump | grep $tfile
18484                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18485                 [ $jobids -eq 0 ] ||
18486                         error "Unexpected jobids when jobid_var=$JOBENV"
18487         fi
18488
18489         # test '%j' access to environment variable - if supported
18490         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18491                 JOBENV="JOBCOMPLEX"
18492                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18493
18494                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18495         fi
18496
18497         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18498                 JOBENV="JOBCOMPLEX"
18499                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18500
18501                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18502         fi
18503
18504         # test '%j' access to per-session jobid - if supported
18505         if lctl list_param jobid_this_session > /dev/null 2>&1
18506         then
18507                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18508                 lctl set_param jobid_this_session=$USER
18509
18510                 JOBENV="JOBCOMPLEX"
18511                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18512
18513                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18514         fi
18515 }
18516 run_test 205a "Verify job stats"
18517
18518 # LU-13117, LU-13597
18519 test_205b() {
18520         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18521                 skip "Need MDS version at least 2.13.54.91"
18522
18523         job_stats="mdt.*.job_stats"
18524         $LCTL set_param $job_stats=clear
18525         # Setting jobid_var to USER might not be supported
18526         $LCTL set_param jobid_var=USER || true
18527         $LCTL set_param jobid_name="%e.%u"
18528         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18529         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18530                 grep "job_id:.*foolish" &&
18531                         error "Unexpected jobid found"
18532         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18533                 grep "open:.*min.*max.*sum" ||
18534                         error "wrong job_stats format found"
18535 }
18536 run_test 205b "Verify job stats jobid and output format"
18537
18538 # LU-13733
18539 test_205c() {
18540         $LCTL set_param llite.*.stats=0
18541         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18542         $LCTL get_param llite.*.stats
18543         $LCTL get_param llite.*.stats | grep \
18544                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18545                         error "wrong client stats format found"
18546 }
18547 run_test 205c "Verify client stats format"
18548
18549 # LU-1480, LU-1773 and LU-1657
18550 test_206() {
18551         mkdir -p $DIR/$tdir
18552         $LFS setstripe -c -1 $DIR/$tdir
18553 #define OBD_FAIL_LOV_INIT 0x1403
18554         $LCTL set_param fail_loc=0xa0001403
18555         $LCTL set_param fail_val=1
18556         touch $DIR/$tdir/$tfile || true
18557 }
18558 run_test 206 "fail lov_init_raid0() doesn't lbug"
18559
18560 test_207a() {
18561         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18562         local fsz=`stat -c %s $DIR/$tfile`
18563         cancel_lru_locks mdc
18564
18565         # do not return layout in getattr intent
18566 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18567         $LCTL set_param fail_loc=0x170
18568         local sz=`stat -c %s $DIR/$tfile`
18569
18570         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18571
18572         rm -rf $DIR/$tfile
18573 }
18574 run_test 207a "can refresh layout at glimpse"
18575
18576 test_207b() {
18577         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18578         local cksum=`md5sum $DIR/$tfile`
18579         local fsz=`stat -c %s $DIR/$tfile`
18580         cancel_lru_locks mdc
18581         cancel_lru_locks osc
18582
18583         # do not return layout in getattr intent
18584 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18585         $LCTL set_param fail_loc=0x171
18586
18587         # it will refresh layout after the file is opened but before read issues
18588         echo checksum is "$cksum"
18589         echo "$cksum" |md5sum -c --quiet || error "file differs"
18590
18591         rm -rf $DIR/$tfile
18592 }
18593 run_test 207b "can refresh layout at open"
18594
18595 test_208() {
18596         # FIXME: in this test suite, only RD lease is used. This is okay
18597         # for now as only exclusive open is supported. After generic lease
18598         # is done, this test suite should be revised. - Jinshan
18599
18600         remote_mds_nodsh && skip "remote MDS with nodsh"
18601         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18602                 skip "Need MDS version at least 2.4.52"
18603
18604         echo "==== test 1: verify get lease work"
18605         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18606
18607         echo "==== test 2: verify lease can be broken by upcoming open"
18608         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18609         local PID=$!
18610         sleep 2
18611
18612         $MULTIOP $DIR/$tfile oO_RDWR:c
18613         kill -USR1 $PID && wait $PID || error "break lease error"
18614
18615         echo "==== test 3: verify lease can't be granted if an open already exists"
18616         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18617         local PID=$!
18618         sleep 2
18619
18620         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18621         kill -USR1 $PID && wait $PID || error "open file error"
18622
18623         echo "==== test 4: lease can sustain over recovery"
18624         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18625         PID=$!
18626         sleep 2
18627
18628         fail mds1
18629
18630         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18631
18632         echo "==== test 5: lease broken can't be regained by replay"
18633         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18634         PID=$!
18635         sleep 2
18636
18637         # open file to break lease and then recovery
18638         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18639         fail mds1
18640
18641         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18642
18643         rm -f $DIR/$tfile
18644 }
18645 run_test 208 "Exclusive open"
18646
18647 test_209() {
18648         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18649                 skip_env "must have disp_stripe"
18650
18651         touch $DIR/$tfile
18652         sync; sleep 5; sync;
18653
18654         echo 3 > /proc/sys/vm/drop_caches
18655         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18656                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18657         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18658
18659         # open/close 500 times
18660         for i in $(seq 500); do
18661                 cat $DIR/$tfile
18662         done
18663
18664         echo 3 > /proc/sys/vm/drop_caches
18665         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18666                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18667         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18668
18669         echo "before: $req_before, after: $req_after"
18670         [ $((req_after - req_before)) -ge 300 ] &&
18671                 error "open/close requests are not freed"
18672         return 0
18673 }
18674 run_test 209 "read-only open/close requests should be freed promptly"
18675
18676 test_210() {
18677         local pid
18678
18679         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18680         pid=$!
18681         sleep 1
18682
18683         $LFS getstripe $DIR/$tfile
18684         kill -USR1 $pid
18685         wait $pid || error "multiop failed"
18686
18687         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18688         pid=$!
18689         sleep 1
18690
18691         $LFS getstripe $DIR/$tfile
18692         kill -USR1 $pid
18693         wait $pid || error "multiop failed"
18694 }
18695 run_test 210 "lfs getstripe does not break leases"
18696
18697 test_212() {
18698         size=`date +%s`
18699         size=$((size % 8192 + 1))
18700         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18701         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18702         rm -f $DIR/f212 $DIR/f212.xyz
18703 }
18704 run_test 212 "Sendfile test ============================================"
18705
18706 test_213() {
18707         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18708         cancel_lru_locks osc
18709         lctl set_param fail_loc=0x8000040f
18710         # generate a read lock
18711         cat $DIR/$tfile > /dev/null
18712         # write to the file, it will try to cancel the above read lock.
18713         cat /etc/hosts >> $DIR/$tfile
18714 }
18715 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18716
18717 test_214() { # for bug 20133
18718         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18719         for (( i=0; i < 340; i++ )) ; do
18720                 touch $DIR/$tdir/d214c/a$i
18721         done
18722
18723         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18724         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18725         ls $DIR/d214c || error "ls $DIR/d214c failed"
18726         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18727         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18728 }
18729 run_test 214 "hash-indexed directory test - bug 20133"
18730
18731 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18732 create_lnet_proc_files() {
18733         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18734 }
18735
18736 # counterpart of create_lnet_proc_files
18737 remove_lnet_proc_files() {
18738         rm -f $TMP/lnet_$1.sys
18739 }
18740
18741 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18742 # 3rd arg as regexp for body
18743 check_lnet_proc_stats() {
18744         local l=$(cat "$TMP/lnet_$1" |wc -l)
18745         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18746
18747         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18748 }
18749
18750 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18751 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18752 # optional and can be regexp for 2nd line (lnet.routes case)
18753 check_lnet_proc_entry() {
18754         local blp=2          # blp stands for 'position of 1st line of body'
18755         [ -z "$5" ] || blp=3 # lnet.routes case
18756
18757         local l=$(cat "$TMP/lnet_$1" |wc -l)
18758         # subtracting one from $blp because the body can be empty
18759         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18760
18761         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18762                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18763
18764         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18765                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18766
18767         # bail out if any unexpected line happened
18768         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18769         [ "$?" != 0 ] || error "$2 misformatted"
18770 }
18771
18772 test_215() { # for bugs 18102, 21079, 21517
18773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18774
18775         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18776         local P='[1-9][0-9]*'           # positive numeric
18777         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18778         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18779         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18780         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18781
18782         local L1 # regexp for 1st line
18783         local L2 # regexp for 2nd line (optional)
18784         local BR # regexp for the rest (body)
18785
18786         # lnet.stats should look as 11 space-separated non-negative numerics
18787         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18788         create_lnet_proc_files "stats"
18789         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18790         remove_lnet_proc_files "stats"
18791
18792         # lnet.routes should look like this:
18793         # Routing disabled/enabled
18794         # net hops priority state router
18795         # where net is a string like tcp0, hops > 0, priority >= 0,
18796         # state is up/down,
18797         # router is a string like 192.168.1.1@tcp2
18798         L1="^Routing (disabled|enabled)$"
18799         L2="^net +hops +priority +state +router$"
18800         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18801         create_lnet_proc_files "routes"
18802         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18803         remove_lnet_proc_files "routes"
18804
18805         # lnet.routers should look like this:
18806         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18807         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18808         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18809         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18810         L1="^ref +rtr_ref +alive +router$"
18811         BR="^$P +$P +(up|down) +$NID$"
18812         create_lnet_proc_files "routers"
18813         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18814         remove_lnet_proc_files "routers"
18815
18816         # lnet.peers should look like this:
18817         # nid refs state last max rtr min tx min queue
18818         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18819         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18820         # numeric (0 or >0 or <0), queue >= 0.
18821         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18822         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18823         create_lnet_proc_files "peers"
18824         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18825         remove_lnet_proc_files "peers"
18826
18827         # lnet.buffers  should look like this:
18828         # pages count credits min
18829         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18830         L1="^pages +count +credits +min$"
18831         BR="^ +$N +$N +$I +$I$"
18832         create_lnet_proc_files "buffers"
18833         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18834         remove_lnet_proc_files "buffers"
18835
18836         # lnet.nis should look like this:
18837         # nid status alive refs peer rtr max tx min
18838         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18839         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18840         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18841         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18842         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18843         create_lnet_proc_files "nis"
18844         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18845         remove_lnet_proc_files "nis"
18846
18847         # can we successfully write to lnet.stats?
18848         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18849 }
18850 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18851
18852 test_216() { # bug 20317
18853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18854         remote_ost_nodsh && skip "remote OST with nodsh"
18855
18856         local node
18857         local facets=$(get_facets OST)
18858         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18859
18860         save_lustre_params client "osc.*.contention_seconds" > $p
18861         save_lustre_params $facets \
18862                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18863         save_lustre_params $facets \
18864                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18865         save_lustre_params $facets \
18866                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18867         clear_stats osc.*.osc_stats
18868
18869         # agressive lockless i/o settings
18870         do_nodes $(comma_list $(osts_nodes)) \
18871                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18872                         ldlm.namespaces.filter-*.contended_locks=0 \
18873                         ldlm.namespaces.filter-*.contention_seconds=60"
18874         lctl set_param -n osc.*.contention_seconds=60
18875
18876         $DIRECTIO write $DIR/$tfile 0 10 4096
18877         $CHECKSTAT -s 40960 $DIR/$tfile
18878
18879         # disable lockless i/o
18880         do_nodes $(comma_list $(osts_nodes)) \
18881                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18882                         ldlm.namespaces.filter-*.contended_locks=32 \
18883                         ldlm.namespaces.filter-*.contention_seconds=0"
18884         lctl set_param -n osc.*.contention_seconds=0
18885         clear_stats osc.*.osc_stats
18886
18887         dd if=/dev/zero of=$DIR/$tfile count=0
18888         $CHECKSTAT -s 0 $DIR/$tfile
18889
18890         restore_lustre_params <$p
18891         rm -f $p
18892         rm $DIR/$tfile
18893 }
18894 run_test 216 "check lockless direct write updates file size and kms correctly"
18895
18896 test_217() { # bug 22430
18897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18898
18899         local node
18900         local nid
18901
18902         for node in $(nodes_list); do
18903                 nid=$(host_nids_address $node $NETTYPE)
18904                 if [[ $nid = *-* ]] ; then
18905                         echo "lctl ping $(h2nettype $nid)"
18906                         lctl ping $(h2nettype $nid)
18907                 else
18908                         echo "skipping $node (no hyphen detected)"
18909                 fi
18910         done
18911 }
18912 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18913
18914 test_218() {
18915        # do directio so as not to populate the page cache
18916        log "creating a 10 Mb file"
18917        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
18918        log "starting reads"
18919        dd if=$DIR/$tfile of=/dev/null bs=4096 &
18920        log "truncating the file"
18921        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
18922        log "killing dd"
18923        kill %+ || true # reads might have finished
18924        echo "wait until dd is finished"
18925        wait
18926        log "removing the temporary file"
18927        rm -rf $DIR/$tfile || error "tmp file removal failed"
18928 }
18929 run_test 218 "parallel read and truncate should not deadlock"
18930
18931 test_219() {
18932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18933
18934         # write one partial page
18935         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
18936         # set no grant so vvp_io_commit_write will do sync write
18937         $LCTL set_param fail_loc=0x411
18938         # write a full page at the end of file
18939         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
18940
18941         $LCTL set_param fail_loc=0
18942         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
18943         $LCTL set_param fail_loc=0x411
18944         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
18945
18946         # LU-4201
18947         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
18948         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
18949 }
18950 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
18951
18952 test_220() { #LU-325
18953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18954         remote_ost_nodsh && skip "remote OST with nodsh"
18955         remote_mds_nodsh && skip "remote MDS with nodsh"
18956         remote_mgs_nodsh && skip "remote MGS with nodsh"
18957
18958         local OSTIDX=0
18959
18960         # create on MDT0000 so the last_id and next_id are correct
18961         mkdir_on_mdt0 $DIR/$tdir
18962         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
18963         OST=${OST%_UUID}
18964
18965         # on the mdt's osc
18966         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
18967         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
18968                         osp.$mdtosc_proc1.prealloc_last_id)
18969         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
18970                         osp.$mdtosc_proc1.prealloc_next_id)
18971
18972         $LFS df -i
18973
18974         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
18975         #define OBD_FAIL_OST_ENOINO              0x229
18976         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
18977         create_pool $FSNAME.$TESTNAME || return 1
18978         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
18979
18980         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
18981
18982         MDSOBJS=$((last_id - next_id))
18983         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
18984
18985         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
18986         echo "OST still has $count kbytes free"
18987
18988         echo "create $MDSOBJS files @next_id..."
18989         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
18990
18991         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18992                         osp.$mdtosc_proc1.prealloc_last_id)
18993         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18994                         osp.$mdtosc_proc1.prealloc_next_id)
18995
18996         echo "after creation, last_id=$last_id2, next_id=$next_id2"
18997         $LFS df -i
18998
18999         echo "cleanup..."
19000
19001         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19002         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19003
19004         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19005                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19006         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19007                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19008         echo "unlink $MDSOBJS files @$next_id..."
19009         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19010 }
19011 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19012
19013 test_221() {
19014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19015
19016         dd if=`which date` of=$MOUNT/date oflag=sync
19017         chmod +x $MOUNT/date
19018
19019         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19020         $LCTL set_param fail_loc=0x80001401
19021
19022         $MOUNT/date > /dev/null
19023         rm -f $MOUNT/date
19024 }
19025 run_test 221 "make sure fault and truncate race to not cause OOM"
19026
19027 test_222a () {
19028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19029
19030         rm -rf $DIR/$tdir
19031         test_mkdir $DIR/$tdir
19032         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19033         createmany -o $DIR/$tdir/$tfile 10
19034         cancel_lru_locks mdc
19035         cancel_lru_locks osc
19036         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19037         $LCTL set_param fail_loc=0x31a
19038         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19039         $LCTL set_param fail_loc=0
19040         rm -r $DIR/$tdir
19041 }
19042 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19043
19044 test_222b () {
19045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19046
19047         rm -rf $DIR/$tdir
19048         test_mkdir $DIR/$tdir
19049         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19050         createmany -o $DIR/$tdir/$tfile 10
19051         cancel_lru_locks mdc
19052         cancel_lru_locks osc
19053         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19054         $LCTL set_param fail_loc=0x31a
19055         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19056         $LCTL set_param fail_loc=0
19057 }
19058 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19059
19060 test_223 () {
19061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19062
19063         rm -rf $DIR/$tdir
19064         test_mkdir $DIR/$tdir
19065         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19066         createmany -o $DIR/$tdir/$tfile 10
19067         cancel_lru_locks mdc
19068         cancel_lru_locks osc
19069         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19070         $LCTL set_param fail_loc=0x31b
19071         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19072         $LCTL set_param fail_loc=0
19073         rm -r $DIR/$tdir
19074 }
19075 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19076
19077 test_224a() { # LU-1039, MRP-303
19078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19079         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19080         $LCTL set_param fail_loc=0x508
19081         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19082         $LCTL set_param fail_loc=0
19083         df $DIR
19084 }
19085 run_test 224a "Don't panic on bulk IO failure"
19086
19087 test_224bd_sub() { # LU-1039, MRP-303
19088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19089         local timeout=$1
19090
19091         shift
19092         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19093
19094         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19095
19096         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19097         cancel_lru_locks osc
19098         set_checksums 0
19099         stack_trap "set_checksums $ORIG_CSUM" EXIT
19100         local at_max_saved=0
19101
19102         # adaptive timeouts may prevent seeing the issue
19103         if at_is_enabled; then
19104                 at_max_saved=$(at_max_get mds)
19105                 at_max_set 0 mds client
19106                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19107         fi
19108
19109         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19110         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19111         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19112
19113         do_facet ost1 $LCTL set_param fail_loc=0
19114         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19115         df $DIR
19116 }
19117
19118 test_224b() {
19119         test_224bd_sub 3 error "dd failed"
19120 }
19121 run_test 224b "Don't panic on bulk IO failure"
19122
19123 test_224c() { # LU-6441
19124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19125         remote_mds_nodsh && skip "remote MDS with nodsh"
19126
19127         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19128         save_writethrough $p
19129         set_cache writethrough on
19130
19131         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19132         local at_max=$($LCTL get_param -n at_max)
19133         local timeout=$($LCTL get_param -n timeout)
19134         local test_at="at_max"
19135         local param_at="$FSNAME.sys.at_max"
19136         local test_timeout="timeout"
19137         local param_timeout="$FSNAME.sys.timeout"
19138
19139         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19140
19141         set_persistent_param_and_check client "$test_at" "$param_at" 0
19142         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19143
19144         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19145         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19146         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19147         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19148         sync
19149         do_facet ost1 "$LCTL set_param fail_loc=0"
19150
19151         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19152         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19153                 $timeout
19154
19155         $LCTL set_param -n $pages_per_rpc
19156         restore_lustre_params < $p
19157         rm -f $p
19158 }
19159 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19160
19161 test_224d() { # LU-11169
19162         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19163 }
19164 run_test 224d "Don't corrupt data on bulk IO timeout"
19165
19166 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19167 test_225a () {
19168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19169         if [ -z ${MDSSURVEY} ]; then
19170                 skip_env "mds-survey not found"
19171         fi
19172         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19173                 skip "Need MDS version at least 2.2.51"
19174
19175         local mds=$(facet_host $SINGLEMDS)
19176         local target=$(do_nodes $mds 'lctl dl' |
19177                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19178
19179         local cmd1="file_count=1000 thrhi=4"
19180         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19181         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19182         local cmd="$cmd1 $cmd2 $cmd3"
19183
19184         rm -f ${TMP}/mds_survey*
19185         echo + $cmd
19186         eval $cmd || error "mds-survey with zero-stripe failed"
19187         cat ${TMP}/mds_survey*
19188         rm -f ${TMP}/mds_survey*
19189 }
19190 run_test 225a "Metadata survey sanity with zero-stripe"
19191
19192 test_225b () {
19193         if [ -z ${MDSSURVEY} ]; then
19194                 skip_env "mds-survey not found"
19195         fi
19196         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19197                 skip "Need MDS version at least 2.2.51"
19198         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19199         remote_mds_nodsh && skip "remote MDS with nodsh"
19200         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19201                 skip_env "Need to mount OST to test"
19202         fi
19203
19204         local mds=$(facet_host $SINGLEMDS)
19205         local target=$(do_nodes $mds 'lctl dl' |
19206                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19207
19208         local cmd1="file_count=1000 thrhi=4"
19209         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19210         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19211         local cmd="$cmd1 $cmd2 $cmd3"
19212
19213         rm -f ${TMP}/mds_survey*
19214         echo + $cmd
19215         eval $cmd || error "mds-survey with stripe_count failed"
19216         cat ${TMP}/mds_survey*
19217         rm -f ${TMP}/mds_survey*
19218 }
19219 run_test 225b "Metadata survey sanity with stripe_count = 1"
19220
19221 mcreate_path2fid () {
19222         local mode=$1
19223         local major=$2
19224         local minor=$3
19225         local name=$4
19226         local desc=$5
19227         local path=$DIR/$tdir/$name
19228         local fid
19229         local rc
19230         local fid_path
19231
19232         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19233                 error "cannot create $desc"
19234
19235         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19236         rc=$?
19237         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19238
19239         fid_path=$($LFS fid2path $MOUNT $fid)
19240         rc=$?
19241         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19242
19243         [ "$path" == "$fid_path" ] ||
19244                 error "fid2path returned $fid_path, expected $path"
19245
19246         echo "pass with $path and $fid"
19247 }
19248
19249 test_226a () {
19250         rm -rf $DIR/$tdir
19251         mkdir -p $DIR/$tdir
19252
19253         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19254         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19255         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19256         mcreate_path2fid 0040666 0 0 dir "directory"
19257         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19258         mcreate_path2fid 0100666 0 0 file "regular file"
19259         mcreate_path2fid 0120666 0 0 link "symbolic link"
19260         mcreate_path2fid 0140666 0 0 sock "socket"
19261 }
19262 run_test 226a "call path2fid and fid2path on files of all type"
19263
19264 test_226b () {
19265         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19266
19267         local MDTIDX=1
19268
19269         rm -rf $DIR/$tdir
19270         mkdir -p $DIR/$tdir
19271         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19272                 error "create remote directory failed"
19273         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19274         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19275                                 "character special file (null)"
19276         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19277                                 "character special file (no device)"
19278         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19279         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19280                                 "block special file (loop)"
19281         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19282         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19283         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19284 }
19285 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19286
19287 test_226c () {
19288         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19289         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19290                 skip "Need MDS version at least 2.13.55"
19291
19292         local submnt=/mnt/submnt
19293         local srcfile=/etc/passwd
19294         local dstfile=$submnt/passwd
19295         local path
19296         local fid
19297
19298         rm -rf $DIR/$tdir
19299         rm -rf $submnt
19300         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19301                 error "create remote directory failed"
19302         mkdir -p $submnt || error "create $submnt failed"
19303         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19304                 error "mount $submnt failed"
19305         stack_trap "umount $submnt" EXIT
19306
19307         cp $srcfile $dstfile
19308         fid=$($LFS path2fid $dstfile)
19309         path=$($LFS fid2path $submnt "$fid")
19310         [ "$path" = "$dstfile" ] ||
19311                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19312 }
19313 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19314
19315 # LU-1299 Executing or running ldd on a truncated executable does not
19316 # cause an out-of-memory condition.
19317 test_227() {
19318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19319         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19320
19321         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19322         chmod +x $MOUNT/date
19323
19324         $MOUNT/date > /dev/null
19325         ldd $MOUNT/date > /dev/null
19326         rm -f $MOUNT/date
19327 }
19328 run_test 227 "running truncated executable does not cause OOM"
19329
19330 # LU-1512 try to reuse idle OI blocks
19331 test_228a() {
19332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19333         remote_mds_nodsh && skip "remote MDS with nodsh"
19334         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19335
19336         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19337         local myDIR=$DIR/$tdir
19338
19339         mkdir -p $myDIR
19340         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19341         $LCTL set_param fail_loc=0x80001002
19342         createmany -o $myDIR/t- 10000
19343         $LCTL set_param fail_loc=0
19344         # The guard is current the largest FID holder
19345         touch $myDIR/guard
19346         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19347                     tr -d '[')
19348         local IDX=$(($SEQ % 64))
19349
19350         do_facet $SINGLEMDS sync
19351         # Make sure journal flushed.
19352         sleep 6
19353         local blk1=$(do_facet $SINGLEMDS \
19354                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19355                      grep Blockcount | awk '{print $4}')
19356
19357         # Remove old files, some OI blocks will become idle.
19358         unlinkmany $myDIR/t- 10000
19359         # Create new files, idle OI blocks should be reused.
19360         createmany -o $myDIR/t- 2000
19361         do_facet $SINGLEMDS sync
19362         # Make sure journal flushed.
19363         sleep 6
19364         local blk2=$(do_facet $SINGLEMDS \
19365                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19366                      grep Blockcount | awk '{print $4}')
19367
19368         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19369 }
19370 run_test 228a "try to reuse idle OI blocks"
19371
19372 test_228b() {
19373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19374         remote_mds_nodsh && skip "remote MDS with nodsh"
19375         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19376
19377         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19378         local myDIR=$DIR/$tdir
19379
19380         mkdir -p $myDIR
19381         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19382         $LCTL set_param fail_loc=0x80001002
19383         createmany -o $myDIR/t- 10000
19384         $LCTL set_param fail_loc=0
19385         # The guard is current the largest FID holder
19386         touch $myDIR/guard
19387         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19388                     tr -d '[')
19389         local IDX=$(($SEQ % 64))
19390
19391         do_facet $SINGLEMDS sync
19392         # Make sure journal flushed.
19393         sleep 6
19394         local blk1=$(do_facet $SINGLEMDS \
19395                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19396                      grep Blockcount | awk '{print $4}')
19397
19398         # Remove old files, some OI blocks will become idle.
19399         unlinkmany $myDIR/t- 10000
19400
19401         # stop the MDT
19402         stop $SINGLEMDS || error "Fail to stop MDT."
19403         # remount the MDT
19404         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
19405
19406         df $MOUNT || error "Fail to df."
19407         # Create new files, idle OI blocks should be reused.
19408         createmany -o $myDIR/t- 2000
19409         do_facet $SINGLEMDS sync
19410         # Make sure journal flushed.
19411         sleep 6
19412         local blk2=$(do_facet $SINGLEMDS \
19413                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19414                      grep Blockcount | awk '{print $4}')
19415
19416         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19417 }
19418 run_test 228b "idle OI blocks can be reused after MDT restart"
19419
19420 #LU-1881
19421 test_228c() {
19422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19423         remote_mds_nodsh && skip "remote MDS with nodsh"
19424         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19425
19426         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19427         local myDIR=$DIR/$tdir
19428
19429         mkdir -p $myDIR
19430         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19431         $LCTL set_param fail_loc=0x80001002
19432         # 20000 files can guarantee there are index nodes in the OI file
19433         createmany -o $myDIR/t- 20000
19434         $LCTL set_param fail_loc=0
19435         # The guard is current the largest FID holder
19436         touch $myDIR/guard
19437         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19438                     tr -d '[')
19439         local IDX=$(($SEQ % 64))
19440
19441         do_facet $SINGLEMDS sync
19442         # Make sure journal flushed.
19443         sleep 6
19444         local blk1=$(do_facet $SINGLEMDS \
19445                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19446                      grep Blockcount | awk '{print $4}')
19447
19448         # Remove old files, some OI blocks will become idle.
19449         unlinkmany $myDIR/t- 20000
19450         rm -f $myDIR/guard
19451         # The OI file should become empty now
19452
19453         # Create new files, idle OI blocks should be reused.
19454         createmany -o $myDIR/t- 2000
19455         do_facet $SINGLEMDS sync
19456         # Make sure journal flushed.
19457         sleep 6
19458         local blk2=$(do_facet $SINGLEMDS \
19459                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19460                      grep Blockcount | awk '{print $4}')
19461
19462         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19463 }
19464 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19465
19466 test_229() { # LU-2482, LU-3448
19467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19468         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19469         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19470                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19471
19472         rm -f $DIR/$tfile
19473
19474         # Create a file with a released layout and stripe count 2.
19475         $MULTIOP $DIR/$tfile H2c ||
19476                 error "failed to create file with released layout"
19477
19478         $LFS getstripe -v $DIR/$tfile
19479
19480         local pattern=$($LFS getstripe -L $DIR/$tfile)
19481         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19482
19483         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19484                 error "getstripe"
19485         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19486         stat $DIR/$tfile || error "failed to stat released file"
19487
19488         chown $RUNAS_ID $DIR/$tfile ||
19489                 error "chown $RUNAS_ID $DIR/$tfile failed"
19490
19491         chgrp $RUNAS_ID $DIR/$tfile ||
19492                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19493
19494         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19495         rm $DIR/$tfile || error "failed to remove released file"
19496 }
19497 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19498
19499 test_230a() {
19500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19501         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19502         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19503                 skip "Need MDS version at least 2.11.52"
19504
19505         local MDTIDX=1
19506
19507         test_mkdir $DIR/$tdir
19508         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19509         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19510         [ $mdt_idx -ne 0 ] &&
19511                 error "create local directory on wrong MDT $mdt_idx"
19512
19513         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19514                         error "create remote directory failed"
19515         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19516         [ $mdt_idx -ne $MDTIDX ] &&
19517                 error "create remote directory on wrong MDT $mdt_idx"
19518
19519         createmany -o $DIR/$tdir/test_230/t- 10 ||
19520                 error "create files on remote directory failed"
19521         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19522         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19523         rm -r $DIR/$tdir || error "unlink remote directory failed"
19524 }
19525 run_test 230a "Create remote directory and files under the remote directory"
19526
19527 test_230b() {
19528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19529         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19530         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19531                 skip "Need MDS version at least 2.11.52"
19532
19533         local MDTIDX=1
19534         local mdt_index
19535         local i
19536         local file
19537         local pid
19538         local stripe_count
19539         local migrate_dir=$DIR/$tdir/migrate_dir
19540         local other_dir=$DIR/$tdir/other_dir
19541
19542         test_mkdir $DIR/$tdir
19543         test_mkdir -i0 -c1 $migrate_dir
19544         test_mkdir -i0 -c1 $other_dir
19545         for ((i=0; i<10; i++)); do
19546                 mkdir -p $migrate_dir/dir_${i}
19547                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19548                         error "create files under remote dir failed $i"
19549         done
19550
19551         cp /etc/passwd $migrate_dir/$tfile
19552         cp /etc/passwd $other_dir/$tfile
19553         chattr +SAD $migrate_dir
19554         chattr +SAD $migrate_dir/$tfile
19555
19556         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19557         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19558         local old_dir_mode=$(stat -c%f $migrate_dir)
19559         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19560
19561         mkdir -p $migrate_dir/dir_default_stripe2
19562         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19563         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19564
19565         mkdir -p $other_dir
19566         ln $migrate_dir/$tfile $other_dir/luna
19567         ln $migrate_dir/$tfile $migrate_dir/sofia
19568         ln $other_dir/$tfile $migrate_dir/david
19569         ln -s $migrate_dir/$tfile $other_dir/zachary
19570         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19571         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19572
19573         local len
19574         local lnktgt
19575
19576         # inline symlink
19577         for len in 58 59 60; do
19578                 lnktgt=$(str_repeat 'l' $len)
19579                 touch $migrate_dir/$lnktgt
19580                 ln -s $lnktgt $migrate_dir/${len}char_ln
19581         done
19582
19583         # PATH_MAX
19584         for len in 4094 4095; do
19585                 lnktgt=$(str_repeat 'l' $len)
19586                 ln -s $lnktgt $migrate_dir/${len}char_ln
19587         done
19588
19589         # NAME_MAX
19590         for len in 254 255; do
19591                 touch $migrate_dir/$(str_repeat 'l' $len)
19592         done
19593
19594         $LFS migrate -m $MDTIDX $migrate_dir ||
19595                 error "fails on migrating remote dir to MDT1"
19596
19597         echo "migratate to MDT1, then checking.."
19598         for ((i = 0; i < 10; i++)); do
19599                 for file in $(find $migrate_dir/dir_${i}); do
19600                         mdt_index=$($LFS getstripe -m $file)
19601                         # broken symlink getstripe will fail
19602                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19603                                 error "$file is not on MDT${MDTIDX}"
19604                 done
19605         done
19606
19607         # the multiple link file should still in MDT0
19608         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19609         [ $mdt_index == 0 ] ||
19610                 error "$file is not on MDT${MDTIDX}"
19611
19612         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19613         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19614                 error " expect $old_dir_flag get $new_dir_flag"
19615
19616         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19617         [ "$old_file_flag" = "$new_file_flag" ] ||
19618                 error " expect $old_file_flag get $new_file_flag"
19619
19620         local new_dir_mode=$(stat -c%f $migrate_dir)
19621         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19622                 error "expect mode $old_dir_mode get $new_dir_mode"
19623
19624         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19625         [ "$old_file_mode" = "$new_file_mode" ] ||
19626                 error "expect mode $old_file_mode get $new_file_mode"
19627
19628         diff /etc/passwd $migrate_dir/$tfile ||
19629                 error "$tfile different after migration"
19630
19631         diff /etc/passwd $other_dir/luna ||
19632                 error "luna different after migration"
19633
19634         diff /etc/passwd $migrate_dir/sofia ||
19635                 error "sofia different after migration"
19636
19637         diff /etc/passwd $migrate_dir/david ||
19638                 error "david different after migration"
19639
19640         diff /etc/passwd $other_dir/zachary ||
19641                 error "zachary different after migration"
19642
19643         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19644                 error "${tfile}_ln different after migration"
19645
19646         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19647                 error "${tfile}_ln_other different after migration"
19648
19649         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19650         [ $stripe_count = 2 ] ||
19651                 error "dir strpe_count $d != 2 after migration."
19652
19653         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19654         [ $stripe_count = 2 ] ||
19655                 error "file strpe_count $d != 2 after migration."
19656
19657         #migrate back to MDT0
19658         MDTIDX=0
19659
19660         $LFS migrate -m $MDTIDX $migrate_dir ||
19661                 error "fails on migrating remote dir to MDT0"
19662
19663         echo "migrate back to MDT0, checking.."
19664         for file in $(find $migrate_dir); do
19665                 mdt_index=$($LFS getstripe -m $file)
19666                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19667                         error "$file is not on MDT${MDTIDX}"
19668         done
19669
19670         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19671         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19672                 error " expect $old_dir_flag get $new_dir_flag"
19673
19674         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19675         [ "$old_file_flag" = "$new_file_flag" ] ||
19676                 error " expect $old_file_flag get $new_file_flag"
19677
19678         local new_dir_mode=$(stat -c%f $migrate_dir)
19679         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19680                 error "expect mode $old_dir_mode get $new_dir_mode"
19681
19682         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19683         [ "$old_file_mode" = "$new_file_mode" ] ||
19684                 error "expect mode $old_file_mode get $new_file_mode"
19685
19686         diff /etc/passwd ${migrate_dir}/$tfile ||
19687                 error "$tfile different after migration"
19688
19689         diff /etc/passwd ${other_dir}/luna ||
19690                 error "luna different after migration"
19691
19692         diff /etc/passwd ${migrate_dir}/sofia ||
19693                 error "sofia different after migration"
19694
19695         diff /etc/passwd ${other_dir}/zachary ||
19696                 error "zachary different after migration"
19697
19698         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19699                 error "${tfile}_ln different after migration"
19700
19701         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19702                 error "${tfile}_ln_other different after migration"
19703
19704         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19705         [ $stripe_count = 2 ] ||
19706                 error "dir strpe_count $d != 2 after migration."
19707
19708         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19709         [ $stripe_count = 2 ] ||
19710                 error "file strpe_count $d != 2 after migration."
19711
19712         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19713 }
19714 run_test 230b "migrate directory"
19715
19716 test_230c() {
19717         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19718         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19719         remote_mds_nodsh && skip "remote MDS with nodsh"
19720         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19721                 skip "Need MDS version at least 2.11.52"
19722
19723         local MDTIDX=1
19724         local total=3
19725         local mdt_index
19726         local file
19727         local migrate_dir=$DIR/$tdir/migrate_dir
19728
19729         #If migrating directory fails in the middle, all entries of
19730         #the directory is still accessiable.
19731         test_mkdir $DIR/$tdir
19732         test_mkdir -i0 -c1 $migrate_dir
19733         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19734         stat $migrate_dir
19735         createmany -o $migrate_dir/f $total ||
19736                 error "create files under ${migrate_dir} failed"
19737
19738         # fail after migrating top dir, and this will fail only once, so the
19739         # first sub file migration will fail (currently f3), others succeed.
19740         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19741         do_facet mds1 lctl set_param fail_loc=0x1801
19742         local t=$(ls $migrate_dir | wc -l)
19743         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19744                 error "migrate should fail"
19745         local u=$(ls $migrate_dir | wc -l)
19746         [ "$u" == "$t" ] || error "$u != $t during migration"
19747
19748         # add new dir/file should succeed
19749         mkdir $migrate_dir/dir ||
19750                 error "mkdir failed under migrating directory"
19751         touch $migrate_dir/file ||
19752                 error "create file failed under migrating directory"
19753
19754         # add file with existing name should fail
19755         for file in $migrate_dir/f*; do
19756                 stat $file > /dev/null || error "stat $file failed"
19757                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19758                         error "open(O_CREAT|O_EXCL) $file should fail"
19759                 $MULTIOP $file m && error "create $file should fail"
19760                 touch $DIR/$tdir/remote_dir/$tfile ||
19761                         error "touch $tfile failed"
19762                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19763                         error "link $file should fail"
19764                 mdt_index=$($LFS getstripe -m $file)
19765                 if [ $mdt_index == 0 ]; then
19766                         # file failed to migrate is not allowed to rename to
19767                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19768                                 error "rename to $file should fail"
19769                 else
19770                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19771                                 error "rename to $file failed"
19772                 fi
19773                 echo hello >> $file || error "write $file failed"
19774         done
19775
19776         # resume migration with different options should fail
19777         $LFS migrate -m 0 $migrate_dir &&
19778                 error "migrate -m 0 $migrate_dir should fail"
19779
19780         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19781                 error "migrate -c 2 $migrate_dir should fail"
19782
19783         # resume migration should succeed
19784         $LFS migrate -m $MDTIDX $migrate_dir ||
19785                 error "migrate $migrate_dir failed"
19786
19787         echo "Finish migration, then checking.."
19788         for file in $(find $migrate_dir); do
19789                 mdt_index=$($LFS getstripe -m $file)
19790                 [ $mdt_index == $MDTIDX ] ||
19791                         error "$file is not on MDT${MDTIDX}"
19792         done
19793
19794         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19795 }
19796 run_test 230c "check directory accessiblity if migration failed"
19797
19798 test_230d() {
19799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19800         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19801         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19802                 skip "Need MDS version at least 2.11.52"
19803         # LU-11235
19804         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19805
19806         local migrate_dir=$DIR/$tdir/migrate_dir
19807         local old_index
19808         local new_index
19809         local old_count
19810         local new_count
19811         local new_hash
19812         local mdt_index
19813         local i
19814         local j
19815
19816         old_index=$((RANDOM % MDSCOUNT))
19817         old_count=$((MDSCOUNT - old_index))
19818         new_index=$((RANDOM % MDSCOUNT))
19819         new_count=$((MDSCOUNT - new_index))
19820         new_hash=1 # for all_char
19821
19822         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19823         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19824
19825         test_mkdir $DIR/$tdir
19826         test_mkdir -i $old_index -c $old_count $migrate_dir
19827
19828         for ((i=0; i<100; i++)); do
19829                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19830                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19831                         error "create files under remote dir failed $i"
19832         done
19833
19834         echo -n "Migrate from MDT$old_index "
19835         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19836         echo -n "to MDT$new_index"
19837         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19838         echo
19839
19840         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19841         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19842                 error "migrate remote dir error"
19843
19844         echo "Finish migration, then checking.."
19845         for file in $(find $migrate_dir -maxdepth 1); do
19846                 mdt_index=$($LFS getstripe -m $file)
19847                 if [ $mdt_index -lt $new_index ] ||
19848                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19849                         error "$file is on MDT$mdt_index"
19850                 fi
19851         done
19852
19853         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19854 }
19855 run_test 230d "check migrate big directory"
19856
19857 test_230e() {
19858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19859         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19860         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19861                 skip "Need MDS version at least 2.11.52"
19862
19863         local i
19864         local j
19865         local a_fid
19866         local b_fid
19867
19868         mkdir_on_mdt0 $DIR/$tdir
19869         mkdir $DIR/$tdir/migrate_dir
19870         mkdir $DIR/$tdir/other_dir
19871         touch $DIR/$tdir/migrate_dir/a
19872         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19873         ls $DIR/$tdir/other_dir
19874
19875         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19876                 error "migrate dir fails"
19877
19878         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19879         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19880
19881         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19882         [ $mdt_index == 0 ] || error "a is not on MDT0"
19883
19884         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19885                 error "migrate dir fails"
19886
19887         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19888         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19889
19890         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19891         [ $mdt_index == 1 ] || error "a is not on MDT1"
19892
19893         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19894         [ $mdt_index == 1 ] || error "b is not on MDT1"
19895
19896         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19897         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19898
19899         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19900
19901         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19902 }
19903 run_test 230e "migrate mulitple local link files"
19904
19905 test_230f() {
19906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19907         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19908         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19909                 skip "Need MDS version at least 2.11.52"
19910
19911         local a_fid
19912         local ln_fid
19913
19914         mkdir -p $DIR/$tdir
19915         mkdir $DIR/$tdir/migrate_dir
19916         $LFS mkdir -i1 $DIR/$tdir/other_dir
19917         touch $DIR/$tdir/migrate_dir/a
19918         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
19919         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
19920         ls $DIR/$tdir/other_dir
19921
19922         # a should be migrated to MDT1, since no other links on MDT0
19923         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19924                 error "#1 migrate dir fails"
19925         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19926         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19927         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19928         [ $mdt_index == 1 ] || error "a is not on MDT1"
19929
19930         # a should stay on MDT1, because it is a mulitple link file
19931         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19932                 error "#2 migrate dir fails"
19933         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19934         [ $mdt_index == 1 ] || error "a is not on MDT1"
19935
19936         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19937                 error "#3 migrate dir fails"
19938
19939         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19940         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
19941         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
19942
19943         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
19944         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
19945
19946         # a should be migrated to MDT0, since no other links on MDT1
19947         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19948                 error "#4 migrate dir fails"
19949         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19950         [ $mdt_index == 0 ] || error "a is not on MDT0"
19951
19952         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19953 }
19954 run_test 230f "migrate mulitple remote link files"
19955
19956 test_230g() {
19957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19958         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19959         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19960                 skip "Need MDS version at least 2.11.52"
19961
19962         mkdir -p $DIR/$tdir/migrate_dir
19963
19964         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
19965                 error "migrating dir to non-exist MDT succeeds"
19966         true
19967 }
19968 run_test 230g "migrate dir to non-exist MDT"
19969
19970 test_230h() {
19971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19972         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19973         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19974                 skip "Need MDS version at least 2.11.52"
19975
19976         local mdt_index
19977
19978         mkdir -p $DIR/$tdir/migrate_dir
19979
19980         $LFS migrate -m1 $DIR &&
19981                 error "migrating mountpoint1 should fail"
19982
19983         $LFS migrate -m1 $DIR/$tdir/.. &&
19984                 error "migrating mountpoint2 should fail"
19985
19986         # same as mv
19987         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
19988                 error "migrating $tdir/migrate_dir/.. should fail"
19989
19990         true
19991 }
19992 run_test 230h "migrate .. and root"
19993
19994 test_230i() {
19995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19996         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19997         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19998                 skip "Need MDS version at least 2.11.52"
19999
20000         mkdir -p $DIR/$tdir/migrate_dir
20001
20002         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20003                 error "migration fails with a tailing slash"
20004
20005         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20006                 error "migration fails with two tailing slashes"
20007 }
20008 run_test 230i "lfs migrate -m tolerates trailing slashes"
20009
20010 test_230j() {
20011         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20012         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20013                 skip "Need MDS version at least 2.11.52"
20014
20015         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20016         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20017                 error "create $tfile failed"
20018         cat /etc/passwd > $DIR/$tdir/$tfile
20019
20020         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20021
20022         cmp /etc/passwd $DIR/$tdir/$tfile ||
20023                 error "DoM file mismatch after migration"
20024 }
20025 run_test 230j "DoM file data not changed after dir migration"
20026
20027 test_230k() {
20028         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20029         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20030                 skip "Need MDS version at least 2.11.56"
20031
20032         local total=20
20033         local files_on_starting_mdt=0
20034
20035         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20036         $LFS getdirstripe $DIR/$tdir
20037         for i in $(seq $total); do
20038                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20039                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20040                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20041         done
20042
20043         echo "$files_on_starting_mdt files on MDT0"
20044
20045         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20046         $LFS getdirstripe $DIR/$tdir
20047
20048         files_on_starting_mdt=0
20049         for i in $(seq $total); do
20050                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20051                         error "file $tfile.$i mismatch after migration"
20052                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20053                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20054         done
20055
20056         echo "$files_on_starting_mdt files on MDT1 after migration"
20057         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20058
20059         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20060         $LFS getdirstripe $DIR/$tdir
20061
20062         files_on_starting_mdt=0
20063         for i in $(seq $total); do
20064                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20065                         error "file $tfile.$i mismatch after 2nd migration"
20066                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20067                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20068         done
20069
20070         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20071         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20072
20073         true
20074 }
20075 run_test 230k "file data not changed after dir migration"
20076
20077 test_230l() {
20078         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20079         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20080                 skip "Need MDS version at least 2.11.56"
20081
20082         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20083         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20084                 error "create files under remote dir failed $i"
20085         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20086 }
20087 run_test 230l "readdir between MDTs won't crash"
20088
20089 test_230m() {
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         local MDTIDX=1
20095         local mig_dir=$DIR/$tdir/migrate_dir
20096         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20097         local shortstr="b"
20098         local val
20099
20100         echo "Creating files and dirs with xattrs"
20101         test_mkdir $DIR/$tdir
20102         test_mkdir -i0 -c1 $mig_dir
20103         mkdir $mig_dir/dir
20104         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20105                 error "cannot set xattr attr1 on dir"
20106         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20107                 error "cannot set xattr attr2 on dir"
20108         touch $mig_dir/dir/f0
20109         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20110                 error "cannot set xattr attr1 on file"
20111         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20112                 error "cannot set xattr attr2 on file"
20113         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20114         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20115         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20116         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20117         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20118         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20119         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20120         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20121         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20122
20123         echo "Migrating to MDT1"
20124         $LFS migrate -m $MDTIDX $mig_dir ||
20125                 error "fails on migrating dir to MDT1"
20126
20127         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20128         echo "Checking xattrs"
20129         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20130         [ "$val" = $longstr ] ||
20131                 error "expecting xattr1 $longstr on dir, found $val"
20132         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20133         [ "$val" = $shortstr ] ||
20134                 error "expecting xattr2 $shortstr on dir, found $val"
20135         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20136         [ "$val" = $longstr ] ||
20137                 error "expecting xattr1 $longstr on file, found $val"
20138         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20139         [ "$val" = $shortstr ] ||
20140                 error "expecting xattr2 $shortstr on file, found $val"
20141 }
20142 run_test 230m "xattrs not changed after dir migration"
20143
20144 test_230n() {
20145         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20146         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20147                 skip "Need MDS version at least 2.13.53"
20148
20149         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20150         cat /etc/hosts > $DIR/$tdir/$tfile
20151         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20152         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20153
20154         cmp /etc/hosts $DIR/$tdir/$tfile ||
20155                 error "File data mismatch after migration"
20156 }
20157 run_test 230n "Dir migration with mirrored file"
20158
20159 test_230o() {
20160         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20161         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20162                 skip "Need MDS version at least 2.13.52"
20163
20164         local mdts=$(comma_list $(mdts_nodes))
20165         local timeout=100
20166         local restripe_status
20167         local delta
20168         local i
20169
20170         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20171
20172         # in case "crush" hash type is not set
20173         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20174
20175         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20176                            mdt.*MDT0000.enable_dir_restripe)
20177         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20178         stack_trap "do_nodes $mdts $LCTL set_param \
20179                     mdt.*.enable_dir_restripe=$restripe_status"
20180
20181         mkdir $DIR/$tdir
20182         createmany -m $DIR/$tdir/f 100 ||
20183                 error "create files under remote dir failed $i"
20184         createmany -d $DIR/$tdir/d 100 ||
20185                 error "create dirs under remote dir failed $i"
20186
20187         for i in $(seq 2 $MDSCOUNT); do
20188                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20189                 $LFS setdirstripe -c $i $DIR/$tdir ||
20190                         error "split -c $i $tdir failed"
20191                 wait_update $HOSTNAME \
20192                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20193                         error "dir split not finished"
20194                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20195                         awk '/migrate/ {sum += $2} END { print sum }')
20196                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20197                 # delta is around total_files/stripe_count
20198                 (( $delta < 200 / (i - 1) + 4 )) ||
20199                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20200         done
20201 }
20202 run_test 230o "dir split"
20203
20204 test_230p() {
20205         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20206         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20207                 skip "Need MDS version at least 2.13.52"
20208
20209         local mdts=$(comma_list $(mdts_nodes))
20210         local timeout=100
20211         local restripe_status
20212         local delta
20213         local c
20214
20215         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20216
20217         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20218
20219         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20220                            mdt.*MDT0000.enable_dir_restripe)
20221         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20222         stack_trap "do_nodes $mdts $LCTL set_param \
20223                     mdt.*.enable_dir_restripe=$restripe_status"
20224
20225         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20226         createmany -m $DIR/$tdir/f 100 ||
20227                 error "create files under remote dir failed"
20228         createmany -d $DIR/$tdir/d 100 ||
20229                 error "create dirs under remote dir failed"
20230
20231         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20232                 local mdt_hash="crush"
20233
20234                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20235                 $LFS setdirstripe -c $c $DIR/$tdir ||
20236                         error "split -c $c $tdir failed"
20237                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20238                         mdt_hash="$mdt_hash,fixed"
20239                 elif [ $c -eq 1 ]; then
20240                         mdt_hash="none"
20241                 fi
20242                 wait_update $HOSTNAME \
20243                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20244                         error "dir merge not finished"
20245                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20246                         awk '/migrate/ {sum += $2} END { print sum }')
20247                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20248                 # delta is around total_files/stripe_count
20249                 (( delta < 200 / c + 4 )) ||
20250                         error "$delta files migrated >= $((200 / c + 4))"
20251         done
20252 }
20253 run_test 230p "dir merge"
20254
20255 test_230q() {
20256         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20257         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20258                 skip "Need MDS version at least 2.13.52"
20259
20260         local mdts=$(comma_list $(mdts_nodes))
20261         local saved_threshold=$(do_facet mds1 \
20262                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20263         local saved_delta=$(do_facet mds1 \
20264                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20265         local threshold=100
20266         local delta=2
20267         local total=0
20268         local stripe_count=0
20269         local stripe_index
20270         local nr_files
20271         local create
20272
20273         # test with fewer files on ZFS
20274         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20275
20276         stack_trap "do_nodes $mdts $LCTL set_param \
20277                     mdt.*.dir_split_count=$saved_threshold"
20278         stack_trap "do_nodes $mdts $LCTL set_param \
20279                     mdt.*.dir_split_delta=$saved_delta"
20280         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20281         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20282         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20283         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20284         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20285         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20286
20287         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20288         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20289
20290         create=$((threshold * 3 / 2))
20291         while [ $stripe_count -lt $MDSCOUNT ]; do
20292                 createmany -m $DIR/$tdir/f $total $create ||
20293                         error "create sub files failed"
20294                 stat $DIR/$tdir > /dev/null
20295                 total=$((total + create))
20296                 stripe_count=$((stripe_count + delta))
20297                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20298
20299                 wait_update $HOSTNAME \
20300                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20301                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20302
20303                 wait_update $HOSTNAME \
20304                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20305                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20306
20307                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20308                 echo "$nr_files/$total files on MDT$stripe_index after split"
20309                 # allow 10% margin of imbalance with crush hash
20310                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20311                         error "$nr_files files on MDT$stripe_index after split"
20312
20313                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20314                 [ $nr_files -eq $total ] ||
20315                         error "total sub files $nr_files != $total"
20316         done
20317
20318         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20319
20320         echo "fixed layout directory won't auto split"
20321         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20322         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20323                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20324         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20325                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20326 }
20327 run_test 230q "dir auto split"
20328
20329 test_230r() {
20330         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20331         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20332         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20333                 skip "Need MDS version at least 2.13.54"
20334
20335         # maximum amount of local locks:
20336         # parent striped dir - 2 locks
20337         # new stripe in parent to migrate to - 1 lock
20338         # source and target - 2 locks
20339         # Total 5 locks for regular file
20340         mkdir -p $DIR/$tdir
20341         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20342         touch $DIR/$tdir/dir1/eee
20343
20344         # create 4 hardlink for 4 more locks
20345         # Total: 9 locks > RS_MAX_LOCKS (8)
20346         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20347         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20348         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20349         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20350         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20351         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20352         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20353         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20354
20355         cancel_lru_locks mdc
20356
20357         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20358                 error "migrate dir fails"
20359
20360         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20361 }
20362 run_test 230r "migrate with too many local locks"
20363
20364 test_230s() {
20365         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
20366                 skip "Need MDS version at least 2.13.57"
20367
20368         local mdts=$(comma_list $(mdts_nodes))
20369         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20370                                 mdt.*MDT0000.enable_dir_restripe)
20371
20372         stack_trap "do_nodes $mdts $LCTL set_param \
20373                     mdt.*.enable_dir_restripe=$restripe_status"
20374
20375         local st
20376         for st in 0 1; do
20377                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20378                 test_mkdir $DIR/$tdir
20379                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20380                         error "$LFS mkdir doesn't return -EEXIST if target exists"
20381                 rmdir $DIR/$tdir
20382         done
20383 }
20384 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20385
20386 test_230t()
20387 {
20388         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20389         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20390                 skip "Need MDS version at least 2.14.50"
20391
20392         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20393         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20394         $LFS project -p 1 -s $DIR/$tdir ||
20395                 error "set $tdir project id failed"
20396         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20397                 error "set subdir project id failed"
20398         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20399 }
20400 run_test 230t "migrate directory with project ID set"
20401
20402 test_230u()
20403 {
20404         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20405         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20406                 skip "Need MDS version at least 2.14.53"
20407
20408         local count
20409
20410         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20411         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20412         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20413         for i in $(seq 0 $((MDSCOUNT - 1))); do
20414                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20415                 echo "$count dirs migrated to MDT$i"
20416         done
20417         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20418         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20419 }
20420 run_test 230u "migrate directory by QOS"
20421
20422 test_230v()
20423 {
20424         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20425         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20426                 skip "Need MDS version at least 2.14.53"
20427
20428         local count
20429
20430         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20431         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20432         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20433         for i in $(seq 0 $((MDSCOUNT - 1))); do
20434                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20435                 echo "$count subdirs migrated to MDT$i"
20436                 (( i == 3 )) && (( count > 0 )) &&
20437                         error "subdir shouldn't be migrated to MDT3"
20438         done
20439         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20440         (( count == 3 )) || error "dirs migrated to $count MDTs"
20441 }
20442 run_test 230v "subdir migrated to the MDT where its parent is located"
20443
20444 test_230w() {
20445         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20446         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20447                 skip "Need MDS version at least 2.14.53"
20448
20449         mkdir -p $DIR/$tdir/sub || error "mkdir failed"
20450
20451         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
20452                 error "migrate failed"
20453
20454         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
20455                 error "$tdir stripe count mismatch"
20456
20457         (( $($LFS getdirstripe -c $DIR/$tdir/sub) == 0 )) ||
20458                 error "$tdir/sub is striped"
20459 }
20460 run_test 230w "non-recursive mode dir migration"
20461
20462 test_231a()
20463 {
20464         # For simplicity this test assumes that max_pages_per_rpc
20465         # is the same across all OSCs
20466         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20467         local bulk_size=$((max_pages * PAGE_SIZE))
20468         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20469                                        head -n 1)
20470
20471         mkdir -p $DIR/$tdir
20472         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20473                 error "failed to set stripe with -S ${brw_size}M option"
20474
20475         # clear the OSC stats
20476         $LCTL set_param osc.*.stats=0 &>/dev/null
20477         stop_writeback
20478
20479         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20480         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20481                 oflag=direct &>/dev/null || error "dd failed"
20482
20483         sync; sleep 1; sync # just to be safe
20484         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20485         if [ x$nrpcs != "x1" ]; then
20486                 $LCTL get_param osc.*.stats
20487                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20488         fi
20489
20490         start_writeback
20491         # Drop the OSC cache, otherwise we will read from it
20492         cancel_lru_locks osc
20493
20494         # clear the OSC stats
20495         $LCTL set_param osc.*.stats=0 &>/dev/null
20496
20497         # Client reads $bulk_size.
20498         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20499                 iflag=direct &>/dev/null || error "dd failed"
20500
20501         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20502         if [ x$nrpcs != "x1" ]; then
20503                 $LCTL get_param osc.*.stats
20504                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20505         fi
20506 }
20507 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20508
20509 test_231b() {
20510         mkdir -p $DIR/$tdir
20511         local i
20512         for i in {0..1023}; do
20513                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20514                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20515                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20516         done
20517         sync
20518 }
20519 run_test 231b "must not assert on fully utilized OST request buffer"
20520
20521 test_232a() {
20522         mkdir -p $DIR/$tdir
20523         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20524
20525         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20526         do_facet ost1 $LCTL set_param fail_loc=0x31c
20527
20528         # ignore dd failure
20529         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20530
20531         do_facet ost1 $LCTL set_param fail_loc=0
20532         umount_client $MOUNT || error "umount failed"
20533         mount_client $MOUNT || error "mount failed"
20534         stop ost1 || error "cannot stop ost1"
20535         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20536 }
20537 run_test 232a "failed lock should not block umount"
20538
20539 test_232b() {
20540         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20541                 skip "Need MDS version at least 2.10.58"
20542
20543         mkdir -p $DIR/$tdir
20544         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20545         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20546         sync
20547         cancel_lru_locks osc
20548
20549         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20550         do_facet ost1 $LCTL set_param fail_loc=0x31c
20551
20552         # ignore failure
20553         $LFS data_version $DIR/$tdir/$tfile || true
20554
20555         do_facet ost1 $LCTL set_param fail_loc=0
20556         umount_client $MOUNT || error "umount failed"
20557         mount_client $MOUNT || error "mount failed"
20558         stop ost1 || error "cannot stop ost1"
20559         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20560 }
20561 run_test 232b "failed data version lock should not block umount"
20562
20563 test_233a() {
20564         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20565                 skip "Need MDS version at least 2.3.64"
20566         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20567
20568         local fid=$($LFS path2fid $MOUNT)
20569
20570         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20571                 error "cannot access $MOUNT using its FID '$fid'"
20572 }
20573 run_test 233a "checking that OBF of the FS root succeeds"
20574
20575 test_233b() {
20576         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20577                 skip "Need MDS version at least 2.5.90"
20578         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20579
20580         local fid=$($LFS path2fid $MOUNT/.lustre)
20581
20582         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20583                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20584
20585         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20586         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20587                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20588 }
20589 run_test 233b "checking that OBF of the FS .lustre succeeds"
20590
20591 test_234() {
20592         local p="$TMP/sanityN-$TESTNAME.parameters"
20593         save_lustre_params client "llite.*.xattr_cache" > $p
20594         lctl set_param llite.*.xattr_cache 1 ||
20595                 skip_env "xattr cache is not supported"
20596
20597         mkdir -p $DIR/$tdir || error "mkdir failed"
20598         touch $DIR/$tdir/$tfile || error "touch failed"
20599         # OBD_FAIL_LLITE_XATTR_ENOMEM
20600         $LCTL set_param fail_loc=0x1405
20601         getfattr -n user.attr $DIR/$tdir/$tfile &&
20602                 error "getfattr should have failed with ENOMEM"
20603         $LCTL set_param fail_loc=0x0
20604         rm -rf $DIR/$tdir
20605
20606         restore_lustre_params < $p
20607         rm -f $p
20608 }
20609 run_test 234 "xattr cache should not crash on ENOMEM"
20610
20611 test_235() {
20612         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20613                 skip "Need MDS version at least 2.4.52"
20614
20615         flock_deadlock $DIR/$tfile
20616         local RC=$?
20617         case $RC in
20618                 0)
20619                 ;;
20620                 124) error "process hangs on a deadlock"
20621                 ;;
20622                 *) error "error executing flock_deadlock $DIR/$tfile"
20623                 ;;
20624         esac
20625 }
20626 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20627
20628 #LU-2935
20629 test_236() {
20630         check_swap_layouts_support
20631
20632         local ref1=/etc/passwd
20633         local ref2=/etc/group
20634         local file1=$DIR/$tdir/f1
20635         local file2=$DIR/$tdir/f2
20636
20637         test_mkdir -c1 $DIR/$tdir
20638         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20639         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20640         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20641         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20642         local fd=$(free_fd)
20643         local cmd="exec $fd<>$file2"
20644         eval $cmd
20645         rm $file2
20646         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20647                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20648         cmd="exec $fd>&-"
20649         eval $cmd
20650         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20651
20652         #cleanup
20653         rm -rf $DIR/$tdir
20654 }
20655 run_test 236 "Layout swap on open unlinked file"
20656
20657 # LU-4659 linkea consistency
20658 test_238() {
20659         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20660                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20661                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20662                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20663
20664         touch $DIR/$tfile
20665         ln $DIR/$tfile $DIR/$tfile.lnk
20666         touch $DIR/$tfile.new
20667         mv $DIR/$tfile.new $DIR/$tfile
20668         local fid1=$($LFS path2fid $DIR/$tfile)
20669         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20670         local path1=$($LFS fid2path $FSNAME "$fid1")
20671         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20672         local path2=$($LFS fid2path $FSNAME "$fid2")
20673         [ $tfile.lnk == $path2 ] ||
20674                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20675         rm -f $DIR/$tfile*
20676 }
20677 run_test 238 "Verify linkea consistency"
20678
20679 test_239A() { # was test_239
20680         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20681                 skip "Need MDS version at least 2.5.60"
20682
20683         local list=$(comma_list $(mdts_nodes))
20684
20685         mkdir -p $DIR/$tdir
20686         createmany -o $DIR/$tdir/f- 5000
20687         unlinkmany $DIR/$tdir/f- 5000
20688         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20689                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20690         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20691                         osp.*MDT*.sync_in_flight" | calc_sum)
20692         [ "$changes" -eq 0 ] || error "$changes not synced"
20693 }
20694 run_test 239A "osp_sync test"
20695
20696 test_239a() { #LU-5297
20697         remote_mds_nodsh && skip "remote MDS with nodsh"
20698
20699         touch $DIR/$tfile
20700         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20701         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20702         chgrp $RUNAS_GID $DIR/$tfile
20703         wait_delete_completed
20704 }
20705 run_test 239a "process invalid osp sync record correctly"
20706
20707 test_239b() { #LU-5297
20708         remote_mds_nodsh && skip "remote MDS with nodsh"
20709
20710         touch $DIR/$tfile1
20711         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20712         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20713         chgrp $RUNAS_GID $DIR/$tfile1
20714         wait_delete_completed
20715         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20716         touch $DIR/$tfile2
20717         chgrp $RUNAS_GID $DIR/$tfile2
20718         wait_delete_completed
20719 }
20720 run_test 239b "process osp sync record with ENOMEM error correctly"
20721
20722 test_240() {
20723         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20724         remote_mds_nodsh && skip "remote MDS with nodsh"
20725
20726         mkdir -p $DIR/$tdir
20727
20728         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20729                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20730         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20731                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20732
20733         umount_client $MOUNT || error "umount failed"
20734         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20735         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20736         mount_client $MOUNT || error "failed to mount client"
20737
20738         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20739         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20740 }
20741 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20742
20743 test_241_bio() {
20744         local count=$1
20745         local bsize=$2
20746
20747         for LOOP in $(seq $count); do
20748                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20749                 cancel_lru_locks $OSC || true
20750         done
20751 }
20752
20753 test_241_dio() {
20754         local count=$1
20755         local bsize=$2
20756
20757         for LOOP in $(seq $1); do
20758                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20759                         2>/dev/null
20760         done
20761 }
20762
20763 test_241a() { # was test_241
20764         local bsize=$PAGE_SIZE
20765
20766         (( bsize < 40960 )) && bsize=40960
20767         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20768         ls -la $DIR/$tfile
20769         cancel_lru_locks $OSC
20770         test_241_bio 1000 $bsize &
20771         PID=$!
20772         test_241_dio 1000 $bsize
20773         wait $PID
20774 }
20775 run_test 241a "bio vs dio"
20776
20777 test_241b() {
20778         local bsize=$PAGE_SIZE
20779
20780         (( bsize < 40960 )) && bsize=40960
20781         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20782         ls -la $DIR/$tfile
20783         test_241_dio 1000 $bsize &
20784         PID=$!
20785         test_241_dio 1000 $bsize
20786         wait $PID
20787 }
20788 run_test 241b "dio vs dio"
20789
20790 test_242() {
20791         remote_mds_nodsh && skip "remote MDS with nodsh"
20792
20793         mkdir_on_mdt0 $DIR/$tdir
20794         touch $DIR/$tdir/$tfile
20795
20796         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20797         do_facet mds1 lctl set_param fail_loc=0x105
20798         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20799
20800         do_facet mds1 lctl set_param fail_loc=0
20801         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20802 }
20803 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20804
20805 test_243()
20806 {
20807         test_mkdir $DIR/$tdir
20808         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20809 }
20810 run_test 243 "various group lock tests"
20811
20812 test_244a()
20813 {
20814         test_mkdir $DIR/$tdir
20815         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20816         sendfile_grouplock $DIR/$tdir/$tfile || \
20817                 error "sendfile+grouplock failed"
20818         rm -rf $DIR/$tdir
20819 }
20820 run_test 244a "sendfile with group lock tests"
20821
20822 test_244b()
20823 {
20824         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20825
20826         local threads=50
20827         local size=$((1024*1024))
20828
20829         test_mkdir $DIR/$tdir
20830         for i in $(seq 1 $threads); do
20831                 local file=$DIR/$tdir/file_$((i / 10))
20832                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20833                 local pids[$i]=$!
20834         done
20835         for i in $(seq 1 $threads); do
20836                 wait ${pids[$i]}
20837         done
20838 }
20839 run_test 244b "multi-threaded write with group lock"
20840
20841 test_245() {
20842         local flagname="multi_mod_rpcs"
20843         local connect_data_name="max_mod_rpcs"
20844         local out
20845
20846         # check if multiple modify RPCs flag is set
20847         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20848                 grep "connect_flags:")
20849         echo "$out"
20850
20851         echo "$out" | grep -qw $flagname
20852         if [ $? -ne 0 ]; then
20853                 echo "connect flag $flagname is not set"
20854                 return
20855         fi
20856
20857         # check if multiple modify RPCs data is set
20858         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20859         echo "$out"
20860
20861         echo "$out" | grep -qw $connect_data_name ||
20862                 error "import should have connect data $connect_data_name"
20863 }
20864 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
20865
20866 cleanup_247() {
20867         local submount=$1
20868
20869         trap 0
20870         umount_client $submount
20871         rmdir $submount
20872 }
20873
20874 test_247a() {
20875         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20876                 grep -q subtree ||
20877                 skip_env "Fileset feature is not supported"
20878
20879         local submount=${MOUNT}_$tdir
20880
20881         mkdir $MOUNT/$tdir
20882         mkdir -p $submount || error "mkdir $submount failed"
20883         FILESET="$FILESET/$tdir" mount_client $submount ||
20884                 error "mount $submount failed"
20885         trap "cleanup_247 $submount" EXIT
20886         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
20887         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
20888                 error "read $MOUNT/$tdir/$tfile failed"
20889         cleanup_247 $submount
20890 }
20891 run_test 247a "mount subdir as fileset"
20892
20893 test_247b() {
20894         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20895                 skip_env "Fileset feature is not supported"
20896
20897         local submount=${MOUNT}_$tdir
20898
20899         rm -rf $MOUNT/$tdir
20900         mkdir -p $submount || error "mkdir $submount failed"
20901         SKIP_FILESET=1
20902         FILESET="$FILESET/$tdir" mount_client $submount &&
20903                 error "mount $submount should fail"
20904         rmdir $submount
20905 }
20906 run_test 247b "mount subdir that dose not exist"
20907
20908 test_247c() {
20909         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20910                 skip_env "Fileset feature is not supported"
20911
20912         local submount=${MOUNT}_$tdir
20913
20914         mkdir -p $MOUNT/$tdir/dir1
20915         mkdir -p $submount || error "mkdir $submount failed"
20916         trap "cleanup_247 $submount" EXIT
20917         FILESET="$FILESET/$tdir" mount_client $submount ||
20918                 error "mount $submount failed"
20919         local fid=$($LFS path2fid $MOUNT/)
20920         $LFS fid2path $submount $fid && error "fid2path should fail"
20921         cleanup_247 $submount
20922 }
20923 run_test 247c "running fid2path outside subdirectory root"
20924
20925 test_247d() {
20926         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20927                 skip "Fileset feature is not supported"
20928
20929         local submount=${MOUNT}_$tdir
20930
20931         mkdir -p $MOUNT/$tdir/dir1
20932         mkdir -p $submount || error "mkdir $submount failed"
20933         FILESET="$FILESET/$tdir" mount_client $submount ||
20934                 error "mount $submount failed"
20935         trap "cleanup_247 $submount" EXIT
20936
20937         local td=$submount/dir1
20938         local fid=$($LFS path2fid $td)
20939         [ -z "$fid" ] && error "path2fid unable to get $td FID"
20940
20941         # check that we get the same pathname back
20942         local rootpath
20943         local found
20944         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
20945                 echo "$rootpath $fid"
20946                 found=$($LFS fid2path $rootpath "$fid")
20947                 [ -n "found" ] || error "fid2path should succeed"
20948                 [ "$found" == "$td" ] || error "fid2path $found != $td"
20949         done
20950         # check wrong root path format
20951         rootpath=$submount"_wrong"
20952         found=$($LFS fid2path $rootpath "$fid")
20953         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
20954
20955         cleanup_247 $submount
20956 }
20957 run_test 247d "running fid2path inside subdirectory root"
20958
20959 # LU-8037
20960 test_247e() {
20961         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20962                 grep -q subtree ||
20963                 skip "Fileset feature is not supported"
20964
20965         local submount=${MOUNT}_$tdir
20966
20967         mkdir $MOUNT/$tdir
20968         mkdir -p $submount || error "mkdir $submount failed"
20969         FILESET="$FILESET/.." mount_client $submount &&
20970                 error "mount $submount should fail"
20971         rmdir $submount
20972 }
20973 run_test 247e "mount .. as fileset"
20974
20975 test_247f() {
20976         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20977         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20978                 skip "Need at least version 2.13.52"
20979         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20980                 skip "Need at least version 2.14.50"
20981         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20982                 grep -q subtree ||
20983                 skip "Fileset feature is not supported"
20984
20985         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20986         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
20987                 error "mkdir remote failed"
20988         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
20989                 error "mkdir remote/subdir failed"
20990         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
20991                 error "mkdir striped failed"
20992         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
20993
20994         local submount=${MOUNT}_$tdir
20995
20996         mkdir -p $submount || error "mkdir $submount failed"
20997         stack_trap "rmdir $submount"
20998
20999         local dir
21000         local stat
21001         local fileset=$FILESET
21002         local mdts=$(comma_list $(mdts_nodes))
21003
21004         stat=$(do_facet mds1 $LCTL get_param -n \
21005                 mdt.*MDT0000.enable_remote_subdir_mount)
21006         stack_trap "do_nodes $mdts $LCTL set_param \
21007                 mdt.*.enable_remote_subdir_mount=$stat"
21008
21009         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21010         stack_trap "umount_client $submount"
21011         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21012                 error "mount remote dir $dir should fail"
21013
21014         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21015                 $tdir/striped/. ; do
21016                 FILESET="$fileset/$dir" mount_client $submount ||
21017                         error "mount $dir failed"
21018                 umount_client $submount
21019         done
21020
21021         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21022         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21023                 error "mount $tdir/remote failed"
21024 }
21025 run_test 247f "mount striped or remote directory as fileset"
21026
21027 test_247g() {
21028         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21029         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21030                 skip "Need at least version 2.14.50"
21031
21032         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21033                 error "mkdir $tdir failed"
21034         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21035
21036         local submount=${MOUNT}_$tdir
21037
21038         mkdir -p $submount || error "mkdir $submount failed"
21039         stack_trap "rmdir $submount"
21040
21041         FILESET="$fileset/$tdir" mount_client $submount ||
21042                 error "mount $dir failed"
21043         stack_trap "umount $submount"
21044
21045         local mdts=$(comma_list $(mdts_nodes))
21046
21047         local nrpcs
21048
21049         stat $submount > /dev/null
21050         cancel_lru_locks $MDC
21051         stat $submount > /dev/null
21052         stat $submount/$tfile > /dev/null
21053         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21054         stat $submount/$tfile > /dev/null
21055         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21056                 awk '/getattr/ {sum += $2} END {print sum}')
21057
21058         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21059 }
21060 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21061
21062 test_248a() {
21063         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21064         [ -z "$fast_read_sav" ] && skip "no fast read support"
21065
21066         # create a large file for fast read verification
21067         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21068
21069         # make sure the file is created correctly
21070         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21071                 { rm -f $DIR/$tfile; skip "file creation error"; }
21072
21073         echo "Test 1: verify that fast read is 4 times faster on cache read"
21074
21075         # small read with fast read enabled
21076         $LCTL set_param -n llite.*.fast_read=1
21077         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21078                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21079                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21080         # small read with fast read disabled
21081         $LCTL set_param -n llite.*.fast_read=0
21082         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21083                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21084                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21085
21086         # verify that fast read is 4 times faster for cache read
21087         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21088                 error_not_in_vm "fast read was not 4 times faster: " \
21089                            "$t_fast vs $t_slow"
21090
21091         echo "Test 2: verify the performance between big and small read"
21092         $LCTL set_param -n llite.*.fast_read=1
21093
21094         # 1k non-cache read
21095         cancel_lru_locks osc
21096         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21097                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21098                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21099
21100         # 1M non-cache read
21101         cancel_lru_locks osc
21102         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21103                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21104                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21105
21106         # verify that big IO is not 4 times faster than small IO
21107         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21108                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21109
21110         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21111         rm -f $DIR/$tfile
21112 }
21113 run_test 248a "fast read verification"
21114
21115 test_248b() {
21116         # Default short_io_bytes=16384, try both smaller and larger sizes.
21117         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21118         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21119         echo "bs=53248 count=113 normal buffered write"
21120         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21121                 error "dd of initial data file failed"
21122         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21123
21124         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21125         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21126                 error "dd with sync normal writes failed"
21127         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21128
21129         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21130         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21131                 error "dd with sync small writes failed"
21132         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21133
21134         cancel_lru_locks osc
21135
21136         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21137         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21138         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21139         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21140                 iflag=direct || error "dd with O_DIRECT small read failed"
21141         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21142         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21143                 error "compare $TMP/$tfile.1 failed"
21144
21145         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21146         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21147
21148         # just to see what the maximum tunable value is, and test parsing
21149         echo "test invalid parameter 2MB"
21150         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21151                 error "too-large short_io_bytes allowed"
21152         echo "test maximum parameter 512KB"
21153         # if we can set a larger short_io_bytes, run test regardless of version
21154         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21155                 # older clients may not allow setting it this large, that's OK
21156                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21157                         skip "Need at least client version 2.13.50"
21158                 error "medium short_io_bytes failed"
21159         fi
21160         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21161         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21162
21163         echo "test large parameter 64KB"
21164         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21165         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21166
21167         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21168         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21169                 error "dd with sync large writes failed"
21170         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21171
21172         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21173         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21174         num=$((113 * 4096 / PAGE_SIZE))
21175         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21176         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21177                 error "dd with O_DIRECT large writes failed"
21178         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21179                 error "compare $DIR/$tfile.3 failed"
21180
21181         cancel_lru_locks osc
21182
21183         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21184         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21185                 error "dd with O_DIRECT large read failed"
21186         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21187                 error "compare $TMP/$tfile.2 failed"
21188
21189         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21190         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21191                 error "dd with O_DIRECT large read failed"
21192         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21193                 error "compare $TMP/$tfile.3 failed"
21194 }
21195 run_test 248b "test short_io read and write for both small and large sizes"
21196
21197 test_249() { # LU-7890
21198         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21199                 skip "Need at least version 2.8.54"
21200
21201         rm -f $DIR/$tfile
21202         $LFS setstripe -c 1 $DIR/$tfile
21203         # Offset 2T == 4k * 512M
21204         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21205                 error "dd to 2T offset failed"
21206 }
21207 run_test 249 "Write above 2T file size"
21208
21209 test_250() {
21210         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21211          && skip "no 16TB file size limit on ZFS"
21212
21213         $LFS setstripe -c 1 $DIR/$tfile
21214         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21215         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21216         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21217         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21218                 conv=notrunc,fsync && error "append succeeded"
21219         return 0
21220 }
21221 run_test 250 "Write above 16T limit"
21222
21223 test_251() {
21224         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21225
21226         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21227         #Skip once - writing the first stripe will succeed
21228         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21229         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21230                 error "short write happened"
21231
21232         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21233         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21234                 error "short read happened"
21235
21236         rm -f $DIR/$tfile
21237 }
21238 run_test 251 "Handling short read and write correctly"
21239
21240 test_252() {
21241         remote_mds_nodsh && skip "remote MDS with nodsh"
21242         remote_ost_nodsh && skip "remote OST with nodsh"
21243         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21244                 skip_env "ldiskfs only test"
21245         fi
21246
21247         local tgt
21248         local dev
21249         local out
21250         local uuid
21251         local num
21252         local gen
21253
21254         # check lr_reader on OST0000
21255         tgt=ost1
21256         dev=$(facet_device $tgt)
21257         out=$(do_facet $tgt $LR_READER $dev)
21258         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21259         echo "$out"
21260         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21261         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21262                 error "Invalid uuid returned by $LR_READER on target $tgt"
21263         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21264
21265         # check lr_reader -c on MDT0000
21266         tgt=mds1
21267         dev=$(facet_device $tgt)
21268         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21269                 skip "$LR_READER does not support additional options"
21270         fi
21271         out=$(do_facet $tgt $LR_READER -c $dev)
21272         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21273         echo "$out"
21274         num=$(echo "$out" | grep -c "mdtlov")
21275         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21276                 error "Invalid number of mdtlov clients returned by $LR_READER"
21277         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21278
21279         # check lr_reader -cr on MDT0000
21280         out=$(do_facet $tgt $LR_READER -cr $dev)
21281         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21282         echo "$out"
21283         echo "$out" | grep -q "^reply_data:$" ||
21284                 error "$LR_READER should have returned 'reply_data' section"
21285         num=$(echo "$out" | grep -c "client_generation")
21286         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21287 }
21288 run_test 252 "check lr_reader tool"
21289
21290 test_253() {
21291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21292         remote_mds_nodsh && skip "remote MDS with nodsh"
21293         remote_mgs_nodsh && skip "remote MGS with nodsh"
21294
21295         local ostidx=0
21296         local rc=0
21297         local ost_name=$(ostname_from_index $ostidx)
21298
21299         # on the mdt's osc
21300         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21301         do_facet $SINGLEMDS $LCTL get_param -n \
21302                 osp.$mdtosc_proc1.reserved_mb_high ||
21303                 skip  "remote MDS does not support reserved_mb_high"
21304
21305         rm -rf $DIR/$tdir
21306         wait_mds_ost_sync
21307         wait_delete_completed
21308         mkdir $DIR/$tdir
21309
21310         pool_add $TESTNAME || error "Pool creation failed"
21311         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21312
21313         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21314                 error "Setstripe failed"
21315
21316         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21317
21318         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21319                     grep "watermarks")
21320         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21321
21322         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21323                         osp.$mdtosc_proc1.prealloc_status)
21324         echo "prealloc_status $oa_status"
21325
21326         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21327                 error "File creation should fail"
21328
21329         #object allocation was stopped, but we still able to append files
21330         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21331                 oflag=append || error "Append failed"
21332
21333         rm -f $DIR/$tdir/$tfile.0
21334
21335         # For this test, we want to delete the files we created to go out of
21336         # space but leave the watermark, so we remain nearly out of space
21337         ost_watermarks_enospc_delete_files $tfile $ostidx
21338
21339         wait_delete_completed
21340
21341         sleep_maxage
21342
21343         for i in $(seq 10 12); do
21344                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21345                         2>/dev/null || error "File creation failed after rm"
21346         done
21347
21348         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21349                         osp.$mdtosc_proc1.prealloc_status)
21350         echo "prealloc_status $oa_status"
21351
21352         if (( oa_status != 0 )); then
21353                 error "Object allocation still disable after rm"
21354         fi
21355 }
21356 run_test 253 "Check object allocation limit"
21357
21358 test_254() {
21359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21360         remote_mds_nodsh && skip "remote MDS with nodsh"
21361
21362         local mdt=$(facet_svc $SINGLEMDS)
21363
21364         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21365                 skip "MDS does not support changelog_size"
21366
21367         local cl_user
21368
21369         changelog_register || error "changelog_register failed"
21370
21371         changelog_clear 0 || error "changelog_clear failed"
21372
21373         local size1=$(do_facet $SINGLEMDS \
21374                       $LCTL get_param -n mdd.$mdt.changelog_size)
21375         echo "Changelog size $size1"
21376
21377         rm -rf $DIR/$tdir
21378         $LFS mkdir -i 0 $DIR/$tdir
21379         # change something
21380         mkdir -p $DIR/$tdir/pics/2008/zachy
21381         touch $DIR/$tdir/pics/2008/zachy/timestamp
21382         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21383         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21384         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21385         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21386         rm $DIR/$tdir/pics/desktop.jpg
21387
21388         local size2=$(do_facet $SINGLEMDS \
21389                       $LCTL get_param -n mdd.$mdt.changelog_size)
21390         echo "Changelog size after work $size2"
21391
21392         (( $size2 > $size1 )) ||
21393                 error "new Changelog size=$size2 less than old size=$size1"
21394 }
21395 run_test 254 "Check changelog size"
21396
21397 ladvise_no_type()
21398 {
21399         local type=$1
21400         local file=$2
21401
21402         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21403                 awk -F: '{print $2}' | grep $type > /dev/null
21404         if [ $? -ne 0 ]; then
21405                 return 0
21406         fi
21407         return 1
21408 }
21409
21410 ladvise_no_ioctl()
21411 {
21412         local file=$1
21413
21414         lfs ladvise -a willread $file > /dev/null 2>&1
21415         if [ $? -eq 0 ]; then
21416                 return 1
21417         fi
21418
21419         lfs ladvise -a willread $file 2>&1 |
21420                 grep "Inappropriate ioctl for device" > /dev/null
21421         if [ $? -eq 0 ]; then
21422                 return 0
21423         fi
21424         return 1
21425 }
21426
21427 percent() {
21428         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21429 }
21430
21431 # run a random read IO workload
21432 # usage: random_read_iops <filename> <filesize> <iosize>
21433 random_read_iops() {
21434         local file=$1
21435         local fsize=$2
21436         local iosize=${3:-4096}
21437
21438         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21439                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21440 }
21441
21442 drop_file_oss_cache() {
21443         local file="$1"
21444         local nodes="$2"
21445
21446         $LFS ladvise -a dontneed $file 2>/dev/null ||
21447                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21448 }
21449
21450 ladvise_willread_performance()
21451 {
21452         local repeat=10
21453         local average_origin=0
21454         local average_cache=0
21455         local average_ladvise=0
21456
21457         for ((i = 1; i <= $repeat; i++)); do
21458                 echo "Iter $i/$repeat: reading without willread hint"
21459                 cancel_lru_locks osc
21460                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21461                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21462                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21463                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21464
21465                 cancel_lru_locks osc
21466                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21467                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21468                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21469
21470                 cancel_lru_locks osc
21471                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21472                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21473                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21474                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21475                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21476         done
21477         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21478         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21479         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21480
21481         speedup_cache=$(percent $average_cache $average_origin)
21482         speedup_ladvise=$(percent $average_ladvise $average_origin)
21483
21484         echo "Average uncached read: $average_origin"
21485         echo "Average speedup with OSS cached read: " \
21486                 "$average_cache = +$speedup_cache%"
21487         echo "Average speedup with ladvise willread: " \
21488                 "$average_ladvise = +$speedup_ladvise%"
21489
21490         local lowest_speedup=20
21491         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
21492                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
21493                         "got $average_cache%. Skipping ladvise willread check."
21494                 return 0
21495         fi
21496
21497         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21498         # it is still good to run until then to exercise 'ladvise willread'
21499         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21500                 [ "$ost1_FSTYPE" = "zfs" ] &&
21501                 echo "osd-zfs does not support dontneed or drop_caches" &&
21502                 return 0
21503
21504         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21505         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
21506                 error_not_in_vm "Speedup with willread is less than " \
21507                         "$lowest_speedup%, got $average_ladvise%"
21508 }
21509
21510 test_255a() {
21511         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21512                 skip "lustre < 2.8.54 does not support ladvise "
21513         remote_ost_nodsh && skip "remote OST with nodsh"
21514
21515         stack_trap "rm -f $DIR/$tfile"
21516         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21517
21518         ladvise_no_type willread $DIR/$tfile &&
21519                 skip "willread ladvise is not supported"
21520
21521         ladvise_no_ioctl $DIR/$tfile &&
21522                 skip "ladvise ioctl is not supported"
21523
21524         local size_mb=100
21525         local size=$((size_mb * 1048576))
21526         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21527                 error "dd to $DIR/$tfile failed"
21528
21529         lfs ladvise -a willread $DIR/$tfile ||
21530                 error "Ladvise failed with no range argument"
21531
21532         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21533                 error "Ladvise failed with no -l or -e argument"
21534
21535         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21536                 error "Ladvise failed with only -e argument"
21537
21538         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21539                 error "Ladvise failed with only -l argument"
21540
21541         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21542                 error "End offset should not be smaller than start offset"
21543
21544         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21545                 error "End offset should not be equal to start offset"
21546
21547         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21548                 error "Ladvise failed with overflowing -s argument"
21549
21550         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21551                 error "Ladvise failed with overflowing -e argument"
21552
21553         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21554                 error "Ladvise failed with overflowing -l argument"
21555
21556         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21557                 error "Ladvise succeeded with conflicting -l and -e arguments"
21558
21559         echo "Synchronous ladvise should wait"
21560         local delay=4
21561 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21562         do_nodes $(comma_list $(osts_nodes)) \
21563                 $LCTL set_param fail_val=$delay fail_loc=0x237
21564
21565         local start_ts=$SECONDS
21566         lfs ladvise -a willread $DIR/$tfile ||
21567                 error "Ladvise failed with no range argument"
21568         local end_ts=$SECONDS
21569         local inteval_ts=$((end_ts - start_ts))
21570
21571         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21572                 error "Synchronous advice didn't wait reply"
21573         fi
21574
21575         echo "Asynchronous ladvise shouldn't wait"
21576         local start_ts=$SECONDS
21577         lfs ladvise -a willread -b $DIR/$tfile ||
21578                 error "Ladvise failed with no range argument"
21579         local end_ts=$SECONDS
21580         local inteval_ts=$((end_ts - start_ts))
21581
21582         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21583                 error "Asynchronous advice blocked"
21584         fi
21585
21586         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21587         ladvise_willread_performance
21588 }
21589 run_test 255a "check 'lfs ladvise -a willread'"
21590
21591 facet_meminfo() {
21592         local facet=$1
21593         local info=$2
21594
21595         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21596 }
21597
21598 test_255b() {
21599         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21600                 skip "lustre < 2.8.54 does not support ladvise "
21601         remote_ost_nodsh && skip "remote OST with nodsh"
21602
21603         stack_trap "rm -f $DIR/$tfile"
21604         lfs setstripe -c 1 -i 0 $DIR/$tfile
21605
21606         ladvise_no_type dontneed $DIR/$tfile &&
21607                 skip "dontneed ladvise is not supported"
21608
21609         ladvise_no_ioctl $DIR/$tfile &&
21610                 skip "ladvise ioctl is not supported"
21611
21612         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21613                 [ "$ost1_FSTYPE" = "zfs" ] &&
21614                 skip "zfs-osd does not support 'ladvise dontneed'"
21615
21616         local size_mb=100
21617         local size=$((size_mb * 1048576))
21618         # In order to prevent disturbance of other processes, only check 3/4
21619         # of the memory usage
21620         local kibibytes=$((size_mb * 1024 * 3 / 4))
21621
21622         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21623                 error "dd to $DIR/$tfile failed"
21624
21625         #force write to complete before dropping OST cache & checking memory
21626         sync
21627
21628         local total=$(facet_meminfo ost1 MemTotal)
21629         echo "Total memory: $total KiB"
21630
21631         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21632         local before_read=$(facet_meminfo ost1 Cached)
21633         echo "Cache used before read: $before_read KiB"
21634
21635         lfs ladvise -a willread $DIR/$tfile ||
21636                 error "Ladvise willread failed"
21637         local after_read=$(facet_meminfo ost1 Cached)
21638         echo "Cache used after read: $after_read KiB"
21639
21640         lfs ladvise -a dontneed $DIR/$tfile ||
21641                 error "Ladvise dontneed again failed"
21642         local no_read=$(facet_meminfo ost1 Cached)
21643         echo "Cache used after dontneed ladvise: $no_read KiB"
21644
21645         if [ $total -lt $((before_read + kibibytes)) ]; then
21646                 echo "Memory is too small, abort checking"
21647                 return 0
21648         fi
21649
21650         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21651                 error "Ladvise willread should use more memory" \
21652                         "than $kibibytes KiB"
21653         fi
21654
21655         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21656                 error "Ladvise dontneed should release more memory" \
21657                         "than $kibibytes KiB"
21658         fi
21659 }
21660 run_test 255b "check 'lfs ladvise -a dontneed'"
21661
21662 test_255c() {
21663         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21664                 skip "lustre < 2.10.50 does not support lockahead"
21665
21666         local ost1_imp=$(get_osc_import_name client ost1)
21667         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21668                          cut -d'.' -f2)
21669         local count
21670         local new_count
21671         local difference
21672         local i
21673         local rc
21674
21675         test_mkdir -p $DIR/$tdir
21676         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21677
21678         #test 10 returns only success/failure
21679         i=10
21680         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21681         rc=$?
21682         if [ $rc -eq 255 ]; then
21683                 error "Ladvise test${i} failed, ${rc}"
21684         fi
21685
21686         #test 11 counts lock enqueue requests, all others count new locks
21687         i=11
21688         count=$(do_facet ost1 \
21689                 $LCTL get_param -n ost.OSS.ost.stats)
21690         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21691
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         new_count=$(do_facet ost1 \
21699                 $LCTL get_param -n ost.OSS.ost.stats)
21700         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21701                    awk '{ print $2 }')
21702
21703         difference="$((new_count - count))"
21704         if [ $difference -ne $rc ]; then
21705                 error "Ladvise test${i}, bad enqueue count, returned " \
21706                       "${rc}, actual ${difference}"
21707         fi
21708
21709         for i in $(seq 12 21); do
21710                 # If we do not do this, we run the risk of having too many
21711                 # locks and starting lock cancellation while we are checking
21712                 # lock counts.
21713                 cancel_lru_locks osc
21714
21715                 count=$($LCTL get_param -n \
21716                        ldlm.namespaces.$imp_name.lock_unused_count)
21717
21718                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21719                 rc=$?
21720                 if [ $rc -eq 255 ]; then
21721                         error "Ladvise test ${i} failed, ${rc}"
21722                 fi
21723
21724                 new_count=$($LCTL get_param -n \
21725                        ldlm.namespaces.$imp_name.lock_unused_count)
21726                 difference="$((new_count - count))"
21727
21728                 # Test 15 output is divided by 100 to map down to valid return
21729                 if [ $i -eq 15 ]; then
21730                         rc="$((rc * 100))"
21731                 fi
21732
21733                 if [ $difference -ne $rc ]; then
21734                         error "Ladvise test ${i}, bad lock count, returned " \
21735                               "${rc}, actual ${difference}"
21736                 fi
21737         done
21738
21739         #test 22 returns only success/failure
21740         i=22
21741         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21742         rc=$?
21743         if [ $rc -eq 255 ]; then
21744                 error "Ladvise test${i} failed, ${rc}"
21745         fi
21746 }
21747 run_test 255c "suite of ladvise lockahead tests"
21748
21749 test_256() {
21750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21751         remote_mds_nodsh && skip "remote MDS with nodsh"
21752         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21753         changelog_users $SINGLEMDS | grep "^cl" &&
21754                 skip "active changelog user"
21755
21756         local cl_user
21757         local cat_sl
21758         local mdt_dev
21759
21760         mdt_dev=$(mdsdevname 1)
21761         echo $mdt_dev
21762
21763         changelog_register || error "changelog_register failed"
21764
21765         rm -rf $DIR/$tdir
21766         mkdir_on_mdt0 $DIR/$tdir
21767
21768         changelog_clear 0 || error "changelog_clear failed"
21769
21770         # change something
21771         touch $DIR/$tdir/{1..10}
21772
21773         # stop the MDT
21774         stop $SINGLEMDS || error "Fail to stop MDT"
21775
21776         # remount the MDT
21777
21778         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
21779
21780         #after mount new plainllog is used
21781         touch $DIR/$tdir/{11..19}
21782         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21783         stack_trap "rm -f $tmpfile"
21784         cat_sl=$(do_facet $SINGLEMDS "sync; \
21785                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21786                  llog_reader $tmpfile | grep -c type=1064553b")
21787         do_facet $SINGLEMDS llog_reader $tmpfile
21788
21789         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21790
21791         changelog_clear 0 || error "changelog_clear failed"
21792
21793         cat_sl=$(do_facet $SINGLEMDS "sync; \
21794                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21795                  llog_reader $tmpfile | grep -c type=1064553b")
21796
21797         if (( cat_sl == 2 )); then
21798                 error "Empty plain llog was not deleted from changelog catalog"
21799         elif (( cat_sl != 1 )); then
21800                 error "Active plain llog shouldn't be deleted from catalog"
21801         fi
21802 }
21803 run_test 256 "Check llog delete for empty and not full state"
21804
21805 test_257() {
21806         remote_mds_nodsh && skip "remote MDS with nodsh"
21807         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21808                 skip "Need MDS version at least 2.8.55"
21809
21810         test_mkdir $DIR/$tdir
21811
21812         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21813                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21814         stat $DIR/$tdir
21815
21816 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21817         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21818         local facet=mds$((mdtidx + 1))
21819         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21820         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21821
21822         stop $facet || error "stop MDS failed"
21823         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21824                 error "start MDS fail"
21825         wait_recovery_complete $facet
21826 }
21827 run_test 257 "xattr locks are not lost"
21828
21829 # Verify we take the i_mutex when security requires it
21830 test_258a() {
21831 #define OBD_FAIL_IMUTEX_SEC 0x141c
21832         $LCTL set_param fail_loc=0x141c
21833         touch $DIR/$tfile
21834         chmod u+s $DIR/$tfile
21835         chmod a+rwx $DIR/$tfile
21836         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21837         RC=$?
21838         if [ $RC -ne 0 ]; then
21839                 error "error, failed to take i_mutex, rc=$?"
21840         fi
21841         rm -f $DIR/$tfile
21842 }
21843 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21844
21845 # Verify we do NOT take the i_mutex in the normal case
21846 test_258b() {
21847 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21848         $LCTL set_param fail_loc=0x141d
21849         touch $DIR/$tfile
21850         chmod a+rwx $DIR
21851         chmod a+rw $DIR/$tfile
21852         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21853         RC=$?
21854         if [ $RC -ne 0 ]; then
21855                 error "error, took i_mutex unnecessarily, rc=$?"
21856         fi
21857         rm -f $DIR/$tfile
21858
21859 }
21860 run_test 258b "verify i_mutex security behavior"
21861
21862 test_259() {
21863         local file=$DIR/$tfile
21864         local before
21865         local after
21866
21867         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21868
21869         stack_trap "rm -f $file" EXIT
21870
21871         wait_delete_completed
21872         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21873         echo "before: $before"
21874
21875         $LFS setstripe -i 0 -c 1 $file
21876         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21877         sync_all_data
21878         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21879         echo "after write: $after"
21880
21881 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
21882         do_facet ost1 $LCTL set_param fail_loc=0x2301
21883         $TRUNCATE $file 0
21884         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21885         echo "after truncate: $after"
21886
21887         stop ost1
21888         do_facet ost1 $LCTL set_param fail_loc=0
21889         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21890         sleep 2
21891         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21892         echo "after restart: $after"
21893         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
21894                 error "missing truncate?"
21895
21896         return 0
21897 }
21898 run_test 259 "crash at delayed truncate"
21899
21900 test_260() {
21901 #define OBD_FAIL_MDC_CLOSE               0x806
21902         $LCTL set_param fail_loc=0x80000806
21903         touch $DIR/$tfile
21904
21905 }
21906 run_test 260 "Check mdc_close fail"
21907
21908 ### Data-on-MDT sanity tests ###
21909 test_270a() {
21910         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21911                 skip "Need MDS version at least 2.10.55 for DoM"
21912
21913         # create DoM file
21914         local dom=$DIR/$tdir/dom_file
21915         local tmp=$DIR/$tdir/tmp_file
21916
21917         mkdir_on_mdt0 $DIR/$tdir
21918
21919         # basic checks for DoM component creation
21920         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
21921                 error "Can set MDT layout to non-first entry"
21922
21923         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
21924                 error "Can define multiple entries as MDT layout"
21925
21926         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
21927
21928         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
21929         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
21930         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
21931
21932         local mdtidx=$($LFS getstripe -m $dom)
21933         local mdtname=MDT$(printf %04x $mdtidx)
21934         local facet=mds$((mdtidx + 1))
21935         local space_check=1
21936
21937         # Skip free space checks with ZFS
21938         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
21939
21940         # write
21941         sync
21942         local size_tmp=$((65536 * 3))
21943         local mdtfree1=$(do_facet $facet \
21944                          lctl get_param -n osd*.*$mdtname.kbytesfree)
21945
21946         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21947         # check also direct IO along write
21948         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
21949         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21950         sync
21951         cmp $tmp $dom || error "file data is different"
21952         [ $(stat -c%s $dom) == $size_tmp ] ||
21953                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21954         if [ $space_check == 1 ]; then
21955                 local mdtfree2=$(do_facet $facet \
21956                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
21957
21958                 # increase in usage from by $size_tmp
21959                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21960                         error "MDT free space wrong after write: " \
21961                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21962         fi
21963
21964         # truncate
21965         local size_dom=10000
21966
21967         $TRUNCATE $dom $size_dom
21968         [ $(stat -c%s $dom) == $size_dom ] ||
21969                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
21970         if [ $space_check == 1 ]; then
21971                 mdtfree1=$(do_facet $facet \
21972                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21973                 # decrease in usage from $size_tmp to new $size_dom
21974                 [ $(($mdtfree1 - $mdtfree2)) -ge \
21975                   $(((size_tmp - size_dom) / 1024)) ] ||
21976                         error "MDT free space is wrong after truncate: " \
21977                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
21978         fi
21979
21980         # append
21981         cat $tmp >> $dom
21982         sync
21983         size_dom=$((size_dom + size_tmp))
21984         [ $(stat -c%s $dom) == $size_dom ] ||
21985                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
21986         if [ $space_check == 1 ]; then
21987                 mdtfree2=$(do_facet $facet \
21988                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21989                 # increase in usage by $size_tmp from previous
21990                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21991                         error "MDT free space is wrong after append: " \
21992                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21993         fi
21994
21995         # delete
21996         rm $dom
21997         if [ $space_check == 1 ]; then
21998                 mdtfree1=$(do_facet $facet \
21999                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22000                 # decrease in usage by $size_dom from previous
22001                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22002                         error "MDT free space is wrong after removal: " \
22003                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22004         fi
22005
22006         # combined striping
22007         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22008                 error "Can't create DoM + OST striping"
22009
22010         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22011         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22012         # check also direct IO along write
22013         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22014         sync
22015         cmp $tmp $dom || error "file data is different"
22016         [ $(stat -c%s $dom) == $size_tmp ] ||
22017                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22018         rm $dom $tmp
22019
22020         return 0
22021 }
22022 run_test 270a "DoM: basic functionality tests"
22023
22024 test_270b() {
22025         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22026                 skip "Need MDS version at least 2.10.55"
22027
22028         local dom=$DIR/$tdir/dom_file
22029         local max_size=1048576
22030
22031         mkdir -p $DIR/$tdir
22032         $LFS setstripe -E $max_size -L mdt $dom
22033
22034         # truncate over the limit
22035         $TRUNCATE $dom $(($max_size + 1)) &&
22036                 error "successful truncate over the maximum size"
22037         # write over the limit
22038         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22039                 error "successful write over the maximum size"
22040         # append over the limit
22041         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22042         echo "12345" >> $dom && error "successful append over the maximum size"
22043         rm $dom
22044
22045         return 0
22046 }
22047 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22048
22049 test_270c() {
22050         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22051                 skip "Need MDS version at least 2.10.55"
22052
22053         mkdir -p $DIR/$tdir
22054         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22055
22056         # check files inherit DoM EA
22057         touch $DIR/$tdir/first
22058         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22059                 error "bad pattern"
22060         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22061                 error "bad stripe count"
22062         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22063                 error "bad stripe size"
22064
22065         # check directory inherits DoM EA and uses it as default
22066         mkdir $DIR/$tdir/subdir
22067         touch $DIR/$tdir/subdir/second
22068         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22069                 error "bad pattern in sub-directory"
22070         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22071                 error "bad stripe count in sub-directory"
22072         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22073                 error "bad stripe size in sub-directory"
22074         return 0
22075 }
22076 run_test 270c "DoM: DoM EA inheritance tests"
22077
22078 test_270d() {
22079         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22080                 skip "Need MDS version at least 2.10.55"
22081
22082         mkdir -p $DIR/$tdir
22083         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22084
22085         # inherit default DoM striping
22086         mkdir $DIR/$tdir/subdir
22087         touch $DIR/$tdir/subdir/f1
22088
22089         # change default directory striping
22090         $LFS setstripe -c 1 $DIR/$tdir/subdir
22091         touch $DIR/$tdir/subdir/f2
22092         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22093                 error "wrong default striping in file 2"
22094         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22095                 error "bad pattern in file 2"
22096         return 0
22097 }
22098 run_test 270d "DoM: change striping from DoM to RAID0"
22099
22100 test_270e() {
22101         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22102                 skip "Need MDS version at least 2.10.55"
22103
22104         mkdir -p $DIR/$tdir/dom
22105         mkdir -p $DIR/$tdir/norm
22106         DOMFILES=20
22107         NORMFILES=10
22108         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22109         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22110
22111         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22112         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22113
22114         # find DoM files by layout
22115         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22116         [ $NUM -eq  $DOMFILES ] ||
22117                 error "lfs find -L: found $NUM, expected $DOMFILES"
22118         echo "Test 1: lfs find 20 DOM files by layout: OK"
22119
22120         # there should be 1 dir with default DOM striping
22121         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22122         [ $NUM -eq  1 ] ||
22123                 error "lfs find -L: found $NUM, expected 1 dir"
22124         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22125
22126         # find DoM files by stripe size
22127         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22128         [ $NUM -eq  $DOMFILES ] ||
22129                 error "lfs find -S: found $NUM, expected $DOMFILES"
22130         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22131
22132         # find files by stripe offset except DoM files
22133         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22134         [ $NUM -eq  $NORMFILES ] ||
22135                 error "lfs find -i: found $NUM, expected $NORMFILES"
22136         echo "Test 5: lfs find no DOM files by stripe index: OK"
22137         return 0
22138 }
22139 run_test 270e "DoM: lfs find with DoM files test"
22140
22141 test_270f() {
22142         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22143                 skip "Need MDS version at least 2.10.55"
22144
22145         local mdtname=${FSNAME}-MDT0000-mdtlov
22146         local dom=$DIR/$tdir/dom_file
22147         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22148                                                 lod.$mdtname.dom_stripesize)
22149         local dom_limit=131072
22150
22151         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22152         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22153                                                 lod.$mdtname.dom_stripesize)
22154         [ ${dom_limit} -eq ${dom_current} ] ||
22155                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22156
22157         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22158         $LFS setstripe -d $DIR/$tdir
22159         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22160                 error "Can't set directory default striping"
22161
22162         # exceed maximum stripe size
22163         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22164                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22165         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22166                 error "Able to create DoM component size more than LOD limit"
22167
22168         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22169         dom_current=$(do_facet mds1 $LCTL get_param -n \
22170                                                 lod.$mdtname.dom_stripesize)
22171         [ 0 -eq ${dom_current} ] ||
22172                 error "Can't set zero DoM stripe limit"
22173         rm $dom
22174
22175         # attempt to create DoM file on server with disabled DoM should
22176         # remove DoM entry from layout and be succeed
22177         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22178                 error "Can't create DoM file (DoM is disabled)"
22179         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22180                 error "File has DoM component while DoM is disabled"
22181         rm $dom
22182
22183         # attempt to create DoM file with only DoM stripe should return error
22184         $LFS setstripe -E $dom_limit -L mdt $dom &&
22185                 error "Able to create DoM-only file while DoM is disabled"
22186
22187         # too low values to be aligned with smallest stripe size 64K
22188         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22189         dom_current=$(do_facet mds1 $LCTL get_param -n \
22190                                                 lod.$mdtname.dom_stripesize)
22191         [ 30000 -eq ${dom_current} ] &&
22192                 error "Can set too small DoM stripe limit"
22193
22194         # 64K is a minimal stripe size in Lustre, expect limit of that size
22195         [ 65536 -eq ${dom_current} ] ||
22196                 error "Limit is not set to 64K but ${dom_current}"
22197
22198         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22199         dom_current=$(do_facet mds1 $LCTL get_param -n \
22200                                                 lod.$mdtname.dom_stripesize)
22201         echo $dom_current
22202         [ 2147483648 -eq ${dom_current} ] &&
22203                 error "Can set too large DoM stripe limit"
22204
22205         do_facet mds1 $LCTL set_param -n \
22206                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22207         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22208                 error "Can't create DoM component size after limit change"
22209         do_facet mds1 $LCTL set_param -n \
22210                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22211         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22212                 error "Can't create DoM file after limit decrease"
22213         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22214                 error "Can create big DoM component after limit decrease"
22215         touch ${dom}_def ||
22216                 error "Can't create file with old default layout"
22217
22218         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22219         return 0
22220 }
22221 run_test 270f "DoM: maximum DoM stripe size checks"
22222
22223 test_270g() {
22224         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22225                 skip "Need MDS version at least 2.13.52"
22226         local dom=$DIR/$tdir/$tfile
22227
22228         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22229         local lodname=${FSNAME}-MDT0000-mdtlov
22230
22231         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22232         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22233         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22234         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22235
22236         local dom_limit=1024
22237         local dom_threshold="50%"
22238
22239         $LFS setstripe -d $DIR/$tdir
22240         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22241                 error "Can't set directory default striping"
22242
22243         do_facet mds1 $LCTL set_param -n \
22244                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22245         # set 0 threshold and create DOM file to change tunable stripesize
22246         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22247         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22248                 error "Failed to create $dom file"
22249         # now tunable dom_cur_stripesize should reach maximum
22250         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22251                                         lod.${lodname}.dom_stripesize_cur_kb)
22252         [[ $dom_current == $dom_limit ]] ||
22253                 error "Current DOM stripesize is not maximum"
22254         rm $dom
22255
22256         # set threshold for further tests
22257         do_facet mds1 $LCTL set_param -n \
22258                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22259         echo "DOM threshold is $dom_threshold free space"
22260         local dom_def
22261         local dom_set
22262         # Spoof bfree to exceed threshold
22263         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22264         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22265         for spfree in 40 20 0 15 30 55; do
22266                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22267                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22268                         error "Failed to create $dom file"
22269                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22270                                         lod.${lodname}.dom_stripesize_cur_kb)
22271                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22272                 [[ $dom_def != $dom_current ]] ||
22273                         error "Default stripe size was not changed"
22274                 if [[ $spfree > 0 ]] ; then
22275                         dom_set=$($LFS getstripe -S $dom)
22276                         [[ $dom_set == $((dom_def * 1024)) ]] ||
22277                                 error "DOM component size is still old"
22278                 else
22279                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22280                                 error "DoM component is set with no free space"
22281                 fi
22282                 rm $dom
22283                 dom_current=$dom_def
22284         done
22285 }
22286 run_test 270g "DoM: default DoM stripe size depends on free space"
22287
22288 test_270h() {
22289         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22290                 skip "Need MDS version at least 2.13.53"
22291
22292         local mdtname=${FSNAME}-MDT0000-mdtlov
22293         local dom=$DIR/$tdir/$tfile
22294         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22295
22296         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22297         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22298
22299         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22300         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22301                 error "can't create OST file"
22302         # mirrored file with DOM entry in the second mirror
22303         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22304                 error "can't create mirror with DoM component"
22305
22306         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22307
22308         # DOM component in the middle and has other enries in the same mirror,
22309         # should succeed but lost DoM component
22310         $LFS setstripe --copy=${dom}_1 $dom ||
22311                 error "Can't create file from OST|DOM mirror layout"
22312         # check new file has no DoM layout after all
22313         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22314                 error "File has DoM component while DoM is disabled"
22315 }
22316 run_test 270h "DoM: DoM stripe removal when disabled on server"
22317
22318 test_270i() {
22319         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22320                 skip "Need MDS version at least 2.14.54"
22321
22322         mkdir $DIR/$tdir
22323         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22324                 error "setstripe should fail" || true
22325 }
22326 run_test 270i "DoM: setting invalid DoM striping should fail"
22327
22328 test_271a() {
22329         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22330                 skip "Need MDS version at least 2.10.55"
22331
22332         local dom=$DIR/$tdir/dom
22333
22334         mkdir -p $DIR/$tdir
22335
22336         $LFS setstripe -E 1024K -L mdt $dom
22337
22338         lctl set_param -n mdc.*.stats=clear
22339         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22340         cat $dom > /dev/null
22341         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22342         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22343         ls $dom
22344         rm -f $dom
22345 }
22346 run_test 271a "DoM: data is cached for read after write"
22347
22348 test_271b() {
22349         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22350                 skip "Need MDS version at least 2.10.55"
22351
22352         local dom=$DIR/$tdir/dom
22353
22354         mkdir -p $DIR/$tdir
22355
22356         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22357
22358         lctl set_param -n mdc.*.stats=clear
22359         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22360         cancel_lru_locks mdc
22361         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22362         # second stat to check size is cached on client
22363         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22364         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22365         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22366         rm -f $dom
22367 }
22368 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22369
22370 test_271ba() {
22371         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22372                 skip "Need MDS version at least 2.10.55"
22373
22374         local dom=$DIR/$tdir/dom
22375
22376         mkdir -p $DIR/$tdir
22377
22378         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22379
22380         lctl set_param -n mdc.*.stats=clear
22381         lctl set_param -n osc.*.stats=clear
22382         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22383         cancel_lru_locks mdc
22384         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22385         # second stat to check size is cached on client
22386         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22387         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22388         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22389         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22390         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22391         rm -f $dom
22392 }
22393 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22394
22395
22396 get_mdc_stats() {
22397         local mdtidx=$1
22398         local param=$2
22399         local mdt=MDT$(printf %04x $mdtidx)
22400
22401         if [ -z $param ]; then
22402                 lctl get_param -n mdc.*$mdt*.stats
22403         else
22404                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22405         fi
22406 }
22407
22408 test_271c() {
22409         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22410                 skip "Need MDS version at least 2.10.55"
22411
22412         local dom=$DIR/$tdir/dom
22413
22414         mkdir -p $DIR/$tdir
22415
22416         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22417
22418         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22419         local facet=mds$((mdtidx + 1))
22420
22421         cancel_lru_locks mdc
22422         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22423         createmany -o $dom 1000
22424         lctl set_param -n mdc.*.stats=clear
22425         smalliomany -w $dom 1000 200
22426         get_mdc_stats $mdtidx
22427         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22428         # Each file has 1 open, 1 IO enqueues, total 2000
22429         # but now we have also +1 getxattr for security.capability, total 3000
22430         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22431         unlinkmany $dom 1000
22432
22433         cancel_lru_locks mdc
22434         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22435         createmany -o $dom 1000
22436         lctl set_param -n mdc.*.stats=clear
22437         smalliomany -w $dom 1000 200
22438         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22439         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22440         # for OPEN and IO lock.
22441         [ $((enq - enq_2)) -ge 1000 ] ||
22442                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22443         unlinkmany $dom 1000
22444         return 0
22445 }
22446 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22447
22448 cleanup_271def_tests() {
22449         trap 0
22450         rm -f $1
22451 }
22452
22453 test_271d() {
22454         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22455                 skip "Need MDS version at least 2.10.57"
22456
22457         local dom=$DIR/$tdir/dom
22458         local tmp=$TMP/$tfile
22459         trap "cleanup_271def_tests $tmp" EXIT
22460
22461         mkdir -p $DIR/$tdir
22462
22463         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22464
22465         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22466
22467         cancel_lru_locks mdc
22468         dd if=/dev/urandom of=$tmp bs=1000 count=1
22469         dd if=$tmp of=$dom bs=1000 count=1
22470         cancel_lru_locks mdc
22471
22472         cat /etc/hosts >> $tmp
22473         lctl set_param -n mdc.*.stats=clear
22474
22475         # append data to the same file it should update local page
22476         echo "Append to the same page"
22477         cat /etc/hosts >> $dom
22478         local num=$(get_mdc_stats $mdtidx ost_read)
22479         local ra=$(get_mdc_stats $mdtidx req_active)
22480         local rw=$(get_mdc_stats $mdtidx req_waittime)
22481
22482         [ -z $num ] || error "$num READ RPC occured"
22483         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22484         echo "... DONE"
22485
22486         # compare content
22487         cmp $tmp $dom || error "file miscompare"
22488
22489         cancel_lru_locks mdc
22490         lctl set_param -n mdc.*.stats=clear
22491
22492         echo "Open and read file"
22493         cat $dom > /dev/null
22494         local num=$(get_mdc_stats $mdtidx ost_read)
22495         local ra=$(get_mdc_stats $mdtidx req_active)
22496         local rw=$(get_mdc_stats $mdtidx req_waittime)
22497
22498         [ -z $num ] || error "$num READ RPC occured"
22499         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22500         echo "... DONE"
22501
22502         # compare content
22503         cmp $tmp $dom || error "file miscompare"
22504
22505         return 0
22506 }
22507 run_test 271d "DoM: read on open (1K file in reply buffer)"
22508
22509 test_271f() {
22510         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22511                 skip "Need MDS version at least 2.10.57"
22512
22513         local dom=$DIR/$tdir/dom
22514         local tmp=$TMP/$tfile
22515         trap "cleanup_271def_tests $tmp" EXIT
22516
22517         mkdir -p $DIR/$tdir
22518
22519         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22520
22521         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22522
22523         cancel_lru_locks mdc
22524         dd if=/dev/urandom of=$tmp bs=265000 count=1
22525         dd if=$tmp of=$dom bs=265000 count=1
22526         cancel_lru_locks mdc
22527         cat /etc/hosts >> $tmp
22528         lctl set_param -n mdc.*.stats=clear
22529
22530         echo "Append to the same page"
22531         cat /etc/hosts >> $dom
22532         local num=$(get_mdc_stats $mdtidx ost_read)
22533         local ra=$(get_mdc_stats $mdtidx req_active)
22534         local rw=$(get_mdc_stats $mdtidx req_waittime)
22535
22536         [ -z $num ] || error "$num READ RPC occured"
22537         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22538         echo "... DONE"
22539
22540         # compare content
22541         cmp $tmp $dom || error "file miscompare"
22542
22543         cancel_lru_locks mdc
22544         lctl set_param -n mdc.*.stats=clear
22545
22546         echo "Open and read file"
22547         cat $dom > /dev/null
22548         local num=$(get_mdc_stats $mdtidx ost_read)
22549         local ra=$(get_mdc_stats $mdtidx req_active)
22550         local rw=$(get_mdc_stats $mdtidx req_waittime)
22551
22552         [ -z $num ] && num=0
22553         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22554         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22555         echo "... DONE"
22556
22557         # compare content
22558         cmp $tmp $dom || error "file miscompare"
22559
22560         return 0
22561 }
22562 run_test 271f "DoM: read on open (200K file and read tail)"
22563
22564 test_271g() {
22565         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22566                 skip "Skipping due to old client or server version"
22567
22568         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22569         # to get layout
22570         $CHECKSTAT -t file $DIR1/$tfile
22571
22572         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22573         MULTIOP_PID=$!
22574         sleep 1
22575         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22576         $LCTL set_param fail_loc=0x80000314
22577         rm $DIR1/$tfile || error "Unlink fails"
22578         RC=$?
22579         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22580         [ $RC -eq 0 ] || error "Failed write to stale object"
22581 }
22582 run_test 271g "Discard DoM data vs client flush race"
22583
22584 test_272a() {
22585         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22586                 skip "Need MDS version at least 2.11.50"
22587
22588         local dom=$DIR/$tdir/dom
22589         mkdir -p $DIR/$tdir
22590
22591         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22592         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22593                 error "failed to write data into $dom"
22594         local old_md5=$(md5sum $dom)
22595
22596         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22597                 error "failed to migrate to the same DoM component"
22598
22599         local new_md5=$(md5sum $dom)
22600
22601         [ "$old_md5" == "$new_md5" ] ||
22602                 error "md5sum differ: $old_md5, $new_md5"
22603
22604         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22605                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22606 }
22607 run_test 272a "DoM migration: new layout with the same DOM component"
22608
22609 test_272b() {
22610         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22611                 skip "Need MDS version at least 2.11.50"
22612
22613         local dom=$DIR/$tdir/dom
22614         mkdir -p $DIR/$tdir
22615         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22616
22617         local mdtidx=$($LFS getstripe -m $dom)
22618         local mdtname=MDT$(printf %04x $mdtidx)
22619         local facet=mds$((mdtidx + 1))
22620
22621         local mdtfree1=$(do_facet $facet \
22622                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22623         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22624                 error "failed to write data into $dom"
22625         local old_md5=$(md5sum $dom)
22626         cancel_lru_locks mdc
22627         local mdtfree1=$(do_facet $facet \
22628                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22629
22630         $LFS migrate -c2 $dom ||
22631                 error "failed to migrate to the new composite layout"
22632         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22633                 error "MDT stripe was not removed"
22634
22635         cancel_lru_locks mdc
22636         local new_md5=$(md5sum $dom)
22637         [ "$old_md5" == "$new_md5" ] ||
22638                 error "$old_md5 != $new_md5"
22639
22640         # Skip free space checks with ZFS
22641         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22642                 local mdtfree2=$(do_facet $facet \
22643                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22644                 [ $mdtfree2 -gt $mdtfree1 ] ||
22645                         error "MDT space is not freed after migration"
22646         fi
22647         return 0
22648 }
22649 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22650
22651 test_272c() {
22652         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22653                 skip "Need MDS version at least 2.11.50"
22654
22655         local dom=$DIR/$tdir/$tfile
22656         mkdir -p $DIR/$tdir
22657         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22658
22659         local mdtidx=$($LFS getstripe -m $dom)
22660         local mdtname=MDT$(printf %04x $mdtidx)
22661         local facet=mds$((mdtidx + 1))
22662
22663         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22664                 error "failed to write data into $dom"
22665         local old_md5=$(md5sum $dom)
22666         cancel_lru_locks mdc
22667         local mdtfree1=$(do_facet $facet \
22668                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22669
22670         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22671                 error "failed to migrate to the new composite layout"
22672         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22673                 error "MDT stripe was not removed"
22674
22675         cancel_lru_locks mdc
22676         local new_md5=$(md5sum $dom)
22677         [ "$old_md5" == "$new_md5" ] ||
22678                 error "$old_md5 != $new_md5"
22679
22680         # Skip free space checks with ZFS
22681         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22682                 local mdtfree2=$(do_facet $facet \
22683                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22684                 [ $mdtfree2 -gt $mdtfree1 ] ||
22685                         error "MDS space is not freed after migration"
22686         fi
22687         return 0
22688 }
22689 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22690
22691 test_272d() {
22692         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22693                 skip "Need MDS version at least 2.12.55"
22694
22695         local dom=$DIR/$tdir/$tfile
22696         mkdir -p $DIR/$tdir
22697         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22698
22699         local mdtidx=$($LFS getstripe -m $dom)
22700         local mdtname=MDT$(printf %04x $mdtidx)
22701         local facet=mds$((mdtidx + 1))
22702
22703         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22704                 error "failed to write data into $dom"
22705         local old_md5=$(md5sum $dom)
22706         cancel_lru_locks mdc
22707         local mdtfree1=$(do_facet $facet \
22708                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22709
22710         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22711                 error "failed mirroring to the new composite layout"
22712         $LFS mirror resync $dom ||
22713                 error "failed mirror resync"
22714         $LFS mirror split --mirror-id 1 -d $dom ||
22715                 error "failed mirror split"
22716
22717         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22718                 error "MDT stripe was not removed"
22719
22720         cancel_lru_locks mdc
22721         local new_md5=$(md5sum $dom)
22722         [ "$old_md5" == "$new_md5" ] ||
22723                 error "$old_md5 != $new_md5"
22724
22725         # Skip free space checks with ZFS
22726         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22727                 local mdtfree2=$(do_facet $facet \
22728                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22729                 [ $mdtfree2 -gt $mdtfree1 ] ||
22730                         error "MDS space is not freed after DOM mirror deletion"
22731         fi
22732         return 0
22733 }
22734 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22735
22736 test_272e() {
22737         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22738                 skip "Need MDS version at least 2.12.55"
22739
22740         local dom=$DIR/$tdir/$tfile
22741         mkdir -p $DIR/$tdir
22742         $LFS setstripe -c 2 $dom
22743
22744         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22745                 error "failed to write data into $dom"
22746         local old_md5=$(md5sum $dom)
22747         cancel_lru_locks
22748
22749         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22750                 error "failed mirroring to the DOM layout"
22751         $LFS mirror resync $dom ||
22752                 error "failed mirror resync"
22753         $LFS mirror split --mirror-id 1 -d $dom ||
22754                 error "failed mirror split"
22755
22756         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22757                 error "MDT stripe wasn't set"
22758
22759         cancel_lru_locks
22760         local new_md5=$(md5sum $dom)
22761         [ "$old_md5" == "$new_md5" ] ||
22762                 error "$old_md5 != $new_md5"
22763
22764         return 0
22765 }
22766 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22767
22768 test_272f() {
22769         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22770                 skip "Need MDS version at least 2.12.55"
22771
22772         local dom=$DIR/$tdir/$tfile
22773         mkdir -p $DIR/$tdir
22774         $LFS setstripe -c 2 $dom
22775
22776         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22777                 error "failed to write data into $dom"
22778         local old_md5=$(md5sum $dom)
22779         cancel_lru_locks
22780
22781         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22782                 error "failed migrating to the DOM file"
22783
22784         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22785                 error "MDT stripe wasn't set"
22786
22787         cancel_lru_locks
22788         local new_md5=$(md5sum $dom)
22789         [ "$old_md5" != "$new_md5" ] &&
22790                 error "$old_md5 != $new_md5"
22791
22792         return 0
22793 }
22794 run_test 272f "DoM migration: OST-striped file to DOM file"
22795
22796 test_273a() {
22797         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22798                 skip "Need MDS version at least 2.11.50"
22799
22800         # Layout swap cannot be done if either file has DOM component,
22801         # this will never be supported, migration should be used instead
22802
22803         local dom=$DIR/$tdir/$tfile
22804         mkdir -p $DIR/$tdir
22805
22806         $LFS setstripe -c2 ${dom}_plain
22807         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22808         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22809                 error "can swap layout with DoM component"
22810         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22811                 error "can swap layout with DoM component"
22812
22813         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22814         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22815                 error "can swap layout with DoM component"
22816         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22817                 error "can swap layout with DoM component"
22818         return 0
22819 }
22820 run_test 273a "DoM: layout swapping should fail with DOM"
22821
22822 test_273b() {
22823         mkdir -p $DIR/$tdir
22824         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22825
22826 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22827         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22828
22829         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22830 }
22831 run_test 273b "DoM: race writeback and object destroy"
22832
22833 test_275() {
22834         remote_ost_nodsh && skip "remote OST with nodsh"
22835         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22836                 skip "Need OST version >= 2.10.57"
22837
22838         local file=$DIR/$tfile
22839         local oss
22840
22841         oss=$(comma_list $(osts_nodes))
22842
22843         dd if=/dev/urandom of=$file bs=1M count=2 ||
22844                 error "failed to create a file"
22845         cancel_lru_locks osc
22846
22847         #lock 1
22848         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22849                 error "failed to read a file"
22850
22851 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22852         $LCTL set_param fail_loc=0x8000031f
22853
22854         cancel_lru_locks osc &
22855         sleep 1
22856
22857 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22858         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22859         #IO takes another lock, but matches the PENDING one
22860         #and places it to the IO RPC
22861         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22862                 error "failed to read a file with PENDING lock"
22863 }
22864 run_test 275 "Read on a canceled duplicate lock"
22865
22866 test_276() {
22867         remote_ost_nodsh && skip "remote OST with nodsh"
22868         local pid
22869
22870         do_facet ost1 "(while true; do \
22871                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22872                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22873         pid=$!
22874
22875         for LOOP in $(seq 20); do
22876                 stop ost1
22877                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22878         done
22879         kill -9 $pid
22880         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
22881                 rm $TMP/sanity_276_pid"
22882 }
22883 run_test 276 "Race between mount and obd_statfs"
22884
22885 test_277() {
22886         $LCTL set_param ldlm.namespaces.*.lru_size=0
22887         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22888         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22889                         grep ^used_mb | awk '{print $2}')
22890         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
22891         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
22892                 oflag=direct conv=notrunc
22893         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22894                         grep ^used_mb | awk '{print $2}')
22895         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
22896 }
22897 run_test 277 "Direct IO shall drop page cache"
22898
22899 test_278() {
22900         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22901         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22902         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
22903                 skip "needs the same host for mdt1 mdt2" && return
22904
22905         local pid1
22906         local pid2
22907
22908 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22909         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22910         stop mds2 &
22911         pid2=$!
22912
22913         stop mds1
22914
22915         echo "Starting MDTs"
22916         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22917         wait $pid2
22918 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
22919 #will return NULL
22920         do_facet mds2 $LCTL set_param fail_loc=0
22921
22922         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
22923         wait_recovery_complete mds2
22924 }
22925 run_test 278 "Race starting MDS between MDTs stop/start"
22926
22927 test_280() {
22928         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
22929                 skip "Need MGS version at least 2.13.52"
22930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22931         combined_mgs_mds || skip "needs combined MGS/MDT"
22932
22933         umount_client $MOUNT
22934 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
22935         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
22936
22937         mount_client $MOUNT &
22938         sleep 1
22939         stop mgs || error "stop mgs failed"
22940         #for a race mgs would crash
22941         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
22942         # make sure we unmount client before remounting
22943         wait
22944         umount_client $MOUNT
22945         mount_client $MOUNT || error "mount client failed"
22946 }
22947 run_test 280 "Race between MGS umount and client llog processing"
22948
22949 cleanup_test_300() {
22950         trap 0
22951         umask $SAVE_UMASK
22952 }
22953 test_striped_dir() {
22954         local mdt_index=$1
22955         local stripe_count
22956         local stripe_index
22957
22958         mkdir -p $DIR/$tdir
22959
22960         SAVE_UMASK=$(umask)
22961         trap cleanup_test_300 RETURN EXIT
22962
22963         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
22964                                                 $DIR/$tdir/striped_dir ||
22965                 error "set striped dir error"
22966
22967         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
22968         [ "$mode" = "755" ] || error "expect 755 got $mode"
22969
22970         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
22971                 error "getdirstripe failed"
22972         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
22973         if [ "$stripe_count" != "2" ]; then
22974                 error "1:stripe_count is $stripe_count, expect 2"
22975         fi
22976         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
22977         if [ "$stripe_count" != "2" ]; then
22978                 error "2:stripe_count is $stripe_count, expect 2"
22979         fi
22980
22981         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
22982         if [ "$stripe_index" != "$mdt_index" ]; then
22983                 error "stripe_index is $stripe_index, expect $mdt_index"
22984         fi
22985
22986         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22987                 error "nlink error after create striped dir"
22988
22989         mkdir $DIR/$tdir/striped_dir/a
22990         mkdir $DIR/$tdir/striped_dir/b
22991
22992         stat $DIR/$tdir/striped_dir/a ||
22993                 error "create dir under striped dir failed"
22994         stat $DIR/$tdir/striped_dir/b ||
22995                 error "create dir under striped dir failed"
22996
22997         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
22998                 error "nlink error after mkdir"
22999
23000         rmdir $DIR/$tdir/striped_dir/a
23001         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23002                 error "nlink error after rmdir"
23003
23004         rmdir $DIR/$tdir/striped_dir/b
23005         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23006                 error "nlink error after rmdir"
23007
23008         chattr +i $DIR/$tdir/striped_dir
23009         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23010                 error "immutable flags not working under striped dir!"
23011         chattr -i $DIR/$tdir/striped_dir
23012
23013         rmdir $DIR/$tdir/striped_dir ||
23014                 error "rmdir striped dir error"
23015
23016         cleanup_test_300
23017
23018         true
23019 }
23020
23021 test_300a() {
23022         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23023                 skip "skipped for lustre < 2.7.0"
23024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23025         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23026
23027         test_striped_dir 0 || error "failed on striped dir on MDT0"
23028         test_striped_dir 1 || error "failed on striped dir on MDT0"
23029 }
23030 run_test 300a "basic striped dir sanity test"
23031
23032 test_300b() {
23033         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23034                 skip "skipped for lustre < 2.7.0"
23035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23036         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23037
23038         local i
23039         local mtime1
23040         local mtime2
23041         local mtime3
23042
23043         test_mkdir $DIR/$tdir || error "mkdir fail"
23044         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23045                 error "set striped dir error"
23046         for i in {0..9}; do
23047                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23048                 sleep 1
23049                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23050                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23051                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23052                 sleep 1
23053                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23054                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23055                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23056         done
23057         true
23058 }
23059 run_test 300b "check ctime/mtime for striped dir"
23060
23061 test_300c() {
23062         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23063                 skip "skipped for lustre < 2.7.0"
23064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23065         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23066
23067         local file_count
23068
23069         mkdir_on_mdt0 $DIR/$tdir
23070         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23071                 error "set striped dir error"
23072
23073         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23074                 error "chown striped dir failed"
23075
23076         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23077                 error "create 5k files failed"
23078
23079         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23080
23081         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23082
23083         rm -rf $DIR/$tdir
23084 }
23085 run_test 300c "chown && check ls under striped directory"
23086
23087 test_300d() {
23088         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23089                 skip "skipped for lustre < 2.7.0"
23090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23091         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23092
23093         local stripe_count
23094         local file
23095
23096         mkdir -p $DIR/$tdir
23097         $LFS setstripe -c 2 $DIR/$tdir
23098
23099         #local striped directory
23100         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23101                 error "set striped dir error"
23102         #look at the directories for debug purposes
23103         ls -l $DIR/$tdir
23104         $LFS getdirstripe $DIR/$tdir
23105         ls -l $DIR/$tdir/striped_dir
23106         $LFS getdirstripe $DIR/$tdir/striped_dir
23107         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23108                 error "create 10 files failed"
23109
23110         #remote striped directory
23111         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23112                 error "set striped dir error"
23113         #look at the directories for debug purposes
23114         ls -l $DIR/$tdir
23115         $LFS getdirstripe $DIR/$tdir
23116         ls -l $DIR/$tdir/remote_striped_dir
23117         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23118         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23119                 error "create 10 files failed"
23120
23121         for file in $(find $DIR/$tdir); do
23122                 stripe_count=$($LFS getstripe -c $file)
23123                 [ $stripe_count -eq 2 ] ||
23124                         error "wrong stripe $stripe_count for $file"
23125         done
23126
23127         rm -rf $DIR/$tdir
23128 }
23129 run_test 300d "check default stripe under striped directory"
23130
23131 test_300e() {
23132         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23133                 skip "Need MDS version at least 2.7.55"
23134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23135         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23136
23137         local stripe_count
23138         local file
23139
23140         mkdir -p $DIR/$tdir
23141
23142         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23143                 error "set striped dir error"
23144
23145         touch $DIR/$tdir/striped_dir/a
23146         touch $DIR/$tdir/striped_dir/b
23147         touch $DIR/$tdir/striped_dir/c
23148
23149         mkdir $DIR/$tdir/striped_dir/dir_a
23150         mkdir $DIR/$tdir/striped_dir/dir_b
23151         mkdir $DIR/$tdir/striped_dir/dir_c
23152
23153         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23154                 error "set striped adir under striped dir error"
23155
23156         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23157                 error "set striped bdir under striped dir error"
23158
23159         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23160                 error "set striped cdir under striped dir error"
23161
23162         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23163                 error "rename dir under striped dir fails"
23164
23165         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23166                 error "rename dir under different stripes fails"
23167
23168         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23169                 error "rename file under striped dir should succeed"
23170
23171         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23172                 error "rename dir under striped dir should succeed"
23173
23174         rm -rf $DIR/$tdir
23175 }
23176 run_test 300e "check rename under striped directory"
23177
23178 test_300f() {
23179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23180         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23181         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23182                 skip "Need MDS version at least 2.7.55"
23183
23184         local stripe_count
23185         local file
23186
23187         rm -rf $DIR/$tdir
23188         mkdir -p $DIR/$tdir
23189
23190         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23191                 error "set striped dir error"
23192
23193         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23194                 error "set striped dir error"
23195
23196         touch $DIR/$tdir/striped_dir/a
23197         mkdir $DIR/$tdir/striped_dir/dir_a
23198         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23199                 error "create striped dir under striped dir fails"
23200
23201         touch $DIR/$tdir/striped_dir1/b
23202         mkdir $DIR/$tdir/striped_dir1/dir_b
23203         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23204                 error "create striped dir under striped dir fails"
23205
23206         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23207                 error "rename dir under different striped dir should fail"
23208
23209         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23210                 error "rename striped dir under diff striped dir should fail"
23211
23212         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23213                 error "rename file under diff striped dirs fails"
23214
23215         rm -rf $DIR/$tdir
23216 }
23217 run_test 300f "check rename cross striped directory"
23218
23219 test_300_check_default_striped_dir()
23220 {
23221         local dirname=$1
23222         local default_count=$2
23223         local default_index=$3
23224         local stripe_count
23225         local stripe_index
23226         local dir_stripe_index
23227         local dir
23228
23229         echo "checking $dirname $default_count $default_index"
23230         $LFS setdirstripe -D -c $default_count -i $default_index \
23231                                 -H all_char $DIR/$tdir/$dirname ||
23232                 error "set default stripe on striped dir error"
23233         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23234         [ $stripe_count -eq $default_count ] ||
23235                 error "expect $default_count get $stripe_count for $dirname"
23236
23237         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23238         [ $stripe_index -eq $default_index ] ||
23239                 error "expect $default_index get $stripe_index for $dirname"
23240
23241         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23242                                                 error "create dirs failed"
23243
23244         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23245         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23246         for dir in $(find $DIR/$tdir/$dirname/*); do
23247                 stripe_count=$($LFS getdirstripe -c $dir)
23248                 (( $stripe_count == $default_count )) ||
23249                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23250                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23251                 error "stripe count $default_count != $stripe_count for $dir"
23252
23253                 stripe_index=$($LFS getdirstripe -i $dir)
23254                 [ $default_index -eq -1 ] ||
23255                         [ $stripe_index -eq $default_index ] ||
23256                         error "$stripe_index != $default_index for $dir"
23257
23258                 #check default stripe
23259                 stripe_count=$($LFS getdirstripe -D -c $dir)
23260                 [ $stripe_count -eq $default_count ] ||
23261                 error "default count $default_count != $stripe_count for $dir"
23262
23263                 stripe_index=$($LFS getdirstripe -D -i $dir)
23264                 [ $stripe_index -eq $default_index ] ||
23265                 error "default index $default_index != $stripe_index for $dir"
23266         done
23267         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23268 }
23269
23270 test_300g() {
23271         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23272         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23273                 skip "Need MDS version at least 2.7.55"
23274
23275         local dir
23276         local stripe_count
23277         local stripe_index
23278
23279         mkdir_on_mdt0 $DIR/$tdir
23280         mkdir $DIR/$tdir/normal_dir
23281
23282         #Checking when client cache stripe index
23283         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23284         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23285                 error "create striped_dir failed"
23286
23287         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23288                 error "create dir0 fails"
23289         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23290         [ $stripe_index -eq 0 ] ||
23291                 error "dir0 expect index 0 got $stripe_index"
23292
23293         mkdir $DIR/$tdir/striped_dir/dir1 ||
23294                 error "create dir1 fails"
23295         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23296         [ $stripe_index -eq 1 ] ||
23297                 error "dir1 expect index 1 got $stripe_index"
23298
23299         #check default stripe count/stripe index
23300         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23301         test_300_check_default_striped_dir normal_dir 1 0
23302         test_300_check_default_striped_dir normal_dir -1 1
23303         test_300_check_default_striped_dir normal_dir 2 -1
23304
23305         #delete default stripe information
23306         echo "delete default stripeEA"
23307         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23308                 error "set default stripe on striped dir error"
23309
23310         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23311         for dir in $(find $DIR/$tdir/normal_dir/*); do
23312                 stripe_count=$($LFS getdirstripe -c $dir)
23313                 [ $stripe_count -eq 0 ] ||
23314                         error "expect 1 get $stripe_count for $dir"
23315         done
23316 }
23317 run_test 300g "check default striped directory for normal directory"
23318
23319 test_300h() {
23320         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23321         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23322                 skip "Need MDS version at least 2.7.55"
23323
23324         local dir
23325         local stripe_count
23326
23327         mkdir $DIR/$tdir
23328         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23329                 error "set striped dir error"
23330
23331         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23332         test_300_check_default_striped_dir striped_dir 1 0
23333         test_300_check_default_striped_dir striped_dir -1 1
23334         test_300_check_default_striped_dir striped_dir 2 -1
23335
23336         #delete default stripe information
23337         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23338                 error "set default stripe on striped dir error"
23339
23340         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23341         for dir in $(find $DIR/$tdir/striped_dir/*); do
23342                 stripe_count=$($LFS getdirstripe -c $dir)
23343                 [ $stripe_count -eq 0 ] ||
23344                         error "expect 1 get $stripe_count for $dir"
23345         done
23346 }
23347 run_test 300h "check default striped directory for striped directory"
23348
23349 test_300i() {
23350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23351         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23352         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23353                 skip "Need MDS version at least 2.7.55"
23354
23355         local stripe_count
23356         local file
23357
23358         mkdir $DIR/$tdir
23359
23360         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23361                 error "set striped dir error"
23362
23363         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23364                 error "create files under striped dir failed"
23365
23366         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23367                 error "set striped hashdir error"
23368
23369         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23370                 error "create dir0 under hash dir failed"
23371         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23372                 error "create dir1 under hash dir failed"
23373         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23374                 error "create dir2 under hash dir failed"
23375
23376         # unfortunately, we need to umount to clear dir layout cache for now
23377         # once we fully implement dir layout, we can drop this
23378         umount_client $MOUNT || error "umount failed"
23379         mount_client $MOUNT || error "mount failed"
23380
23381         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23382         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23383         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
23384
23385         #set the stripe to be unknown hash type
23386         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
23387         $LCTL set_param fail_loc=0x1901
23388         for ((i = 0; i < 10; i++)); do
23389                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23390                         error "stat f-$i failed"
23391                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23392         done
23393
23394         touch $DIR/$tdir/striped_dir/f0 &&
23395                 error "create under striped dir with unknown hash should fail"
23396
23397         $LCTL set_param fail_loc=0
23398
23399         umount_client $MOUNT || error "umount failed"
23400         mount_client $MOUNT || error "mount failed"
23401
23402         return 0
23403 }
23404 run_test 300i "client handle unknown hash type striped directory"
23405
23406 test_300j() {
23407         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23409         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23410                 skip "Need MDS version at least 2.7.55"
23411
23412         local stripe_count
23413         local file
23414
23415         mkdir $DIR/$tdir
23416
23417         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23418         $LCTL set_param fail_loc=0x1702
23419         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23420                 error "set striped dir error"
23421
23422         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23423                 error "create files under striped dir failed"
23424
23425         $LCTL set_param fail_loc=0
23426
23427         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23428
23429         return 0
23430 }
23431 run_test 300j "test large update record"
23432
23433 test_300k() {
23434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23435         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23436         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23437                 skip "Need MDS version at least 2.7.55"
23438
23439         # this test needs a huge transaction
23440         local kb
23441         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23442              osd*.$FSNAME-MDT0000.kbytestotal")
23443         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23444
23445         local stripe_count
23446         local file
23447
23448         mkdir $DIR/$tdir
23449
23450         #define OBD_FAIL_LARGE_STRIPE   0x1703
23451         $LCTL set_param fail_loc=0x1703
23452         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23453                 error "set striped dir error"
23454         $LCTL set_param fail_loc=0
23455
23456         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23457                 error "getstripeddir fails"
23458         rm -rf $DIR/$tdir/striped_dir ||
23459                 error "unlink striped dir fails"
23460
23461         return 0
23462 }
23463 run_test 300k "test large striped directory"
23464
23465 test_300l() {
23466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23467         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23468         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23469                 skip "Need MDS version at least 2.7.55"
23470
23471         local stripe_index
23472
23473         test_mkdir -p $DIR/$tdir/striped_dir
23474         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23475                         error "chown $RUNAS_ID failed"
23476         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23477                 error "set default striped dir failed"
23478
23479         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23480         $LCTL set_param fail_loc=0x80000158
23481         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23482
23483         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23484         [ $stripe_index -eq 1 ] ||
23485                 error "expect 1 get $stripe_index for $dir"
23486 }
23487 run_test 300l "non-root user to create dir under striped dir with stale layout"
23488
23489 test_300m() {
23490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23491         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23492         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23493                 skip "Need MDS version at least 2.7.55"
23494
23495         mkdir -p $DIR/$tdir/striped_dir
23496         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23497                 error "set default stripes dir error"
23498
23499         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23500
23501         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23502         [ $stripe_count -eq 0 ] ||
23503                         error "expect 0 get $stripe_count for a"
23504
23505         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23506                 error "set default stripes dir error"
23507
23508         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23509
23510         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23511         [ $stripe_count -eq 0 ] ||
23512                         error "expect 0 get $stripe_count for b"
23513
23514         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23515                 error "set default stripes dir error"
23516
23517         mkdir $DIR/$tdir/striped_dir/c &&
23518                 error "default stripe_index is invalid, mkdir c should fails"
23519
23520         rm -rf $DIR/$tdir || error "rmdir fails"
23521 }
23522 run_test 300m "setstriped directory on single MDT FS"
23523
23524 cleanup_300n() {
23525         local list=$(comma_list $(mdts_nodes))
23526
23527         trap 0
23528         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23529 }
23530
23531 test_300n() {
23532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23533         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23534         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23535                 skip "Need MDS version at least 2.7.55"
23536         remote_mds_nodsh && skip "remote MDS with nodsh"
23537
23538         local stripe_index
23539         local list=$(comma_list $(mdts_nodes))
23540
23541         trap cleanup_300n RETURN EXIT
23542         mkdir -p $DIR/$tdir
23543         chmod 777 $DIR/$tdir
23544         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23545                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23546                 error "create striped dir succeeds with gid=0"
23547
23548         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23549         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23550                 error "create striped dir fails with gid=-1"
23551
23552         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23553         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23554                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23555                 error "set default striped dir succeeds with gid=0"
23556
23557
23558         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23559         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23560                 error "set default striped dir fails with gid=-1"
23561
23562
23563         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23564         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23565                                         error "create test_dir fails"
23566         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23567                                         error "create test_dir1 fails"
23568         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23569                                         error "create test_dir2 fails"
23570         cleanup_300n
23571 }
23572 run_test 300n "non-root user to create dir under striped dir with default EA"
23573
23574 test_300o() {
23575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23576         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23577         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23578                 skip "Need MDS version at least 2.7.55"
23579
23580         local numfree1
23581         local numfree2
23582
23583         mkdir -p $DIR/$tdir
23584
23585         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23586         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23587         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23588                 skip "not enough free inodes $numfree1 $numfree2"
23589         fi
23590
23591         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23592         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23593         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23594                 skip "not enough free space $numfree1 $numfree2"
23595         fi
23596
23597         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23598                 error "setdirstripe fails"
23599
23600         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23601                 error "create dirs fails"
23602
23603         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23604         ls $DIR/$tdir/striped_dir > /dev/null ||
23605                 error "ls striped dir fails"
23606         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23607                 error "unlink big striped dir fails"
23608 }
23609 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23610
23611 test_300p() {
23612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23613         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23614         remote_mds_nodsh && skip "remote MDS with nodsh"
23615
23616         mkdir_on_mdt0 $DIR/$tdir
23617
23618         #define OBD_FAIL_OUT_ENOSPC     0x1704
23619         do_facet mds2 lctl set_param fail_loc=0x80001704
23620         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23621                  && error "create striped directory should fail"
23622
23623         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23624
23625         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23626         true
23627 }
23628 run_test 300p "create striped directory without space"
23629
23630 test_300q() {
23631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23632         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23633
23634         local fd=$(free_fd)
23635         local cmd="exec $fd<$tdir"
23636         cd $DIR
23637         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23638         eval $cmd
23639         cmd="exec $fd<&-"
23640         trap "eval $cmd" EXIT
23641         cd $tdir || error "cd $tdir fails"
23642         rmdir  ../$tdir || error "rmdir $tdir fails"
23643         mkdir local_dir && error "create dir succeeds"
23644         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23645         eval $cmd
23646         return 0
23647 }
23648 run_test 300q "create remote directory under orphan directory"
23649
23650 test_300r() {
23651         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23652                 skip "Need MDS version at least 2.7.55" && return
23653         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23654
23655         mkdir $DIR/$tdir
23656
23657         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23658                 error "set striped dir error"
23659
23660         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23661                 error "getstripeddir fails"
23662
23663         local stripe_count
23664         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23665                       awk '/lmv_stripe_count:/ { print $2 }')
23666
23667         [ $MDSCOUNT -ne $stripe_count ] &&
23668                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23669
23670         rm -rf $DIR/$tdir/striped_dir ||
23671                 error "unlink striped dir fails"
23672 }
23673 run_test 300r "test -1 striped directory"
23674
23675 test_300s_helper() {
23676         local count=$1
23677
23678         local stripe_dir=$DIR/$tdir/striped_dir.$count
23679
23680         $LFS mkdir -c $count $stripe_dir ||
23681                 error "lfs mkdir -c error"
23682
23683         $LFS getdirstripe $stripe_dir ||
23684                 error "lfs getdirstripe fails"
23685
23686         local stripe_count
23687         stripe_count=$($LFS getdirstripe $stripe_dir |
23688                       awk '/lmv_stripe_count:/ { print $2 }')
23689
23690         [ $count -ne $stripe_count ] &&
23691                 error_noexit "bad stripe count $stripe_count expected $count"
23692
23693         local dupe_stripes
23694         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23695                 awk '/0x/ {count[$1] += 1}; END {
23696                         for (idx in count) {
23697                                 if (count[idx]>1) {
23698                                         print "index " idx " count " count[idx]
23699                                 }
23700                         }
23701                 }')
23702
23703         if [[ -n "$dupe_stripes" ]] ; then
23704                 lfs getdirstripe $stripe_dir
23705                 error_noexit "Dupe MDT above: $dupe_stripes "
23706         fi
23707
23708         rm -rf $stripe_dir ||
23709                 error_noexit "unlink $stripe_dir fails"
23710 }
23711
23712 test_300s() {
23713         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23714                 skip "Need MDS version at least 2.7.55" && return
23715         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23716
23717         mkdir $DIR/$tdir
23718         for count in $(seq 2 $MDSCOUNT); do
23719                 test_300s_helper $count
23720         done
23721 }
23722 run_test 300s "test lfs mkdir -c without -i"
23723
23724 prepare_remote_file() {
23725         mkdir $DIR/$tdir/src_dir ||
23726                 error "create remote source failed"
23727
23728         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23729                  error "cp to remote source failed"
23730         touch $DIR/$tdir/src_dir/a
23731
23732         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23733                 error "create remote target dir failed"
23734
23735         touch $DIR/$tdir/tgt_dir/b
23736
23737         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23738                 error "rename dir cross MDT failed!"
23739
23740         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23741                 error "src_child still exists after rename"
23742
23743         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23744                 error "missing file(a) after rename"
23745
23746         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
23747                 error "diff after rename"
23748 }
23749
23750 test_310a() {
23751         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23752         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23753
23754         local remote_file=$DIR/$tdir/tgt_dir/b
23755
23756         mkdir -p $DIR/$tdir
23757
23758         prepare_remote_file || error "prepare remote file failed"
23759
23760         #open-unlink file
23761         $OPENUNLINK $remote_file $remote_file ||
23762                 error "openunlink $remote_file failed"
23763         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23764 }
23765 run_test 310a "open unlink remote file"
23766
23767 test_310b() {
23768         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23770
23771         local remote_file=$DIR/$tdir/tgt_dir/b
23772
23773         mkdir -p $DIR/$tdir
23774
23775         prepare_remote_file || error "prepare remote file failed"
23776
23777         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23778         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23779         $CHECKSTAT -t file $remote_file || error "check file failed"
23780 }
23781 run_test 310b "unlink remote file with multiple links while open"
23782
23783 test_310c() {
23784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23785         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23786
23787         local remote_file=$DIR/$tdir/tgt_dir/b
23788
23789         mkdir -p $DIR/$tdir
23790
23791         prepare_remote_file || error "prepare remote file failed"
23792
23793         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23794         multiop_bg_pause $remote_file O_uc ||
23795                         error "mulitop failed for remote file"
23796         MULTIPID=$!
23797         $MULTIOP $DIR/$tfile Ouc
23798         kill -USR1 $MULTIPID
23799         wait $MULTIPID
23800 }
23801 run_test 310c "open-unlink remote file with multiple links"
23802
23803 #LU-4825
23804 test_311() {
23805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23806         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23807         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23808                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23809         remote_mds_nodsh && skip "remote MDS with nodsh"
23810
23811         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23812         local mdts=$(comma_list $(mdts_nodes))
23813
23814         mkdir -p $DIR/$tdir
23815         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23816         createmany -o $DIR/$tdir/$tfile. 1000
23817
23818         # statfs data is not real time, let's just calculate it
23819         old_iused=$((old_iused + 1000))
23820
23821         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23822                         osp.*OST0000*MDT0000.create_count")
23823         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23824                                 osp.*OST0000*MDT0000.max_create_count")
23825         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23826
23827         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23828         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23829         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23830
23831         unlinkmany $DIR/$tdir/$tfile. 1000
23832
23833         do_nodes $mdts "$LCTL set_param -n \
23834                         osp.*OST0000*.max_create_count=$max_count"
23835         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23836                 do_nodes $mdts "$LCTL set_param -n \
23837                                 osp.*OST0000*.create_count=$count"
23838         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23839                         grep "=0" && error "create_count is zero"
23840
23841         local new_iused
23842         for i in $(seq 120); do
23843                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23844                 # system may be too busy to destroy all objs in time, use
23845                 # a somewhat small value to not fail autotest
23846                 [ $((old_iused - new_iused)) -gt 400 ] && break
23847                 sleep 1
23848         done
23849
23850         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
23851         [ $((old_iused - new_iused)) -gt 400 ] ||
23852                 error "objs not destroyed after unlink"
23853 }
23854 run_test 311 "disable OSP precreate, and unlink should destroy objs"
23855
23856 zfs_oid_to_objid()
23857 {
23858         local ost=$1
23859         local objid=$2
23860
23861         local vdevdir=$(dirname $(facet_vdevice $ost))
23862         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
23863         local zfs_zapid=$(do_facet $ost $cmd |
23864                           grep -w "/O/0/d$((objid%32))" -C 5 |
23865                           awk '/Object/{getline; print $1}')
23866         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
23867                           awk "/$objid = /"'{printf $3}')
23868
23869         echo $zfs_objid
23870 }
23871
23872 zfs_object_blksz() {
23873         local ost=$1
23874         local objid=$2
23875
23876         local vdevdir=$(dirname $(facet_vdevice $ost))
23877         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
23878         local blksz=$(do_facet $ost $cmd $objid |
23879                       awk '/dblk/{getline; printf $4}')
23880
23881         case "${blksz: -1}" in
23882                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
23883                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
23884                 *) ;;
23885         esac
23886
23887         echo $blksz
23888 }
23889
23890 test_312() { # LU-4856
23891         remote_ost_nodsh && skip "remote OST with nodsh"
23892         [ "$ost1_FSTYPE" = "zfs" ] ||
23893                 skip_env "the test only applies to zfs"
23894
23895         local max_blksz=$(do_facet ost1 \
23896                           $ZFS get -p recordsize $(facet_device ost1) |
23897                           awk '!/VALUE/{print $3}')
23898
23899         # to make life a little bit easier
23900         $LFS mkdir -c 1 -i 0 $DIR/$tdir
23901         $LFS setstripe -c 1 -i 0 $DIR/$tdir
23902
23903         local tf=$DIR/$tdir/$tfile
23904         touch $tf
23905         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23906
23907         # Get ZFS object id
23908         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23909         # block size change by sequential overwrite
23910         local bs
23911
23912         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
23913                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
23914
23915                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
23916                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
23917         done
23918         rm -f $tf
23919
23920         # block size change by sequential append write
23921         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
23922         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23923         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23924         local count
23925
23926         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
23927                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
23928                         oflag=sync conv=notrunc
23929
23930                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
23931                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
23932                         error "blksz error, actual $blksz, " \
23933                                 "expected: 2 * $count * $PAGE_SIZE"
23934         done
23935         rm -f $tf
23936
23937         # random write
23938         touch $tf
23939         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23940         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23941
23942         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
23943         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23944         [ $blksz -eq $PAGE_SIZE ] ||
23945                 error "blksz error: $blksz, expected: $PAGE_SIZE"
23946
23947         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
23948         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23949         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
23950
23951         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
23952         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23953         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
23954 }
23955 run_test 312 "make sure ZFS adjusts its block size by write pattern"
23956
23957 test_313() {
23958         remote_ost_nodsh && skip "remote OST with nodsh"
23959
23960         local file=$DIR/$tfile
23961
23962         rm -f $file
23963         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
23964
23965         # define OBD_FAIL_TGT_RCVD_EIO           0x720
23966         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23967         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
23968                 error "write should failed"
23969         do_facet ost1 "$LCTL set_param fail_loc=0"
23970         rm -f $file
23971 }
23972 run_test 313 "io should fail after last_rcvd update fail"
23973
23974 test_314() {
23975         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23976
23977         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
23978         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23979         rm -f $DIR/$tfile
23980         wait_delete_completed
23981         do_facet ost1 "$LCTL set_param fail_loc=0"
23982 }
23983 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
23984
23985 test_315() { # LU-618
23986         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
23987
23988         local file=$DIR/$tfile
23989         rm -f $file
23990
23991         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
23992                 error "multiop file write failed"
23993         $MULTIOP $file oO_RDONLY:r4063232_c &
23994         PID=$!
23995
23996         sleep 2
23997
23998         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
23999         kill -USR1 $PID
24000
24001         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24002         rm -f $file
24003 }
24004 run_test 315 "read should be accounted"
24005
24006 test_316() {
24007         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24008         large_xattr_enabled || skip_env "ea_inode feature disabled"
24009
24010         rm -rf $DIR/$tdir/d
24011         mkdir -p $DIR/$tdir/d
24012         chown nobody $DIR/$tdir/d
24013         touch $DIR/$tdir/d/file
24014
24015         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
24016 }
24017 run_test 316 "lfs mv"
24018
24019 test_317() {
24020         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24021                 skip "Need MDS version at least 2.11.53"
24022         if [ "$ost1_FSTYPE" == "zfs" ]; then
24023                 skip "LU-10370: no implementation for ZFS"
24024         fi
24025
24026         local trunc_sz
24027         local grant_blk_size
24028
24029         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24030                         awk '/grant_block_size:/ { print $2; exit; }')
24031         #
24032         # Create File of size 5M. Truncate it to below size's and verify
24033         # blocks count.
24034         #
24035         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24036                 error "Create file $DIR/$tfile failed"
24037         stack_trap "rm -f $DIR/$tfile" EXIT
24038
24039         for trunc_sz in 2097152 4097 4000 509 0; do
24040                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24041                         error "truncate $tfile to $trunc_sz failed"
24042                 local sz=$(stat --format=%s $DIR/$tfile)
24043                 local blk=$(stat --format=%b $DIR/$tfile)
24044                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24045                                      grant_blk_size) * 8))
24046
24047                 if [[ $blk -ne $trunc_blk ]]; then
24048                         $(which stat) $DIR/$tfile
24049                         error "Expected Block $trunc_blk got $blk for $tfile"
24050                 fi
24051
24052                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24053                         error "Expected Size $trunc_sz got $sz for $tfile"
24054         done
24055
24056         #
24057         # sparse file test
24058         # Create file with a hole and write actual 65536 bytes which aligned
24059         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24060         #
24061         local bs=65536
24062         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24063                 error "Create file : $DIR/$tfile"
24064
24065         #
24066         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24067         # blocks. The block count must drop to 8.
24068         #
24069         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - \
24070                 ((bs - grant_blk_size) + 1)))
24071         $TRUNCATE $DIR/$tfile $trunc_sz ||
24072                 error "truncate $tfile to $trunc_sz failed"
24073
24074         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24075         sz=$(stat --format=%s $DIR/$tfile)
24076         blk=$(stat --format=%b $DIR/$tfile)
24077
24078         if [[ $blk -ne $trunc_bsz ]]; then
24079                 $(which stat) $DIR/$tfile
24080                 error "Expected Block $trunc_bsz got $blk for $tfile"
24081         fi
24082
24083         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24084                 error "Expected Size $trunc_sz got $sz for $tfile"
24085 }
24086 run_test 317 "Verify blocks get correctly update after truncate"
24087
24088 test_318() {
24089         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24090         local old_max_active=$($LCTL get_param -n \
24091                             ${llite_name}.max_read_ahead_async_active \
24092                             2>/dev/null)
24093
24094         $LCTL set_param llite.*.max_read_ahead_async_active=256
24095         local max_active=$($LCTL get_param -n \
24096                            ${llite_name}.max_read_ahead_async_active \
24097                            2>/dev/null)
24098         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24099
24100         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24101                 error "set max_read_ahead_async_active should succeed"
24102
24103         $LCTL set_param llite.*.max_read_ahead_async_active=512
24104         max_active=$($LCTL get_param -n \
24105                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24106         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24107
24108         # restore @max_active
24109         [ $old_max_active -ne 0 ] && $LCTL set_param \
24110                 llite.*.max_read_ahead_async_active=$old_max_active
24111
24112         local old_threshold=$($LCTL get_param -n \
24113                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24114         local max_per_file_mb=$($LCTL get_param -n \
24115                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24116
24117         local invalid=$(($max_per_file_mb + 1))
24118         $LCTL set_param \
24119                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24120                         && error "set $invalid should fail"
24121
24122         local valid=$(($invalid - 1))
24123         $LCTL set_param \
24124                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24125                         error "set $valid should succeed"
24126         local threshold=$($LCTL get_param -n \
24127                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24128         [ $threshold -eq $valid ] || error \
24129                 "expect threshold $valid got $threshold"
24130         $LCTL set_param \
24131                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24132 }
24133 run_test 318 "Verify async readahead tunables"
24134
24135 test_319() {
24136         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
24137
24138         local before=$(date +%s)
24139         local evict
24140         local mdir=$DIR/$tdir
24141         local file=$mdir/xxx
24142
24143         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24144         touch $file
24145
24146 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24147         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24148         $LFS mv -m1 $file &
24149
24150         sleep 1
24151         dd if=$file of=/dev/null
24152         wait
24153         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24154           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24155
24156         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24157 }
24158 run_test 319 "lost lease lock on migrate error"
24159
24160 test_398a() { # LU-4198
24161         local ost1_imp=$(get_osc_import_name client ost1)
24162         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24163                          cut -d'.' -f2)
24164
24165         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24166         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24167
24168         # request a new lock on client
24169         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24170
24171         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24172         local lock_count=$($LCTL get_param -n \
24173                            ldlm.namespaces.$imp_name.lru_size)
24174         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24175
24176         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24177
24178         # no lock cached, should use lockless IO and not enqueue new lock
24179         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24180         lock_count=$($LCTL get_param -n \
24181                      ldlm.namespaces.$imp_name.lru_size)
24182         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24183 }
24184 run_test 398a "direct IO should cancel lock otherwise lockless"
24185
24186 test_398b() { # LU-4198
24187         which fio || skip_env "no fio installed"
24188         $LFS setstripe -c -1 $DIR/$tfile
24189
24190         local size=12
24191         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24192
24193         local njobs=4
24194         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
24195         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24196                 --numjobs=$njobs --fallocate=none \
24197                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24198                 --filename=$DIR/$tfile &
24199         bg_pid=$!
24200
24201         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
24202         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
24203                 --numjobs=$njobs --fallocate=none \
24204                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24205                 --filename=$DIR/$tfile || true
24206         wait $bg_pid
24207
24208         rm -f $DIR/$tfile
24209 }
24210 run_test 398b "DIO and buffer IO race"
24211
24212 test_398c() { # LU-4198
24213         local ost1_imp=$(get_osc_import_name client ost1)
24214         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24215                          cut -d'.' -f2)
24216
24217         which fio || skip_env "no fio installed"
24218
24219         saved_debug=$($LCTL get_param -n debug)
24220         $LCTL set_param debug=0
24221
24222         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24223         ((size /= 1024)) # by megabytes
24224         ((size /= 2)) # write half of the OST at most
24225         [ $size -gt 40 ] && size=40 #reduce test time anyway
24226
24227         $LFS setstripe -c 1 $DIR/$tfile
24228
24229         # it seems like ldiskfs reserves more space than necessary if the
24230         # writing blocks are not mapped, so it extends the file firstly
24231         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24232         cancel_lru_locks osc
24233
24234         # clear and verify rpc_stats later
24235         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24236
24237         local njobs=4
24238         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24239         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24240                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24241                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24242                 --filename=$DIR/$tfile
24243         [ $? -eq 0 ] || error "fio write error"
24244
24245         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24246                 error "Locks were requested while doing AIO"
24247
24248         # get the percentage of 1-page I/O
24249         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24250                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24251                 awk '{print $7}')
24252         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24253
24254         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24255         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24256                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24257                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24258                 --filename=$DIR/$tfile
24259         [ $? -eq 0 ] || error "fio mixed read write error"
24260
24261         echo "AIO with large block size ${size}M"
24262         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24263                 --numjobs=1 --fallocate=none --ioengine=libaio \
24264                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24265                 --filename=$DIR/$tfile
24266         [ $? -eq 0 ] || error "fio large block size failed"
24267
24268         rm -f $DIR/$tfile
24269         $LCTL set_param debug="$saved_debug"
24270 }
24271 run_test 398c "run fio to test AIO"
24272
24273 test_398d() { #  LU-13846
24274         which aiocp || skip_env "no aiocp installed"
24275         local aio_file=$DIR/$tfile.aio
24276
24277         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24278
24279         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24280         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24281         stack_trap "rm -f $DIR/$tfile $aio_file"
24282
24283         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24284
24285         # make sure we don't crash and fail properly
24286         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24287                 error "aio not aligned with PAGE SIZE should fail"
24288
24289         rm -f $DIR/$tfile $aio_file
24290 }
24291 run_test 398d "run aiocp to verify block size > stripe size"
24292
24293 test_398e() {
24294         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24295         touch $DIR/$tfile.new
24296         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24297 }
24298 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24299
24300 test_398f() { #  LU-14687
24301         which aiocp || skip_env "no aiocp installed"
24302         local aio_file=$DIR/$tfile.aio
24303
24304         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24305
24306         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24307         stack_trap "rm -f $DIR/$tfile $aio_file"
24308
24309         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24310         $LCTL set_param fail_loc=0x1418
24311         # make sure we don't crash and fail properly
24312         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24313                 error "aio with page allocation failure succeeded"
24314         $LCTL set_param fail_loc=0
24315         diff $DIR/$tfile $aio_file
24316         [[ $? != 0 ]] || error "no diff after failed aiocp"
24317 }
24318 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24319
24320 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24321 # stripe and i/o size must be > stripe size
24322 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24323 # single RPC in flight.  This test shows async DIO submission is working by
24324 # showing multiple RPCs in flight.
24325 test_398g() { #  LU-13798
24326         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24327
24328         # We need to do some i/o first to acquire enough grant to put our RPCs
24329         # in flight; otherwise a new connection may not have enough grant
24330         # available
24331         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24332                 error "parallel dio failed"
24333         stack_trap "rm -f $DIR/$tfile"
24334
24335         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24336         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24337         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24338         stack_trap "$LCTL set_param -n $pages_per_rpc"
24339
24340         # Recreate file so it's empty
24341         rm -f $DIR/$tfile
24342         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24343         #Pause rpc completion to guarantee we see multiple rpcs in flight
24344         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24345         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24346         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24347
24348         # Clear rpc stats
24349         $LCTL set_param osc.*.rpc_stats=c
24350
24351         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24352                 error "parallel dio failed"
24353         stack_trap "rm -f $DIR/$tfile"
24354
24355         $LCTL get_param osc.*-OST0000-*.rpc_stats
24356         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24357                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24358                 grep "8:" | awk '{print $8}')
24359         # We look at the "8 rpcs in flight" field, and verify A) it is present
24360         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24361         # as expected for an 8M DIO to a file with 1M stripes.
24362         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24363
24364         # Verify turning off parallel dio works as expected
24365         # Clear rpc stats
24366         $LCTL set_param osc.*.rpc_stats=c
24367         $LCTL set_param llite.*.parallel_dio=0
24368         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24369
24370         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24371                 error "dio with parallel dio disabled failed"
24372
24373         # Ideally, we would see only one RPC in flight here, but there is an
24374         # unavoidable race between i/o completion and RPC in flight counting,
24375         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24376         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24377         # So instead we just verify it's always < 8.
24378         $LCTL get_param osc.*-OST0000-*.rpc_stats
24379         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24380                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24381                 grep '^$' -B1 | grep . | awk '{print $1}')
24382         [ $ret != "8:" ] ||
24383                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24384 }
24385 run_test 398g "verify parallel dio async RPC submission"
24386
24387 test_398h() { #  LU-13798
24388         local dio_file=$DIR/$tfile.dio
24389
24390         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24391
24392         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24393         stack_trap "rm -f $DIR/$tfile $dio_file"
24394
24395         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24396                 error "parallel dio failed"
24397         diff $DIR/$tfile $dio_file
24398         [[ $? == 0 ]] || error "file diff after aiocp"
24399 }
24400 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24401
24402 test_398i() { #  LU-13798
24403         local dio_file=$DIR/$tfile.dio
24404
24405         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24406
24407         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24408         stack_trap "rm -f $DIR/$tfile $dio_file"
24409
24410         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24411         $LCTL set_param fail_loc=0x1418
24412         # make sure we don't crash and fail properly
24413         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24414                 error "parallel dio page allocation failure succeeded"
24415         diff $DIR/$tfile $dio_file
24416         [[ $? != 0 ]] || error "no diff after failed aiocp"
24417 }
24418 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24419
24420 test_398j() { #  LU-13798
24421         # Stripe size > RPC size but less than i/o size tests split across
24422         # stripes and RPCs for individual i/o op
24423         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24424
24425         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24426         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24427         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24428         stack_trap "$LCTL set_param -n $pages_per_rpc"
24429
24430         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24431                 error "parallel dio write failed"
24432         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24433
24434         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24435                 error "parallel dio read failed"
24436         diff $DIR/$tfile $DIR/$tfile.2
24437         [[ $? == 0 ]] || error "file diff after parallel dio read"
24438 }
24439 run_test 398j "test parallel dio where stripe size > rpc_size"
24440
24441 test_398k() { #  LU-13798
24442         wait_delete_completed
24443         wait_mds_ost_sync
24444
24445         # 4 stripe file; we will cause out of space on OST0
24446         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24447
24448         # Fill OST0 (if it's not too large)
24449         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24450                    head -n1)
24451         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24452                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24453         fi
24454         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24455         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24456                 error "dd should fill OST0"
24457         stack_trap "rm -f $DIR/$tfile.1"
24458
24459         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24460         err=$?
24461
24462         ls -la $DIR/$tfile
24463         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24464                 error "file is not 0 bytes in size"
24465
24466         # dd above should not succeed, but don't error until here so we can
24467         # get debug info above
24468         [[ $err != 0 ]] ||
24469                 error "parallel dio write with enospc succeeded"
24470         stack_trap "rm -f $DIR/$tfile"
24471 }
24472 run_test 398k "test enospc on first stripe"
24473
24474 test_398l() { #  LU-13798
24475         wait_delete_completed
24476         wait_mds_ost_sync
24477
24478         # 4 stripe file; we will cause out of space on OST0
24479         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24480         # happens on the second i/o chunk we issue
24481         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24482
24483         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24484         stack_trap "rm -f $DIR/$tfile"
24485
24486         # Fill OST0 (if it's not too large)
24487         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24488                    head -n1)
24489         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24490                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24491         fi
24492         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24493         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24494                 error "dd should fill OST0"
24495         stack_trap "rm -f $DIR/$tfile.1"
24496
24497         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24498         err=$?
24499         stack_trap "rm -f $DIR/$tfile.2"
24500
24501         # Check that short write completed as expected
24502         ls -la $DIR/$tfile.2
24503         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24504                 error "file is not 1M in size"
24505
24506         # dd above should not succeed, but don't error until here so we can
24507         # get debug info above
24508         [[ $err != 0 ]] ||
24509                 error "parallel dio write with enospc succeeded"
24510
24511         # Truncate source file to same length as output file and diff them
24512         $TRUNCATE $DIR/$tfile 1048576
24513         diff $DIR/$tfile $DIR/$tfile.2
24514         [[ $? == 0 ]] || error "data incorrect after short write"
24515 }
24516 run_test 398l "test enospc on intermediate stripe/RPC"
24517
24518 test_398m() { #  LU-13798
24519         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24520
24521         # Set up failure on OST0, the first stripe:
24522         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24523         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24524         # So this fail_val specifies OST0
24525         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24526         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24527
24528         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24529                 error "parallel dio write with failure on first stripe succeeded"
24530         stack_trap "rm -f $DIR/$tfile"
24531         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24532
24533         # Place data in file for read
24534         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24535                 error "parallel dio write failed"
24536
24537         # Fail read on OST0, first stripe
24538         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24539         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24540         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24541                 error "parallel dio read with error on first stripe succeeded"
24542         rm -f $DIR/$tfile.2
24543         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24544
24545         # Switch to testing on OST1, second stripe
24546         # Clear file contents, maintain striping
24547         echo > $DIR/$tfile
24548         # Set up failure on OST1, second stripe:
24549         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24550         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24551
24552         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24553                 error "parallel dio write with failure on first stripe succeeded"
24554         stack_trap "rm -f $DIR/$tfile"
24555         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24556
24557         # Place data in file for read
24558         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24559                 error "parallel dio write failed"
24560
24561         # Fail read on OST1, second stripe
24562         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24563         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24564         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24565                 error "parallel dio read with error on first stripe succeeded"
24566         rm -f $DIR/$tfile.2
24567         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24568 }
24569 run_test 398m "test RPC failures with parallel dio"
24570
24571 # Parallel submission of DIO should not cause problems for append, but it's
24572 # important to verify.
24573 test_398n() { #  LU-13798
24574         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24575
24576         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24577                 error "dd to create source file failed"
24578         stack_trap "rm -f $DIR/$tfile"
24579
24580         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24581                 error "parallel dio write with failure on second stripe succeeded"
24582         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24583         diff $DIR/$tfile $DIR/$tfile.1
24584         [[ $? == 0 ]] || error "data incorrect after append"
24585
24586 }
24587 run_test 398n "test append with parallel DIO"
24588
24589 test_fake_rw() {
24590         local read_write=$1
24591         if [ "$read_write" = "write" ]; then
24592                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24593         elif [ "$read_write" = "read" ]; then
24594                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24595         else
24596                 error "argument error"
24597         fi
24598
24599         # turn off debug for performance testing
24600         local saved_debug=$($LCTL get_param -n debug)
24601         $LCTL set_param debug=0
24602
24603         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24604
24605         # get ost1 size - $FSNAME-OST0000
24606         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24607         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
24608         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
24609
24610         if [ "$read_write" = "read" ]; then
24611                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
24612         fi
24613
24614         local start_time=$(date +%s.%N)
24615         $dd_cmd bs=1M count=$blocks oflag=sync ||
24616                 error "real dd $read_write error"
24617         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
24618
24619         if [ "$read_write" = "write" ]; then
24620                 rm -f $DIR/$tfile
24621         fi
24622
24623         # define OBD_FAIL_OST_FAKE_RW           0x238
24624         do_facet ost1 $LCTL set_param fail_loc=0x238
24625
24626         local start_time=$(date +%s.%N)
24627         $dd_cmd bs=1M count=$blocks oflag=sync ||
24628                 error "fake dd $read_write error"
24629         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
24630
24631         if [ "$read_write" = "write" ]; then
24632                 # verify file size
24633                 cancel_lru_locks osc
24634                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
24635                         error "$tfile size not $blocks MB"
24636         fi
24637         do_facet ost1 $LCTL set_param fail_loc=0
24638
24639         echo "fake $read_write $duration_fake vs. normal $read_write" \
24640                 "$duration in seconds"
24641         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
24642                 error_not_in_vm "fake write is slower"
24643
24644         $LCTL set_param -n debug="$saved_debug"
24645         rm -f $DIR/$tfile
24646 }
24647 test_399a() { # LU-7655 for OST fake write
24648         remote_ost_nodsh && skip "remote OST with nodsh"
24649
24650         test_fake_rw write
24651 }
24652 run_test 399a "fake write should not be slower than normal write"
24653
24654 test_399b() { # LU-8726 for OST fake read
24655         remote_ost_nodsh && skip "remote OST with nodsh"
24656         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
24657                 skip_env "ldiskfs only test"
24658         fi
24659
24660         test_fake_rw read
24661 }
24662 run_test 399b "fake read should not be slower than normal read"
24663
24664 test_400a() { # LU-1606, was conf-sanity test_74
24665         if ! which $CC > /dev/null 2>&1; then
24666                 skip_env "$CC is not installed"
24667         fi
24668
24669         local extra_flags=''
24670         local out=$TMP/$tfile
24671         local prefix=/usr/include/lustre
24672         local prog
24673
24674         # Oleg removes c files in his test rig so test if any c files exist
24675         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24676                 skip_env "Needed c test files are missing"
24677
24678         if ! [[ -d $prefix ]]; then
24679                 # Assume we're running in tree and fixup the include path.
24680                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24681                 extra_flags+=" -L$LUSTRE/utils/.lib"
24682         fi
24683
24684         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24685                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24686                         error "client api broken"
24687         done
24688         rm -f $out
24689 }
24690 run_test 400a "Lustre client api program can compile and link"
24691
24692 test_400b() { # LU-1606, LU-5011
24693         local header
24694         local out=$TMP/$tfile
24695         local prefix=/usr/include/linux/lustre
24696
24697         # We use a hard coded prefix so that this test will not fail
24698         # when run in tree. There are headers in lustre/include/lustre/
24699         # that are not packaged (like lustre_idl.h) and have more
24700         # complicated include dependencies (like config.h and lnet/types.h).
24701         # Since this test about correct packaging we just skip them when
24702         # they don't exist (see below) rather than try to fixup cppflags.
24703
24704         if ! which $CC > /dev/null 2>&1; then
24705                 skip_env "$CC is not installed"
24706         fi
24707
24708         for header in $prefix/*.h; do
24709                 if ! [[ -f "$header" ]]; then
24710                         continue
24711                 fi
24712
24713                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24714                         continue # lustre_ioctl.h is internal header
24715                 fi
24716
24717                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24718                         error "cannot compile '$header'"
24719         done
24720         rm -f $out
24721 }
24722 run_test 400b "packaged headers can be compiled"
24723
24724 test_401a() { #LU-7437
24725         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
24726         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
24727
24728         #count the number of parameters by "list_param -R"
24729         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
24730         #count the number of parameters by listing proc files
24731         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
24732         echo "proc_dirs='$proc_dirs'"
24733         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
24734         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
24735                       sort -u | wc -l)
24736
24737         [ $params -eq $procs ] ||
24738                 error "found $params parameters vs. $procs proc files"
24739
24740         # test the list_param -D option only returns directories
24741         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
24742         #count the number of parameters by listing proc directories
24743         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
24744                 sort -u | wc -l)
24745
24746         [ $params -eq $procs ] ||
24747                 error "found $params parameters vs. $procs proc files"
24748 }
24749 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
24750
24751 test_401b() {
24752         # jobid_var may not allow arbitrary values, so use jobid_name
24753         # if available
24754         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24755                 local testname=jobid_name tmp='testing%p'
24756         else
24757                 local testname=jobid_var tmp=testing
24758         fi
24759
24760         local save=$($LCTL get_param -n $testname)
24761
24762         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
24763                 error "no error returned when setting bad parameters"
24764
24765         local jobid_new=$($LCTL get_param -n foe $testname baz)
24766         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
24767
24768         $LCTL set_param -n fog=bam $testname=$save bat=fog
24769         local jobid_old=$($LCTL get_param -n foe $testname bag)
24770         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
24771 }
24772 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
24773
24774 test_401c() {
24775         # jobid_var may not allow arbitrary values, so use jobid_name
24776         # if available
24777         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24778                 local testname=jobid_name
24779         else
24780                 local testname=jobid_var
24781         fi
24782
24783         local jobid_var_old=$($LCTL get_param -n $testname)
24784         local jobid_var_new
24785
24786         $LCTL set_param $testname= &&
24787                 error "no error returned for 'set_param a='"
24788
24789         jobid_var_new=$($LCTL get_param -n $testname)
24790         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24791                 error "$testname was changed by setting without value"
24792
24793         $LCTL set_param $testname &&
24794                 error "no error returned for 'set_param a'"
24795
24796         jobid_var_new=$($LCTL get_param -n $testname)
24797         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24798                 error "$testname was changed by setting without value"
24799 }
24800 run_test 401c "Verify 'lctl set_param' without value fails in either format."
24801
24802 test_401d() {
24803         # jobid_var may not allow arbitrary values, so use jobid_name
24804         # if available
24805         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24806                 local testname=jobid_name new_value='foo=bar%p'
24807         else
24808                 local testname=jobid_var new_valuie=foo=bar
24809         fi
24810
24811         local jobid_var_old=$($LCTL get_param -n $testname)
24812         local jobid_var_new
24813
24814         $LCTL set_param $testname=$new_value ||
24815                 error "'set_param a=b' did not accept a value containing '='"
24816
24817         jobid_var_new=$($LCTL get_param -n $testname)
24818         [[ "$jobid_var_new" == "$new_value" ]] ||
24819                 error "'set_param a=b' failed on a value containing '='"
24820
24821         # Reset the $testname to test the other format
24822         $LCTL set_param $testname=$jobid_var_old
24823         jobid_var_new=$($LCTL get_param -n $testname)
24824         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24825                 error "failed to reset $testname"
24826
24827         $LCTL set_param $testname $new_value ||
24828                 error "'set_param a b' did not accept a value containing '='"
24829
24830         jobid_var_new=$($LCTL get_param -n $testname)
24831         [[ "$jobid_var_new" == "$new_value" ]] ||
24832                 error "'set_param a b' failed on a value containing '='"
24833
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 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
24840
24841 test_401e() { # LU-14779
24842         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
24843                 error "lctl list_param MGC* failed"
24844         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
24845         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
24846                 error "lctl get_param lru_size failed"
24847 }
24848 run_test 401e "verify 'lctl get_param' works with NID in parameter"
24849
24850 test_402() {
24851         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
24852         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
24853                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
24854         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
24855                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
24856                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
24857         remote_mds_nodsh && skip "remote MDS with nodsh"
24858
24859         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
24860 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
24861         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
24862         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
24863                 echo "Touch failed - OK"
24864 }
24865 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
24866
24867 test_403() {
24868         local file1=$DIR/$tfile.1
24869         local file2=$DIR/$tfile.2
24870         local tfile=$TMP/$tfile
24871
24872         rm -f $file1 $file2 $tfile
24873
24874         touch $file1
24875         ln $file1 $file2
24876
24877         # 30 sec OBD_TIMEOUT in ll_getattr()
24878         # right before populating st_nlink
24879         $LCTL set_param fail_loc=0x80001409
24880         stat -c %h $file1 > $tfile &
24881
24882         # create an alias, drop all locks and reclaim the dentry
24883         < $file2
24884         cancel_lru_locks mdc
24885         cancel_lru_locks osc
24886         sysctl -w vm.drop_caches=2
24887
24888         wait
24889
24890         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
24891
24892         rm -f $tfile $file1 $file2
24893 }
24894 run_test 403 "i_nlink should not drop to zero due to aliasing"
24895
24896 test_404() { # LU-6601
24897         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
24898                 skip "Need server version newer than 2.8.52"
24899         remote_mds_nodsh && skip "remote MDS with nodsh"
24900
24901         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
24902                 awk '/osp .*-osc-MDT/ { print $4}')
24903
24904         local osp
24905         for osp in $mosps; do
24906                 echo "Deactivate: " $osp
24907                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
24908                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24909                         awk -vp=$osp '$4 == p { print $2 }')
24910                 [ $stat = IN ] || {
24911                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24912                         error "deactivate error"
24913                 }
24914                 echo "Activate: " $osp
24915                 do_facet $SINGLEMDS $LCTL --device %$osp activate
24916                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24917                         awk -vp=$osp '$4 == p { print $2 }')
24918                 [ $stat = UP ] || {
24919                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24920                         error "activate error"
24921                 }
24922         done
24923 }
24924 run_test 404 "validate manual {de}activated works properly for OSPs"
24925
24926 test_405() {
24927         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24928         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
24929                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
24930                         skip "Layout swap lock is not supported"
24931
24932         check_swap_layouts_support
24933         check_swap_layout_no_dom $DIR
24934
24935         test_mkdir $DIR/$tdir
24936         swap_lock_test -d $DIR/$tdir ||
24937                 error "One layout swap locked test failed"
24938 }
24939 run_test 405 "Various layout swap lock tests"
24940
24941 test_406() {
24942         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24943         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
24944         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
24945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24946         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
24947                 skip "Need MDS version at least 2.8.50"
24948
24949         local def_stripe_size=$($LFS getstripe -S $MOUNT)
24950         local test_pool=$TESTNAME
24951
24952         pool_add $test_pool || error "pool_add failed"
24953         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
24954                 error "pool_add_targets failed"
24955
24956         save_layout_restore_at_exit $MOUNT
24957
24958         # parent set default stripe count only, child will stripe from both
24959         # parent and fs default
24960         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
24961                 error "setstripe $MOUNT failed"
24962         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
24963         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
24964         for i in $(seq 10); do
24965                 local f=$DIR/$tdir/$tfile.$i
24966                 touch $f || error "touch failed"
24967                 local count=$($LFS getstripe -c $f)
24968                 [ $count -eq $OSTCOUNT ] ||
24969                         error "$f stripe count $count != $OSTCOUNT"
24970                 local offset=$($LFS getstripe -i $f)
24971                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
24972                 local size=$($LFS getstripe -S $f)
24973                 [ $size -eq $((def_stripe_size * 2)) ] ||
24974                         error "$f stripe size $size != $((def_stripe_size * 2))"
24975                 local pool=$($LFS getstripe -p $f)
24976                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
24977         done
24978
24979         # change fs default striping, delete parent default striping, now child
24980         # will stripe from new fs default striping only
24981         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
24982                 error "change $MOUNT default stripe failed"
24983         $LFS setstripe -c 0 $DIR/$tdir ||
24984                 error "delete $tdir default stripe failed"
24985         for i in $(seq 11 20); do
24986                 local f=$DIR/$tdir/$tfile.$i
24987                 touch $f || error "touch $f failed"
24988                 local count=$($LFS getstripe -c $f)
24989                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
24990                 local offset=$($LFS getstripe -i $f)
24991                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
24992                 local size=$($LFS getstripe -S $f)
24993                 [ $size -eq $def_stripe_size ] ||
24994                         error "$f stripe size $size != $def_stripe_size"
24995                 local pool=$($LFS getstripe -p $f)
24996                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
24997         done
24998
24999         unlinkmany $DIR/$tdir/$tfile. 1 20
25000
25001         local f=$DIR/$tdir/$tfile
25002         pool_remove_all_targets $test_pool $f
25003         pool_remove $test_pool $f
25004 }
25005 run_test 406 "DNE support fs default striping"
25006
25007 test_407() {
25008         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25009         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25010                 skip "Need MDS version at least 2.8.55"
25011         remote_mds_nodsh && skip "remote MDS with nodsh"
25012
25013         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25014                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25015         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25016                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25017         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25018
25019         #define OBD_FAIL_DT_TXN_STOP    0x2019
25020         for idx in $(seq $MDSCOUNT); do
25021                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25022         done
25023         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25024         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25025                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25026         true
25027 }
25028 run_test 407 "transaction fail should cause operation fail"
25029
25030 test_408() {
25031         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25032
25033         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25034         lctl set_param fail_loc=0x8000040a
25035         # let ll_prepare_partial_page() fail
25036         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25037
25038         rm -f $DIR/$tfile
25039
25040         # create at least 100 unused inodes so that
25041         # shrink_icache_memory(0) should not return 0
25042         touch $DIR/$tfile-{0..100}
25043         rm -f $DIR/$tfile-{0..100}
25044         sync
25045
25046         echo 2 > /proc/sys/vm/drop_caches
25047 }
25048 run_test 408 "drop_caches should not hang due to page leaks"
25049
25050 test_409()
25051 {
25052         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25053
25054         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25055         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25056         touch $DIR/$tdir/guard || error "(2) Fail to create"
25057
25058         local PREFIX=$(str_repeat 'A' 128)
25059         echo "Create 1K hard links start at $(date)"
25060         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25061                 error "(3) Fail to hard link"
25062
25063         echo "Links count should be right although linkEA overflow"
25064         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25065         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25066         [ $linkcount -eq 1001 ] ||
25067                 error "(5) Unexpected hard links count: $linkcount"
25068
25069         echo "List all links start at $(date)"
25070         ls -l $DIR/$tdir/foo > /dev/null ||
25071                 error "(6) Fail to list $DIR/$tdir/foo"
25072
25073         echo "Unlink hard links start at $(date)"
25074         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25075                 error "(7) Fail to unlink"
25076         echo "Unlink hard links finished at $(date)"
25077 }
25078 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25079
25080 test_410()
25081 {
25082         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25083                 skip "Need client version at least 2.9.59"
25084         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25085                 skip "Need MODULES build"
25086
25087         # Create a file, and stat it from the kernel
25088         local testfile=$DIR/$tfile
25089         touch $testfile
25090
25091         local run_id=$RANDOM
25092         local my_ino=$(stat --format "%i" $testfile)
25093
25094         # Try to insert the module. This will always fail as the
25095         # module is designed to not be inserted.
25096         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25097             &> /dev/null
25098
25099         # Anything but success is a test failure
25100         dmesg | grep -q \
25101             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25102             error "no inode match"
25103 }
25104 run_test 410 "Test inode number returned from kernel thread"
25105
25106 cleanup_test411_cgroup() {
25107         trap 0
25108         rmdir "$1"
25109 }
25110
25111 test_411() {
25112         local cg_basedir=/sys/fs/cgroup/memory
25113         # LU-9966
25114         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25115                 skip "no setup for cgroup"
25116
25117         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25118                 error "test file creation failed"
25119         cancel_lru_locks osc
25120
25121         # Create a very small memory cgroup to force a slab allocation error
25122         local cgdir=$cg_basedir/osc_slab_alloc
25123         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25124         trap "cleanup_test411_cgroup $cgdir" EXIT
25125         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25126         echo 1M > $cgdir/memory.limit_in_bytes
25127
25128         # Should not LBUG, just be killed by oom-killer
25129         # dd will return 0 even allocation failure in some environment.
25130         # So don't check return value
25131         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25132         cleanup_test411_cgroup $cgdir
25133
25134         return 0
25135 }
25136 run_test 411 "Slab allocation error with cgroup does not LBUG"
25137
25138 test_412() {
25139         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25140         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25141                 skip "Need server version at least 2.10.55"
25142
25143         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25144                 error "mkdir failed"
25145         $LFS getdirstripe $DIR/$tdir
25146         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25147         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25148                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25149         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25150         [ $stripe_count -eq 2 ] ||
25151                 error "expect 2 get $stripe_count"
25152
25153         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25154
25155         local index
25156         local index2
25157
25158         # subdirs should be on the same MDT as parent
25159         for i in $(seq 0 $((MDSCOUNT - 1))); do
25160                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25161                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25162                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25163                 (( index == i )) || error "mdt$i/sub on MDT$index"
25164         done
25165
25166         # stripe offset -1, ditto
25167         for i in {1..10}; do
25168                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25169                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25170                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25171                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25172                 (( index == index2 )) ||
25173                         error "qos$i on MDT$index, sub on MDT$index2"
25174         done
25175
25176         local testdir=$DIR/$tdir/inherit
25177
25178         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25179         # inherit 2 levels
25180         for i in 1 2; do
25181                 testdir=$testdir/s$i
25182                 mkdir $testdir || error "mkdir $testdir failed"
25183                 index=$($LFS getstripe -m $testdir)
25184                 (( index == 1 )) ||
25185                         error "$testdir on MDT$index"
25186         done
25187
25188         # not inherit any more
25189         testdir=$testdir/s3
25190         mkdir $testdir || error "mkdir $testdir failed"
25191         getfattr -d -m dmv $testdir | grep dmv &&
25192                 error "default LMV set on $testdir" || true
25193 }
25194 run_test 412 "mkdir on specific MDTs"
25195
25196 generate_uneven_mdts() {
25197         local threshold=$1
25198         local lmv_qos_maxage
25199         local lod_qos_maxage
25200         local ffree
25201         local bavail
25202         local max
25203         local min
25204         local max_index
25205         local min_index
25206         local tmp
25207         local i
25208
25209         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25210         $LCTL set_param lmv.*.qos_maxage=1
25211         stack_trap "$LCTL set_param \
25212                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25213         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25214                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25215         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25216                 lod.*.mdt_qos_maxage=1
25217         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25218                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25219
25220         echo
25221         echo "Check for uneven MDTs: "
25222
25223         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25224         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25225         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25226
25227         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25228         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25229         max_index=0
25230         min_index=0
25231         for ((i = 1; i < ${#ffree[@]}; i++)); do
25232                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25233                 if [ $tmp -gt $max ]; then
25234                         max=$tmp
25235                         max_index=$i
25236                 fi
25237                 if [ $tmp -lt $min ]; then
25238                         min=$tmp
25239                         min_index=$i
25240                 fi
25241         done
25242
25243         (( ${ffree[min_index]} > 0 )) ||
25244                 skip "no free files in MDT$min_index"
25245         (( ${ffree[min_index]} < 10000000 )) ||
25246                 skip "too many free files in MDT$min_index"
25247
25248         # Check if we need to generate uneven MDTs
25249         local diff=$(((max - min) * 100 / min))
25250         local testdir=$DIR/$tdir-fillmdt
25251         local start
25252
25253         mkdir -p $testdir
25254
25255         i=0
25256         while (( diff < threshold )); do
25257                 # generate uneven MDTs, create till $threshold% diff
25258                 echo -n "weight diff=$diff% must be > $threshold% ..."
25259                 echo "Fill MDT$min_index with 1000 files: loop $i"
25260                 testdir=$DIR/$tdir-fillmdt/$i
25261                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
25262                         error "mkdir $testdir failed"
25263                 $LFS setstripe -E 1M -L mdt $testdir ||
25264                         error "setstripe $testdir failed"
25265                 start=$SECONDS
25266                 for F in f.{0..999}; do
25267                         dd if=/dev/zero of=$testdir/$F bs=64K count=1 > \
25268                                 /dev/null 2>&1 || error "dd $F failed"
25269                 done
25270
25271                 # wait for QOS to update
25272                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25273
25274                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25275                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25276                 max=$(((${ffree[max_index]} >> 8) * \
25277                         (${bavail[max_index]} * bsize >> 16)))
25278                 min=$(((${ffree[min_index]} >> 8) * \
25279                         (${bavail[min_index]} * bsize >> 16)))
25280                 diff=$(((max - min) * 100 / min))
25281                 i=$((i + 1))
25282         done
25283
25284         echo "MDT filesfree available: ${ffree[@]}"
25285         echo "MDT blocks available: ${bavail[@]}"
25286         echo "weight diff=$diff%"
25287 }
25288
25289 test_qos_mkdir() {
25290         local mkdir_cmd=$1
25291         local stripe_count=$2
25292         local mdts=$(comma_list $(mdts_nodes))
25293
25294         local testdir
25295         local lmv_qos_prio_free
25296         local lmv_qos_threshold_rr
25297         local lmv_qos_maxage
25298         local lod_qos_prio_free
25299         local lod_qos_threshold_rr
25300         local lod_qos_maxage
25301         local count
25302         local i
25303
25304         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25305         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25306         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25307                 head -n1)
25308         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25309         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25310         stack_trap "$LCTL set_param \
25311                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25312         stack_trap "$LCTL set_param \
25313                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25314         stack_trap "$LCTL set_param \
25315                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25316
25317         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25318                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25319         lod_qos_prio_free=${lod_qos_prio_free%%%}
25320         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25321                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25322         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25323         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25324                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25325         stack_trap "do_nodes $mdts $LCTL set_param \
25326                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25327         stack_trap "do_nodes $mdts $LCTL set_param \
25328                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25329         stack_trap "do_nodes $mdts $LCTL set_param \
25330                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25331
25332         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25333         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25334
25335         testdir=$DIR/$tdir-s$stripe_count/rr
25336
25337         local stripe_index=$($LFS getstripe -m $testdir)
25338         local test_mkdir_rr=true
25339
25340         getfattr -d -m dmv -e hex $testdir | grep dmv
25341         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25342                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25343                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25344                         test_mkdir_rr=false
25345         fi
25346
25347         echo
25348         $test_mkdir_rr &&
25349                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25350                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25351
25352         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25353         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25354                 eval $mkdir_cmd $testdir/subdir$i ||
25355                         error "$mkdir_cmd subdir$i failed"
25356         done
25357
25358         for (( i = 0; i < $MDSCOUNT; i++ )); do
25359                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25360                 echo "$count directories created on MDT$i"
25361                 if $test_mkdir_rr; then
25362                         (( $count == 100 )) ||
25363                                 error "subdirs are not evenly distributed"
25364                 elif (( $i == $stripe_index )); then
25365                         (( $count == 100 * MDSCOUNT )) ||
25366                                 error "$count subdirs created on MDT$i"
25367                 else
25368                         (( $count == 0 )) ||
25369                                 error "$count subdirs created on MDT$i"
25370                 fi
25371
25372                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25373                         count=$($LFS getdirstripe $testdir/* |
25374                                 grep -c -P "^\s+$i\t")
25375                         echo "$count stripes created on MDT$i"
25376                         # deviation should < 5% of average
25377                         (( $count >= 95 * stripe_count &&
25378                            $count <= 105 * stripe_count)) ||
25379                                 error "stripes are not evenly distributed"
25380                 fi
25381         done
25382
25383         echo
25384         echo "Check for uneven MDTs: "
25385
25386         local ffree
25387         local bavail
25388         local max
25389         local min
25390         local max_index
25391         local min_index
25392         local tmp
25393
25394         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25395         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25396         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25397
25398         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25399         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25400         max_index=0
25401         min_index=0
25402         for ((i = 1; i < ${#ffree[@]}; i++)); do
25403                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25404                 if [ $tmp -gt $max ]; then
25405                         max=$tmp
25406                         max_index=$i
25407                 fi
25408                 if [ $tmp -lt $min ]; then
25409                         min=$tmp
25410                         min_index=$i
25411                 fi
25412         done
25413
25414         (( ${ffree[min_index]} > 0 )) ||
25415                 skip "no free files in MDT$min_index"
25416         (( ${ffree[min_index]} < 10000000 )) ||
25417                 skip "too many free files in MDT$min_index"
25418
25419         echo "MDT filesfree available: ${ffree[@]}"
25420         echo "MDT blocks available: ${bavail[@]}"
25421         echo "weight diff=$(((max - min) * 100 / min))%"
25422         echo
25423         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25424
25425         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25426         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25427         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25428         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25429         # decrease statfs age, so that it can be updated in time
25430         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25431         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25432
25433         sleep 1
25434
25435         testdir=$DIR/$tdir-s$stripe_count/qos
25436         local num=200
25437
25438         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25439         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25440                 eval $mkdir_cmd $testdir/subdir$i ||
25441                         error "$mkdir_cmd subdir$i failed"
25442         done
25443
25444         max=0
25445         for (( i = 0; i < $MDSCOUNT; i++ )); do
25446                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25447                 (( count > max )) && max=$count
25448                 echo "$count directories created on MDT$i"
25449         done
25450
25451         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25452
25453         # D-value should > 10% of averge
25454         (( max - min > num / 10 )) ||
25455                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25456
25457         # ditto for stripes
25458         if (( stripe_count > 1 )); then
25459                 max=0
25460                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25461                         count=$($LFS getdirstripe $testdir/* |
25462                                 grep -c -P "^\s+$i\t")
25463                         (( count > max )) && max=$count
25464                         echo "$count stripes created on MDT$i"
25465                 done
25466
25467                 min=$($LFS getdirstripe $testdir/* |
25468                         grep -c -P "^\s+$min_index\t")
25469                 (( max - min > num * stripe_count / 10 )) ||
25470                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25471         fi
25472 }
25473
25474 most_full_mdt() {
25475         local ffree
25476         local bavail
25477         local bsize
25478         local min
25479         local min_index
25480         local tmp
25481
25482         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25483         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25484         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25485
25486         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25487         min_index=0
25488         for ((i = 1; i < ${#ffree[@]}; i++)); do
25489                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25490                 (( tmp < min )) && min=$tmp && min_index=$i
25491         done
25492
25493         echo -n $min_index
25494 }
25495
25496 test_413a() {
25497         [ $MDSCOUNT -lt 2 ] &&
25498                 skip "We need at least 2 MDTs for this test"
25499
25500         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25501                 skip "Need server version at least 2.12.52"
25502
25503         local stripe_count
25504
25505         generate_uneven_mdts 100
25506         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25507                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25508                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25509                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25510                         error "mkdir failed"
25511                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25512         done
25513 }
25514 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25515
25516 test_413b() {
25517         [ $MDSCOUNT -lt 2 ] &&
25518                 skip "We need at least 2 MDTs for this test"
25519
25520         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25521                 skip "Need server version at least 2.12.52"
25522
25523         local testdir
25524         local stripe_count
25525
25526         generate_uneven_mdts 100
25527         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25528                 testdir=$DIR/$tdir-s$stripe_count
25529                 mkdir $testdir || error "mkdir $testdir failed"
25530                 mkdir $testdir/rr || error "mkdir rr failed"
25531                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25532                         error "mkdir qos failed"
25533                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25534                         $testdir/rr || error "setdirstripe rr failed"
25535                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25536                         error "setdirstripe failed"
25537                 test_qos_mkdir "mkdir" $stripe_count
25538         done
25539 }
25540 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25541
25542 test_413c() {
25543         (( $MDSCOUNT >= 2 )) ||
25544                 skip "We need at least 2 MDTs for this test"
25545
25546         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25547                 skip "Need server version at least 2.14.51"
25548
25549         local testdir
25550         local inherit
25551         local inherit_rr
25552
25553         testdir=$DIR/${tdir}-s1
25554         mkdir $testdir || error "mkdir $testdir failed"
25555         mkdir $testdir/rr || error "mkdir rr failed"
25556         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25557         # default max_inherit is -1, default max_inherit_rr is 0
25558         $LFS setdirstripe -D -c 1 $testdir/rr ||
25559                 error "setdirstripe rr failed"
25560         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25561                 error "setdirstripe qos failed"
25562         test_qos_mkdir "mkdir" 1
25563
25564         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25565         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25566         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25567         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25568         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25569
25570         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25571         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25572         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25573         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25574         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25575         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25576         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25577                 error "level2 shouldn't have default LMV" || true
25578 }
25579 run_test 413c "mkdir with default LMV max inherit rr"
25580
25581 test_413d() {
25582         (( MDSCOUNT >= 2 )) ||
25583                 skip "We need at least 2 MDTs for this test"
25584
25585         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25586                 skip "Need server version at least 2.14.51"
25587
25588         local lmv_qos_threshold_rr
25589
25590         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25591                 head -n1)
25592         stack_trap "$LCTL set_param \
25593                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
25594
25595         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25596         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25597         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
25598                 error "$tdir shouldn't have default LMV"
25599         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
25600                 error "mkdir sub failed"
25601
25602         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
25603
25604         (( count == 100 )) || error "$count subdirs on MDT0"
25605 }
25606 run_test 413d "inherit ROOT default LMV"
25607
25608 test_413e() {
25609         (( MDSCOUNT >= 2 )) ||
25610                 skip "We need at least 2 MDTs for this test"
25611         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25612                 skip "Need server version at least 2.14.55"
25613
25614         local testdir=$DIR/$tdir
25615         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
25616         local max_inherit
25617         local sub_max_inherit
25618
25619         mkdir -p $testdir || error "failed to create $testdir"
25620
25621         # set default max-inherit to -1 if stripe count is 0 or 1
25622         $LFS setdirstripe -D -c 1 $testdir ||
25623                 error "failed to set default LMV"
25624         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25625         (( max_inherit == -1 )) ||
25626                 error "wrong max_inherit value $max_inherit"
25627
25628         # set default max_inherit to a fixed value if stripe count is not 0 or 1
25629         $LFS setdirstripe -D -c -1 $testdir ||
25630                 error "failed to set default LMV"
25631         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25632         (( max_inherit > 0 )) ||
25633                 error "wrong max_inherit value $max_inherit"
25634
25635         # and the subdir will decrease the max_inherit by 1
25636         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
25637         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
25638         (( sub_max_inherit == max_inherit - 1)) ||
25639                 error "wrong max-inherit of subdir $sub_max_inherit"
25640
25641         # check specified --max-inherit and warning message
25642         stack_trap "rm -f $tmpfile"
25643         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
25644                 error "failed to set default LMV"
25645         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25646         (( max_inherit == -1 )) ||
25647                 error "wrong max_inherit value $max_inherit"
25648
25649         # check the warning messages
25650         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
25651                 error "failed to detect warning string"
25652         fi
25653 }
25654 run_test 413e "check default max-inherit value"
25655
25656 test_413z() {
25657         local pids=""
25658         local subdir
25659         local pid
25660
25661         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
25662                 unlinkmany $subdir/f. 1000 &
25663                 pids="$pids $!"
25664         done
25665
25666         for pid in $pids; do
25667                 wait $pid
25668         done
25669 }
25670 run_test 413z "413 test cleanup"
25671
25672 test_414() {
25673 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
25674         $LCTL set_param fail_loc=0x80000521
25675         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25676         rm -f $DIR/$tfile
25677 }
25678 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
25679
25680 test_415() {
25681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25682         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25683                 skip "Need server version at least 2.11.52"
25684
25685         # LU-11102
25686         local total
25687         local setattr_pid
25688         local start_time
25689         local end_time
25690         local duration
25691
25692         total=500
25693         # this test may be slow on ZFS
25694         [ "$mds1_FSTYPE" == "zfs" ] && total=100
25695
25696         # though this test is designed for striped directory, let's test normal
25697         # directory too since lock is always saved as CoS lock.
25698         test_mkdir $DIR/$tdir || error "mkdir $tdir"
25699         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
25700
25701         (
25702                 while true; do
25703                         touch $DIR/$tdir
25704                 done
25705         ) &
25706         setattr_pid=$!
25707
25708         start_time=$(date +%s)
25709         for i in $(seq $total); do
25710                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
25711                         > /dev/null
25712         done
25713         end_time=$(date +%s)
25714         duration=$((end_time - start_time))
25715
25716         kill -9 $setattr_pid
25717
25718         echo "rename $total files took $duration sec"
25719         [ $duration -lt 100 ] || error "rename took $duration sec"
25720 }
25721 run_test 415 "lock revoke is not missing"
25722
25723 test_416() {
25724         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25725                 skip "Need server version at least 2.11.55"
25726
25727         # define OBD_FAIL_OSD_TXN_START    0x19a
25728         do_facet mds1 lctl set_param fail_loc=0x19a
25729
25730         lfs mkdir -c $MDSCOUNT $DIR/$tdir
25731
25732         true
25733 }
25734 run_test 416 "transaction start failure won't cause system hung"
25735
25736 cleanup_417() {
25737         trap 0
25738         do_nodes $(comma_list $(mdts_nodes)) \
25739                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
25740         do_nodes $(comma_list $(mdts_nodes)) \
25741                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
25742         do_nodes $(comma_list $(mdts_nodes)) \
25743                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
25744 }
25745
25746 test_417() {
25747         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25748         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
25749                 skip "Need MDS version at least 2.11.56"
25750
25751         trap cleanup_417 RETURN EXIT
25752
25753         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
25754         do_nodes $(comma_list $(mdts_nodes)) \
25755                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
25756         $LFS migrate -m 0 $DIR/$tdir.1 &&
25757                 error "migrate dir $tdir.1 should fail"
25758
25759         do_nodes $(comma_list $(mdts_nodes)) \
25760                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
25761         $LFS mkdir -i 1 $DIR/$tdir.2 &&
25762                 error "create remote dir $tdir.2 should fail"
25763
25764         do_nodes $(comma_list $(mdts_nodes)) \
25765                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
25766         $LFS mkdir -c 2 $DIR/$tdir.3 &&
25767                 error "create striped dir $tdir.3 should fail"
25768         true
25769 }
25770 run_test 417 "disable remote dir, striped dir and dir migration"
25771
25772 # Checks that the outputs of df [-i] and lfs df [-i] match
25773 #
25774 # usage: check_lfs_df <blocks | inodes> <mountpoint>
25775 check_lfs_df() {
25776         local dir=$2
25777         local inodes
25778         local df_out
25779         local lfs_df_out
25780         local count
25781         local passed=false
25782
25783         # blocks or inodes
25784         [ "$1" == "blocks" ] && inodes= || inodes="-i"
25785
25786         for count in {1..100}; do
25787                 do_nodes "$CLIENTS" \
25788                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25789                 sync; sleep 0.2
25790
25791                 # read the lines of interest
25792                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
25793                         error "df $inodes $dir | tail -n +2 failed"
25794                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
25795                         error "lfs df $inodes $dir | grep summary: failed"
25796
25797                 # skip first substrings of each output as they are different
25798                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
25799                 # compare the two outputs
25800                 passed=true
25801                 #  skip "available" on MDT until LU-13997 is fixed.
25802                 #for i in {1..5}; do
25803                 for i in 1 2 4 5; do
25804                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
25805                 done
25806                 $passed && break
25807         done
25808
25809         if ! $passed; then
25810                 df -P $inodes $dir
25811                 echo
25812                 lfs df $inodes $dir
25813                 error "df and lfs df $1 output mismatch: "      \
25814                       "df ${inodes}: ${df_out[*]}, "            \
25815                       "lfs df ${inodes}: ${lfs_df_out[*]}"
25816         fi
25817 }
25818
25819 test_418() {
25820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25821
25822         local dir=$DIR/$tdir
25823         local numfiles=$((RANDOM % 4096 + 2))
25824         local numblocks=$((RANDOM % 256 + 1))
25825
25826         wait_delete_completed
25827         test_mkdir $dir
25828
25829         # check block output
25830         check_lfs_df blocks $dir
25831         # check inode output
25832         check_lfs_df inodes $dir
25833
25834         # create a single file and retest
25835         echo "Creating a single file and testing"
25836         createmany -o $dir/$tfile- 1 &>/dev/null ||
25837                 error "creating 1 file in $dir failed"
25838         check_lfs_df blocks $dir
25839         check_lfs_df inodes $dir
25840
25841         # create a random number of files
25842         echo "Creating $((numfiles - 1)) files and testing"
25843         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
25844                 error "creating $((numfiles - 1)) files in $dir failed"
25845
25846         # write a random number of blocks to the first test file
25847         echo "Writing $numblocks 4K blocks and testing"
25848         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
25849                 count=$numblocks &>/dev/null ||
25850                 error "dd to $dir/${tfile}-0 failed"
25851
25852         # retest
25853         check_lfs_df blocks $dir
25854         check_lfs_df inodes $dir
25855
25856         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
25857                 error "unlinking $numfiles files in $dir failed"
25858 }
25859 run_test 418 "df and lfs df outputs match"
25860
25861 test_419()
25862 {
25863         local dir=$DIR/$tdir
25864
25865         mkdir -p $dir
25866         touch $dir/file
25867
25868         cancel_lru_locks mdc
25869
25870         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
25871         $LCTL set_param fail_loc=0x1410
25872         cat $dir/file
25873         $LCTL set_param fail_loc=0
25874         rm -rf $dir
25875 }
25876 run_test 419 "Verify open file by name doesn't crash kernel"
25877
25878 test_420()
25879 {
25880         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
25881                 skip "Need MDS version at least 2.12.53"
25882
25883         local SAVE_UMASK=$(umask)
25884         local dir=$DIR/$tdir
25885         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
25886
25887         mkdir -p $dir
25888         umask 0000
25889         mkdir -m03777 $dir/testdir
25890         ls -dn $dir/testdir
25891         # Need to remove trailing '.' when SELinux is enabled
25892         local dirperms=$(ls -dn $dir/testdir |
25893                          awk '{ sub(/\.$/, "", $1); print $1}')
25894         [ $dirperms == "drwxrwsrwt" ] ||
25895                 error "incorrect perms on $dir/testdir"
25896
25897         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
25898                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
25899         ls -n $dir/testdir/testfile
25900         local fileperms=$(ls -n $dir/testdir/testfile |
25901                           awk '{ sub(/\.$/, "", $1); print $1}')
25902         [ $fileperms == "-rwxr-xr-x" ] ||
25903                 error "incorrect perms on $dir/testdir/testfile"
25904
25905         umask $SAVE_UMASK
25906 }
25907 run_test 420 "clear SGID bit on non-directories for non-members"
25908
25909 test_421a() {
25910         local cnt
25911         local fid1
25912         local fid2
25913
25914         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25915                 skip "Need MDS version at least 2.12.54"
25916
25917         test_mkdir $DIR/$tdir
25918         createmany -o $DIR/$tdir/f 3
25919         cnt=$(ls -1 $DIR/$tdir | wc -l)
25920         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25921
25922         fid1=$(lfs path2fid $DIR/$tdir/f1)
25923         fid2=$(lfs path2fid $DIR/$tdir/f2)
25924         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
25925
25926         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
25927         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
25928
25929         cnt=$(ls -1 $DIR/$tdir | wc -l)
25930         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25931
25932         rm -f $DIR/$tdir/f3 || error "can't remove f3"
25933         createmany -o $DIR/$tdir/f 3
25934         cnt=$(ls -1 $DIR/$tdir | wc -l)
25935         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25936
25937         fid1=$(lfs path2fid $DIR/$tdir/f1)
25938         fid2=$(lfs path2fid $DIR/$tdir/f2)
25939         echo "remove using fsname $FSNAME"
25940         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
25941
25942         cnt=$(ls -1 $DIR/$tdir | wc -l)
25943         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25944 }
25945 run_test 421a "simple rm by fid"
25946
25947 test_421b() {
25948         local cnt
25949         local FID1
25950         local FID2
25951
25952         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25953                 skip "Need MDS version at least 2.12.54"
25954
25955         test_mkdir $DIR/$tdir
25956         createmany -o $DIR/$tdir/f 3
25957         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
25958         MULTIPID=$!
25959
25960         FID1=$(lfs path2fid $DIR/$tdir/f1)
25961         FID2=$(lfs path2fid $DIR/$tdir/f2)
25962         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
25963
25964         kill -USR1 $MULTIPID
25965         wait
25966
25967         cnt=$(ls $DIR/$tdir | wc -l)
25968         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
25969 }
25970 run_test 421b "rm by fid on open file"
25971
25972 test_421c() {
25973         local cnt
25974         local FIDS
25975
25976         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25977                 skip "Need MDS version at least 2.12.54"
25978
25979         test_mkdir $DIR/$tdir
25980         createmany -o $DIR/$tdir/f 3
25981         touch $DIR/$tdir/$tfile
25982         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
25983         cnt=$(ls -1 $DIR/$tdir | wc -l)
25984         [ $cnt != 184 ] && error "unexpected #files: $cnt"
25985
25986         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
25987         $LFS rmfid $DIR $FID1 || error "rmfid failed"
25988
25989         cnt=$(ls $DIR/$tdir | wc -l)
25990         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
25991 }
25992 run_test 421c "rm by fid against hardlinked files"
25993
25994 test_421d() {
25995         local cnt
25996         local FIDS
25997
25998         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25999                 skip "Need MDS version at least 2.12.54"
26000
26001         test_mkdir $DIR/$tdir
26002         createmany -o $DIR/$tdir/f 4097
26003         cnt=$(ls -1 $DIR/$tdir | wc -l)
26004         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26005
26006         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26007         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26008
26009         cnt=$(ls $DIR/$tdir | wc -l)
26010         rm -rf $DIR/$tdir
26011         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26012 }
26013 run_test 421d "rmfid en masse"
26014
26015 test_421e() {
26016         local cnt
26017         local FID
26018
26019         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26020         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26021                 skip "Need MDS version at least 2.12.54"
26022
26023         mkdir -p $DIR/$tdir
26024         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26025         createmany -o $DIR/$tdir/striped_dir/f 512
26026         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26027         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26028
26029         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26030                 sed "s/[/][^:]*://g")
26031         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26032
26033         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26034         rm -rf $DIR/$tdir
26035         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26036 }
26037 run_test 421e "rmfid in DNE"
26038
26039 test_421f() {
26040         local cnt
26041         local FID
26042
26043         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26044                 skip "Need MDS version at least 2.12.54"
26045
26046         test_mkdir $DIR/$tdir
26047         touch $DIR/$tdir/f
26048         cnt=$(ls -1 $DIR/$tdir | wc -l)
26049         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26050
26051         FID=$(lfs path2fid $DIR/$tdir/f)
26052         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26053         # rmfid should fail
26054         cnt=$(ls -1 $DIR/$tdir | wc -l)
26055         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26056
26057         chmod a+rw $DIR/$tdir
26058         ls -la $DIR/$tdir
26059         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26060         # rmfid should fail
26061         cnt=$(ls -1 $DIR/$tdir | wc -l)
26062         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26063
26064         rm -f $DIR/$tdir/f
26065         $RUNAS touch $DIR/$tdir/f
26066         FID=$(lfs path2fid $DIR/$tdir/f)
26067         echo "rmfid as root"
26068         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26069         cnt=$(ls -1 $DIR/$tdir | wc -l)
26070         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26071
26072         rm -f $DIR/$tdir/f
26073         $RUNAS touch $DIR/$tdir/f
26074         cnt=$(ls -1 $DIR/$tdir | wc -l)
26075         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26076         FID=$(lfs path2fid $DIR/$tdir/f)
26077         # rmfid w/o user_fid2path mount option should fail
26078         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26079         cnt=$(ls -1 $DIR/$tdir | wc -l)
26080         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26081
26082         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26083         stack_trap "rmdir $tmpdir"
26084         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26085                 error "failed to mount client'"
26086         stack_trap "umount_client $tmpdir"
26087
26088         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26089         # rmfid should succeed
26090         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26091         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26092
26093         # rmfid shouldn't allow to remove files due to dir's permission
26094         chmod a+rwx $tmpdir/$tdir
26095         touch $tmpdir/$tdir/f
26096         ls -la $tmpdir/$tdir
26097         FID=$(lfs path2fid $tmpdir/$tdir/f)
26098         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26099         return 0
26100 }
26101 run_test 421f "rmfid checks permissions"
26102
26103 test_421g() {
26104         local cnt
26105         local FIDS
26106
26107         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26108         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26109                 skip "Need MDS version at least 2.12.54"
26110
26111         mkdir -p $DIR/$tdir
26112         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26113         createmany -o $DIR/$tdir/striped_dir/f 512
26114         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26115         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26116
26117         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26118                 sed "s/[/][^:]*://g")
26119
26120         rm -f $DIR/$tdir/striped_dir/f1*
26121         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26122         removed=$((512 - cnt))
26123
26124         # few files have been just removed, so we expect
26125         # rmfid to fail on their fids
26126         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26127         [ $removed != $errors ] && error "$errors != $removed"
26128
26129         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26130         rm -rf $DIR/$tdir
26131         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26132 }
26133 run_test 421g "rmfid to return errors properly"
26134
26135 test_422() {
26136         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26137         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26138         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26139         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26140         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26141
26142         local amc=$(at_max_get client)
26143         local amo=$(at_max_get mds1)
26144         local timeout=`lctl get_param -n timeout`
26145
26146         at_max_set 0 client
26147         at_max_set 0 mds1
26148
26149 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26150         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26151                         fail_val=$(((2*timeout + 10)*1000))
26152         touch $DIR/$tdir/d3/file &
26153         sleep 2
26154 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26155         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26156                         fail_val=$((2*timeout + 5))
26157         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26158         local pid=$!
26159         sleep 1
26160         kill -9 $pid
26161         sleep $((2 * timeout))
26162         echo kill $pid
26163         kill -9 $pid
26164         lctl mark touch
26165         touch $DIR/$tdir/d2/file3
26166         touch $DIR/$tdir/d2/file4
26167         touch $DIR/$tdir/d2/file5
26168
26169         wait
26170         at_max_set $amc client
26171         at_max_set $amo mds1
26172
26173         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26174         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26175                 error "Watchdog is always throttled"
26176 }
26177 run_test 422 "kill a process with RPC in progress"
26178
26179 stat_test() {
26180     df -h $MOUNT &
26181     df -h $MOUNT &
26182     df -h $MOUNT &
26183     df -h $MOUNT &
26184     df -h $MOUNT &
26185     df -h $MOUNT &
26186 }
26187
26188 test_423() {
26189     local _stats
26190     # ensure statfs cache is expired
26191     sleep 2;
26192
26193     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26194     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26195
26196     return 0
26197 }
26198 run_test 423 "statfs should return a right data"
26199
26200 test_424() {
26201 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26202         $LCTL set_param fail_loc=0x80000522
26203         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26204         rm -f $DIR/$tfile
26205 }
26206 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26207
26208 test_425() {
26209         test_mkdir -c -1 $DIR/$tdir
26210         $LFS setstripe -c -1 $DIR/$tdir
26211
26212         lru_resize_disable "" 100
26213         stack_trap "lru_resize_enable" EXIT
26214
26215         sleep 5
26216
26217         for i in $(seq $((MDSCOUNT * 125))); do
26218                 local t=$DIR/$tdir/$tfile_$i
26219
26220                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26221                         error_noexit "Create file $t"
26222         done
26223         stack_trap "rm -rf $DIR/$tdir" EXIT
26224
26225         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26226                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26227                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26228
26229                 [ $lock_count -le $lru_size ] ||
26230                         error "osc lock count $lock_count > lru size $lru_size"
26231         done
26232
26233         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26234                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26235                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26236
26237                 [ $lock_count -le $lru_size ] ||
26238                         error "mdc lock count $lock_count > lru size $lru_size"
26239         done
26240 }
26241 run_test 425 "lock count should not exceed lru size"
26242
26243 test_426() {
26244         splice-test -r $DIR/$tfile
26245         splice-test -rd $DIR/$tfile
26246         splice-test $DIR/$tfile
26247         splice-test -d $DIR/$tfile
26248 }
26249 run_test 426 "splice test on Lustre"
26250
26251 test_427() {
26252         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26253         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26254                 skip "Need MDS version at least 2.12.4"
26255         local log
26256
26257         mkdir $DIR/$tdir
26258         mkdir $DIR/$tdir/1
26259         mkdir $DIR/$tdir/2
26260         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26261         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26262
26263         $LFS getdirstripe $DIR/$tdir/1/dir
26264
26265         #first setfattr for creating updatelog
26266         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26267
26268 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26269         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26270         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26271         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26272
26273         sleep 2
26274         fail mds2
26275         wait_recovery_complete mds2 $((2*TIMEOUT))
26276
26277         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26278         echo $log | grep "get update log failed" &&
26279                 error "update log corruption is detected" || true
26280 }
26281 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26282
26283 test_428() {
26284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26285         local cache_limit=$CACHE_MAX
26286
26287         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26288         $LCTL set_param -n llite.*.max_cached_mb=64
26289
26290         mkdir $DIR/$tdir
26291         $LFS setstripe -c 1 $DIR/$tdir
26292         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26293         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26294         #test write
26295         for f in $(seq 4); do
26296                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26297         done
26298         wait
26299
26300         cancel_lru_locks osc
26301         # Test read
26302         for f in $(seq 4); do
26303                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26304         done
26305         wait
26306 }
26307 run_test 428 "large block size IO should not hang"
26308
26309 test_429() { # LU-7915 / LU-10948
26310         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26311         local testfile=$DIR/$tfile
26312         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26313         local new_flag=1
26314         local first_rpc
26315         local second_rpc
26316         local third_rpc
26317
26318         $LCTL get_param $ll_opencache_threshold_count ||
26319                 skip "client does not have opencache parameter"
26320
26321         set_opencache $new_flag
26322         stack_trap "restore_opencache"
26323         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26324                 error "enable opencache failed"
26325         touch $testfile
26326         # drop MDC DLM locks
26327         cancel_lru_locks mdc
26328         # clear MDC RPC stats counters
26329         $LCTL set_param $mdc_rpcstats=clear
26330
26331         # According to the current implementation, we need to run 3 times
26332         # open & close file to verify if opencache is enabled correctly.
26333         # 1st, RPCs are sent for lookup/open and open handle is released on
26334         #      close finally.
26335         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26336         #      so open handle won't be released thereafter.
26337         # 3rd, No RPC is sent out.
26338         $MULTIOP $testfile oc || error "multiop failed"
26339         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26340         echo "1st: $first_rpc RPCs in flight"
26341
26342         $MULTIOP $testfile oc || error "multiop failed"
26343         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26344         echo "2nd: $second_rpc RPCs in flight"
26345
26346         $MULTIOP $testfile oc || error "multiop failed"
26347         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26348         echo "3rd: $third_rpc RPCs in flight"
26349
26350         #verify no MDC RPC is sent
26351         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26352 }
26353 run_test 429 "verify if opencache flag on client side does work"
26354
26355 lseek_test_430() {
26356         local offset
26357         local file=$1
26358
26359         # data at [200K, 400K)
26360         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26361                 error "256K->512K dd fails"
26362         # data at [2M, 3M)
26363         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26364                 error "2M->3M dd fails"
26365         # data at [4M, 5M)
26366         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26367                 error "4M->5M dd fails"
26368         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26369         # start at first component hole #1
26370         printf "Seeking hole from 1000 ... "
26371         offset=$(lseek_test -l 1000 $file)
26372         echo $offset
26373         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26374         printf "Seeking data from 1000 ... "
26375         offset=$(lseek_test -d 1000 $file)
26376         echo $offset
26377         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26378
26379         # start at first component data block
26380         printf "Seeking hole from 300000 ... "
26381         offset=$(lseek_test -l 300000 $file)
26382         echo $offset
26383         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26384         printf "Seeking data from 300000 ... "
26385         offset=$(lseek_test -d 300000 $file)
26386         echo $offset
26387         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26388
26389         # start at the first component but beyond end of object size
26390         printf "Seeking hole from 1000000 ... "
26391         offset=$(lseek_test -l 1000000 $file)
26392         echo $offset
26393         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26394         printf "Seeking data from 1000000 ... "
26395         offset=$(lseek_test -d 1000000 $file)
26396         echo $offset
26397         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26398
26399         # start at second component stripe 2 (empty file)
26400         printf "Seeking hole from 1500000 ... "
26401         offset=$(lseek_test -l 1500000 $file)
26402         echo $offset
26403         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26404         printf "Seeking data from 1500000 ... "
26405         offset=$(lseek_test -d 1500000 $file)
26406         echo $offset
26407         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26408
26409         # start at second component stripe 1 (all data)
26410         printf "Seeking hole from 3000000 ... "
26411         offset=$(lseek_test -l 3000000 $file)
26412         echo $offset
26413         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26414         printf "Seeking data from 3000000 ... "
26415         offset=$(lseek_test -d 3000000 $file)
26416         echo $offset
26417         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26418
26419         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26420                 error "2nd dd fails"
26421         echo "Add data block at 640K...1280K"
26422
26423         # start at before new data block, in hole
26424         printf "Seeking hole from 600000 ... "
26425         offset=$(lseek_test -l 600000 $file)
26426         echo $offset
26427         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26428         printf "Seeking data from 600000 ... "
26429         offset=$(lseek_test -d 600000 $file)
26430         echo $offset
26431         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26432
26433         # start at the first component new data block
26434         printf "Seeking hole from 1000000 ... "
26435         offset=$(lseek_test -l 1000000 $file)
26436         echo $offset
26437         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26438         printf "Seeking data from 1000000 ... "
26439         offset=$(lseek_test -d 1000000 $file)
26440         echo $offset
26441         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26442
26443         # start at second component stripe 2, new data
26444         printf "Seeking hole from 1200000 ... "
26445         offset=$(lseek_test -l 1200000 $file)
26446         echo $offset
26447         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26448         printf "Seeking data from 1200000 ... "
26449         offset=$(lseek_test -d 1200000 $file)
26450         echo $offset
26451         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
26452
26453         # start beyond file end
26454         printf "Using offset > filesize ... "
26455         lseek_test -l 4000000 $file && error "lseek should fail"
26456         printf "Using offset > filesize ... "
26457         lseek_test -d 4000000 $file && error "lseek should fail"
26458
26459         printf "Done\n\n"
26460 }
26461
26462 test_430a() {
26463         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
26464                 skip "MDT does not support SEEK_HOLE"
26465
26466         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26467                 skip "OST does not support SEEK_HOLE"
26468
26469         local file=$DIR/$tdir/$tfile
26470
26471         mkdir -p $DIR/$tdir
26472
26473         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
26474         # OST stripe #1 will have continuous data at [1M, 3M)
26475         # OST stripe #2 is empty
26476         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
26477         lseek_test_430 $file
26478         rm $file
26479         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
26480         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
26481         lseek_test_430 $file
26482         rm $file
26483         $LFS setstripe -c2 -S 512K $file
26484         echo "Two stripes, stripe size 512K"
26485         lseek_test_430 $file
26486         rm $file
26487         # FLR with stale mirror
26488         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
26489                        -N -c2 -S 1M $file
26490         echo "Mirrored file:"
26491         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
26492         echo "Plain 2 stripes 1M"
26493         lseek_test_430 $file
26494         rm $file
26495 }
26496 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
26497
26498 test_430b() {
26499         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26500                 skip "OST does not support SEEK_HOLE"
26501
26502         local offset
26503         local file=$DIR/$tdir/$tfile
26504
26505         mkdir -p $DIR/$tdir
26506         # Empty layout lseek should fail
26507         $MCREATE $file
26508         # seek from 0
26509         printf "Seeking hole from 0 ... "
26510         lseek_test -l 0 $file && error "lseek should fail"
26511         printf "Seeking data from 0 ... "
26512         lseek_test -d 0 $file && error "lseek should fail"
26513         rm $file
26514
26515         # 1M-hole file
26516         $LFS setstripe -E 1M -c2 -E eof $file
26517         $TRUNCATE $file 1048576
26518         printf "Seeking hole from 1000000 ... "
26519         offset=$(lseek_test -l 1000000 $file)
26520         echo $offset
26521         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26522         printf "Seeking data from 1000000 ... "
26523         lseek_test -d 1000000 $file && error "lseek should fail"
26524         rm $file
26525
26526         # full component followed by non-inited one
26527         $LFS setstripe -E 1M -c2 -E eof $file
26528         dd if=/dev/urandom of=$file bs=1M count=1
26529         printf "Seeking hole from 1000000 ... "
26530         offset=$(lseek_test -l 1000000 $file)
26531         echo $offset
26532         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26533         printf "Seeking hole from 1048576 ... "
26534         lseek_test -l 1048576 $file && error "lseek should fail"
26535         # init second component and truncate back
26536         echo "123" >> $file
26537         $TRUNCATE $file 1048576
26538         printf "Seeking hole from 1000000 ... "
26539         offset=$(lseek_test -l 1000000 $file)
26540         echo $offset
26541         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26542         printf "Seeking hole from 1048576 ... "
26543         lseek_test -l 1048576 $file && error "lseek should fail"
26544         # boundary checks for big values
26545         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
26546         offset=$(lseek_test -d 0 $file.10g)
26547         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
26548         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
26549         offset=$(lseek_test -d 0 $file.100g)
26550         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
26551         return 0
26552 }
26553 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
26554
26555 test_430c() {
26556         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26557                 skip "OST does not support SEEK_HOLE"
26558
26559         local file=$DIR/$tdir/$tfile
26560         local start
26561
26562         mkdir -p $DIR/$tdir
26563         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
26564
26565         # cp version 8.33+ prefers lseek over fiemap
26566         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
26567                 start=$SECONDS
26568                 time cp $file /dev/null
26569                 (( SECONDS - start < 5 )) ||
26570                         error "cp: too long runtime $((SECONDS - start))"
26571
26572         fi
26573         # tar version 1.29+ supports SEEK_HOLE/DATA
26574         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
26575                 start=$SECONDS
26576                 time tar cS $file - | cat > /dev/null
26577                 (( SECONDS - start < 5 )) ||
26578                         error "tar: too long runtime $((SECONDS - start))"
26579         fi
26580 }
26581 run_test 430c "lseek: external tools check"
26582
26583 test_431() { # LU-14187
26584         local file=$DIR/$tdir/$tfile
26585
26586         mkdir -p $DIR/$tdir
26587         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
26588         dd if=/dev/urandom of=$file bs=4k count=1
26589         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
26590         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
26591         #define OBD_FAIL_OST_RESTART_IO 0x251
26592         do_facet ost1 "$LCTL set_param fail_loc=0x251"
26593         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
26594         cp $file $file.0
26595         cancel_lru_locks
26596         sync_all_data
26597         echo 3 > /proc/sys/vm/drop_caches
26598         diff  $file $file.0 || error "data diff"
26599 }
26600 run_test 431 "Restart transaction for IO"
26601
26602 cleanup_test_432() {
26603         do_facet mgs $LCTL nodemap_activate 0
26604         wait_nm_sync active
26605 }
26606
26607 test_432() {
26608         local tmpdir=$TMP/dir432
26609
26610         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
26611                 skip "Need MDS version at least 2.14.52"
26612
26613         stack_trap cleanup_test_432 EXIT
26614         mkdir $DIR/$tdir
26615         mkdir $tmpdir
26616
26617         do_facet mgs $LCTL nodemap_activate 1
26618         wait_nm_sync active
26619         do_facet mgs $LCTL nodemap_modify --name default \
26620                 --property admin --value 1
26621         do_facet mgs $LCTL nodemap_modify --name default \
26622                 --property trusted --value 1
26623         cancel_lru_locks mdc
26624         wait_nm_sync default admin_nodemap
26625         wait_nm_sync default trusted_nodemap
26626
26627         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
26628                grep -ci "Operation not permitted") -ne 0 ]; then
26629                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
26630         fi
26631 }
26632 run_test 432 "mv dir from outside Lustre"
26633
26634 prep_801() {
26635         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26636         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26637                 skip "Need server version at least 2.9.55"
26638
26639         start_full_debug_logging
26640 }
26641
26642 post_801() {
26643         stop_full_debug_logging
26644 }
26645
26646 barrier_stat() {
26647         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26648                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26649                            awk '/The barrier for/ { print $7 }')
26650                 echo $st
26651         else
26652                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
26653                 echo \'$st\'
26654         fi
26655 }
26656
26657 barrier_expired() {
26658         local expired
26659
26660         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26661                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26662                           awk '/will be expired/ { print $7 }')
26663         else
26664                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
26665         fi
26666
26667         echo $expired
26668 }
26669
26670 test_801a() {
26671         prep_801
26672
26673         echo "Start barrier_freeze at: $(date)"
26674         #define OBD_FAIL_BARRIER_DELAY          0x2202
26675         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26676         # Do not reduce barrier time - See LU-11873
26677         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
26678
26679         sleep 2
26680         local b_status=$(barrier_stat)
26681         echo "Got barrier status at: $(date)"
26682         [ "$b_status" = "'freezing_p1'" ] ||
26683                 error "(1) unexpected barrier status $b_status"
26684
26685         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26686         wait
26687         b_status=$(barrier_stat)
26688         [ "$b_status" = "'frozen'" ] ||
26689                 error "(2) unexpected barrier status $b_status"
26690
26691         local expired=$(barrier_expired)
26692         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
26693         sleep $((expired + 3))
26694
26695         b_status=$(barrier_stat)
26696         [ "$b_status" = "'expired'" ] ||
26697                 error "(3) unexpected barrier status $b_status"
26698
26699         # Do not reduce barrier time - See LU-11873
26700         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
26701                 error "(4) fail to freeze barrier"
26702
26703         b_status=$(barrier_stat)
26704         [ "$b_status" = "'frozen'" ] ||
26705                 error "(5) unexpected barrier status $b_status"
26706
26707         echo "Start barrier_thaw at: $(date)"
26708         #define OBD_FAIL_BARRIER_DELAY          0x2202
26709         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26710         do_facet mgs $LCTL barrier_thaw $FSNAME &
26711
26712         sleep 2
26713         b_status=$(barrier_stat)
26714         echo "Got barrier status at: $(date)"
26715         [ "$b_status" = "'thawing'" ] ||
26716                 error "(6) unexpected barrier status $b_status"
26717
26718         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26719         wait
26720         b_status=$(barrier_stat)
26721         [ "$b_status" = "'thawed'" ] ||
26722                 error "(7) unexpected barrier status $b_status"
26723
26724         #define OBD_FAIL_BARRIER_FAILURE        0x2203
26725         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
26726         do_facet mgs $LCTL barrier_freeze $FSNAME
26727
26728         b_status=$(barrier_stat)
26729         [ "$b_status" = "'failed'" ] ||
26730                 error "(8) unexpected barrier status $b_status"
26731
26732         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
26733         do_facet mgs $LCTL barrier_thaw $FSNAME
26734
26735         post_801
26736 }
26737 run_test 801a "write barrier user interfaces and stat machine"
26738
26739 test_801b() {
26740         prep_801
26741
26742         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26743         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
26744         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
26745         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
26746         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
26747
26748         cancel_lru_locks mdc
26749
26750         # 180 seconds should be long enough
26751         do_facet mgs $LCTL barrier_freeze $FSNAME 180
26752
26753         local b_status=$(barrier_stat)
26754         [ "$b_status" = "'frozen'" ] ||
26755                 error "(6) unexpected barrier status $b_status"
26756
26757         mkdir $DIR/$tdir/d0/d10 &
26758         mkdir_pid=$!
26759
26760         touch $DIR/$tdir/d1/f13 &
26761         touch_pid=$!
26762
26763         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
26764         ln_pid=$!
26765
26766         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
26767         mv_pid=$!
26768
26769         rm -f $DIR/$tdir/d4/f12 &
26770         rm_pid=$!
26771
26772         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
26773
26774         # To guarantee taht the 'stat' is not blocked
26775         b_status=$(barrier_stat)
26776         [ "$b_status" = "'frozen'" ] ||
26777                 error "(8) unexpected barrier status $b_status"
26778
26779         # let above commands to run at background
26780         sleep 5
26781
26782         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
26783         ps -p $touch_pid || error "(10) touch should be blocked"
26784         ps -p $ln_pid || error "(11) link should be blocked"
26785         ps -p $mv_pid || error "(12) rename should be blocked"
26786         ps -p $rm_pid || error "(13) unlink should be blocked"
26787
26788         b_status=$(barrier_stat)
26789         [ "$b_status" = "'frozen'" ] ||
26790                 error "(14) unexpected barrier status $b_status"
26791
26792         do_facet mgs $LCTL barrier_thaw $FSNAME
26793         b_status=$(barrier_stat)
26794         [ "$b_status" = "'thawed'" ] ||
26795                 error "(15) unexpected barrier status $b_status"
26796
26797         wait $mkdir_pid || error "(16) mkdir should succeed"
26798         wait $touch_pid || error "(17) touch should succeed"
26799         wait $ln_pid || error "(18) link should succeed"
26800         wait $mv_pid || error "(19) rename should succeed"
26801         wait $rm_pid || error "(20) unlink should succeed"
26802
26803         post_801
26804 }
26805 run_test 801b "modification will be blocked by write barrier"
26806
26807 test_801c() {
26808         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26809
26810         prep_801
26811
26812         stop mds2 || error "(1) Fail to stop mds2"
26813
26814         do_facet mgs $LCTL barrier_freeze $FSNAME 30
26815
26816         local b_status=$(barrier_stat)
26817         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
26818                 do_facet mgs $LCTL barrier_thaw $FSNAME
26819                 error "(2) unexpected barrier status $b_status"
26820         }
26821
26822         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26823                 error "(3) Fail to rescan barrier bitmap"
26824
26825         # Do not reduce barrier time - See LU-11873
26826         do_facet mgs $LCTL barrier_freeze $FSNAME 20
26827
26828         b_status=$(barrier_stat)
26829         [ "$b_status" = "'frozen'" ] ||
26830                 error "(4) unexpected barrier status $b_status"
26831
26832         do_facet mgs $LCTL barrier_thaw $FSNAME
26833         b_status=$(barrier_stat)
26834         [ "$b_status" = "'thawed'" ] ||
26835                 error "(5) unexpected barrier status $b_status"
26836
26837         local devname=$(mdsdevname 2)
26838
26839         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
26840
26841         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26842                 error "(7) Fail to rescan barrier bitmap"
26843
26844         post_801
26845 }
26846 run_test 801c "rescan barrier bitmap"
26847
26848 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
26849 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
26850 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
26851 saved_MOUNT_OPTS=$MOUNT_OPTS
26852
26853 cleanup_802a() {
26854         trap 0
26855
26856         stopall
26857         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
26858         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
26859         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
26860         MOUNT_OPTS=$saved_MOUNT_OPTS
26861         setupall
26862 }
26863
26864 test_802a() {
26865         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
26866         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26867         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26868                 skip "Need server version at least 2.9.55"
26869
26870         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
26871
26872         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26873
26874         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26875                 error "(2) Fail to copy"
26876
26877         trap cleanup_802a EXIT
26878
26879         # sync by force before remount as readonly
26880         sync; sync_all_data; sleep 3; sync_all_data
26881
26882         stopall
26883
26884         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
26885         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
26886         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
26887
26888         echo "Mount the server as read only"
26889         setupall server_only || error "(3) Fail to start servers"
26890
26891         echo "Mount client without ro should fail"
26892         mount_client $MOUNT &&
26893                 error "(4) Mount client without 'ro' should fail"
26894
26895         echo "Mount client with ro should succeed"
26896         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
26897         mount_client $MOUNT ||
26898                 error "(5) Mount client with 'ro' should succeed"
26899
26900         echo "Modify should be refused"
26901         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26902
26903         echo "Read should be allowed"
26904         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26905                 error "(7) Read should succeed under ro mode"
26906
26907         cleanup_802a
26908 }
26909 run_test 802a "simulate readonly device"
26910
26911 test_802b() {
26912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26913         remote_mds_nodsh && skip "remote MDS with nodsh"
26914
26915         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
26916                 skip "readonly option not available"
26917
26918         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
26919
26920         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26921                 error "(2) Fail to copy"
26922
26923         # write back all cached data before setting MDT to readonly
26924         cancel_lru_locks
26925         sync_all_data
26926
26927         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
26928         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
26929
26930         echo "Modify should be refused"
26931         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26932
26933         echo "Read should be allowed"
26934         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26935                 error "(7) Read should succeed under ro mode"
26936
26937         # disable readonly
26938         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
26939 }
26940 run_test 802b "be able to set MDTs to readonly"
26941
26942 test_803a() {
26943         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26944         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26945                 skip "MDS needs to be newer than 2.10.54"
26946
26947         mkdir_on_mdt0 $DIR/$tdir
26948         # Create some objects on all MDTs to trigger related logs objects
26949         for idx in $(seq $MDSCOUNT); do
26950                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
26951                         $DIR/$tdir/dir${idx} ||
26952                         error "Fail to create $DIR/$tdir/dir${idx}"
26953         done
26954
26955         sync; sleep 3
26956         wait_delete_completed # ensure old test cleanups are finished
26957         echo "before create:"
26958         $LFS df -i $MOUNT
26959         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26960
26961         for i in {1..10}; do
26962                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
26963                         error "Fail to create $DIR/$tdir/foo$i"
26964         done
26965
26966         sync; sleep 3
26967         echo "after create:"
26968         $LFS df -i $MOUNT
26969         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26970
26971         # allow for an llog to be cleaned up during the test
26972         [ $after_used -ge $((before_used + 10 - 1)) ] ||
26973                 error "before ($before_used) + 10 > after ($after_used)"
26974
26975         for i in {1..10}; do
26976                 rm -rf $DIR/$tdir/foo$i ||
26977                         error "Fail to remove $DIR/$tdir/foo$i"
26978         done
26979
26980         sleep 3 # avoid MDT return cached statfs
26981         wait_delete_completed
26982         echo "after unlink:"
26983         $LFS df -i $MOUNT
26984         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26985
26986         # allow for an llog to be created during the test
26987         [ $after_used -le $((before_used + 1)) ] ||
26988                 error "after ($after_used) > before ($before_used) + 1"
26989 }
26990 run_test 803a "verify agent object for remote object"
26991
26992 test_803b() {
26993         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26994         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
26995                 skip "MDS needs to be newer than 2.13.56"
26996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26997
26998         for i in $(seq 0 $((MDSCOUNT - 1))); do
26999                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27000         done
27001
27002         local before=0
27003         local after=0
27004
27005         local tmp
27006
27007         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27008         for i in $(seq 0 $((MDSCOUNT - 1))); do
27009                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27010                         awk '/getattr/ { print $2 }')
27011                 before=$((before + tmp))
27012         done
27013         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27014         for i in $(seq 0 $((MDSCOUNT - 1))); do
27015                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27016                         awk '/getattr/ { print $2 }')
27017                 after=$((after + tmp))
27018         done
27019
27020         [ $before -eq $after ] || error "getattr count $before != $after"
27021 }
27022 run_test 803b "remote object can getattr from cache"
27023
27024 test_804() {
27025         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27026         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27027                 skip "MDS needs to be newer than 2.10.54"
27028         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27029
27030         mkdir -p $DIR/$tdir
27031         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27032                 error "Fail to create $DIR/$tdir/dir0"
27033
27034         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27035         local dev=$(mdsdevname 2)
27036
27037         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27038                 grep ${fid} || error "NOT found agent entry for dir0"
27039
27040         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27041                 error "Fail to create $DIR/$tdir/dir1"
27042
27043         touch $DIR/$tdir/dir1/foo0 ||
27044                 error "Fail to create $DIR/$tdir/dir1/foo0"
27045         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27046         local rc=0
27047
27048         for idx in $(seq $MDSCOUNT); do
27049                 dev=$(mdsdevname $idx)
27050                 do_facet mds${idx} \
27051                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27052                         grep ${fid} && rc=$idx
27053         done
27054
27055         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27056                 error "Fail to rename foo0 to foo1"
27057         if [ $rc -eq 0 ]; then
27058                 for idx in $(seq $MDSCOUNT); do
27059                         dev=$(mdsdevname $idx)
27060                         do_facet mds${idx} \
27061                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27062                         grep ${fid} && rc=$idx
27063                 done
27064         fi
27065
27066         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27067                 error "Fail to rename foo1 to foo2"
27068         if [ $rc -eq 0 ]; then
27069                 for idx in $(seq $MDSCOUNT); do
27070                         dev=$(mdsdevname $idx)
27071                         do_facet mds${idx} \
27072                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27073                         grep ${fid} && rc=$idx
27074                 done
27075         fi
27076
27077         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27078
27079         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27080                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27081         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27082                 error "Fail to rename foo2 to foo0"
27083         unlink $DIR/$tdir/dir1/foo0 ||
27084                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27085         rm -rf $DIR/$tdir/dir0 ||
27086                 error "Fail to rm $DIR/$tdir/dir0"
27087
27088         for idx in $(seq $MDSCOUNT); do
27089                 dev=$(mdsdevname $idx)
27090                 rc=0
27091
27092                 stop mds${idx}
27093                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27094                         rc=$?
27095                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27096                         error "mount mds$idx failed"
27097                 df $MOUNT > /dev/null 2>&1
27098
27099                 # e2fsck should not return error
27100                 [ $rc -eq 0 ] ||
27101                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27102         done
27103 }
27104 run_test 804 "verify agent entry for remote entry"
27105
27106 cleanup_805() {
27107         do_facet $SINGLEMDS zfs set quota=$old $fsset
27108         unlinkmany $DIR/$tdir/f- 1000000
27109         trap 0
27110 }
27111
27112 test_805() {
27113         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
27114         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
27115         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
27116                 skip "netfree not implemented before 0.7"
27117         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
27118                 skip "Need MDS version at least 2.10.57"
27119
27120         local fsset
27121         local freekb
27122         local usedkb
27123         local old
27124         local quota
27125         local pref="osd-zfs.$FSNAME-MDT0000."
27126
27127         # limit available space on MDS dataset to meet nospace issue
27128         # quickly. then ZFS 0.7.2 can use reserved space if asked
27129         # properly (using netfree flag in osd_declare_destroy()
27130         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
27131         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
27132                 gawk '{print $3}')
27133         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
27134         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
27135         let "usedkb=usedkb-freekb"
27136         let "freekb=freekb/2"
27137         if let "freekb > 5000"; then
27138                 let "freekb=5000"
27139         fi
27140         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
27141         trap cleanup_805 EXIT
27142         mkdir_on_mdt0 $DIR/$tdir
27143         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
27144                 error "Can't set PFL layout"
27145         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27146         rm -rf $DIR/$tdir || error "not able to remove"
27147         do_facet $SINGLEMDS zfs set quota=$old $fsset
27148         trap 0
27149 }
27150 run_test 805 "ZFS can remove from full fs"
27151
27152 # Size-on-MDS test
27153 check_lsom_data()
27154 {
27155         local file=$1
27156         local expect=$(stat -c %s $file)
27157
27158         check_lsom_size $1 $expect
27159
27160         local blocks=$($LFS getsom -b $file)
27161         expect=$(stat -c %b $file)
27162         [[ $blocks == $expect ]] ||
27163                 error "$file expected blocks: $expect, got: $blocks"
27164 }
27165
27166 check_lsom_size()
27167 {
27168         local size
27169         local expect=$2
27170
27171         cancel_lru_locks mdc
27172
27173         size=$($LFS getsom -s $1)
27174         [[ $size == $expect ]] ||
27175                 error "$file expected size: $expect, got: $size"
27176 }
27177
27178 test_806() {
27179         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27180                 skip "Need MDS version at least 2.11.52"
27181
27182         local bs=1048576
27183
27184         touch $DIR/$tfile || error "touch $tfile failed"
27185
27186         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27187         save_lustre_params client "llite.*.xattr_cache" > $save
27188         lctl set_param llite.*.xattr_cache=0
27189         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27190
27191         # single-threaded write
27192         echo "Test SOM for single-threaded write"
27193         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27194                 error "write $tfile failed"
27195         check_lsom_size $DIR/$tfile $bs
27196
27197         local num=32
27198         local size=$(($num * $bs))
27199         local offset=0
27200         local i
27201
27202         echo "Test SOM for single client multi-threaded($num) write"
27203         $TRUNCATE $DIR/$tfile 0
27204         for ((i = 0; i < $num; i++)); do
27205                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27206                 local pids[$i]=$!
27207                 offset=$((offset + $bs))
27208         done
27209         for (( i=0; i < $num; i++ )); do
27210                 wait ${pids[$i]}
27211         done
27212         check_lsom_size $DIR/$tfile $size
27213
27214         $TRUNCATE $DIR/$tfile 0
27215         for ((i = 0; i < $num; i++)); do
27216                 offset=$((offset - $bs))
27217                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27218                 local pids[$i]=$!
27219         done
27220         for (( i=0; i < $num; i++ )); do
27221                 wait ${pids[$i]}
27222         done
27223         check_lsom_size $DIR/$tfile $size
27224
27225         # multi-client writes
27226         num=$(get_node_count ${CLIENTS//,/ })
27227         size=$(($num * $bs))
27228         offset=0
27229         i=0
27230
27231         echo "Test SOM for multi-client ($num) writes"
27232         $TRUNCATE $DIR/$tfile 0
27233         for client in ${CLIENTS//,/ }; do
27234                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27235                 local pids[$i]=$!
27236                 i=$((i + 1))
27237                 offset=$((offset + $bs))
27238         done
27239         for (( i=0; i < $num; i++ )); do
27240                 wait ${pids[$i]}
27241         done
27242         check_lsom_size $DIR/$tfile $offset
27243
27244         i=0
27245         $TRUNCATE $DIR/$tfile 0
27246         for client in ${CLIENTS//,/ }; do
27247                 offset=$((offset - $bs))
27248                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27249                 local pids[$i]=$!
27250                 i=$((i + 1))
27251         done
27252         for (( i=0; i < $num; i++ )); do
27253                 wait ${pids[$i]}
27254         done
27255         check_lsom_size $DIR/$tfile $size
27256
27257         # verify truncate
27258         echo "Test SOM for truncate"
27259         $TRUNCATE $DIR/$tfile 1048576
27260         check_lsom_size $DIR/$tfile 1048576
27261         $TRUNCATE $DIR/$tfile 1234
27262         check_lsom_size $DIR/$tfile 1234
27263
27264         # verify SOM blocks count
27265         echo "Verify SOM block count"
27266         $TRUNCATE $DIR/$tfile 0
27267         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27268                 error "failed to write file $tfile"
27269         check_lsom_data $DIR/$tfile
27270 }
27271 run_test 806 "Verify Lazy Size on MDS"
27272
27273 test_807() {
27274         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27275         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27276                 skip "Need MDS version at least 2.11.52"
27277
27278         # Registration step
27279         changelog_register || error "changelog_register failed"
27280         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27281         changelog_users $SINGLEMDS | grep -q $cl_user ||
27282                 error "User $cl_user not found in changelog_users"
27283
27284         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27285         save_lustre_params client "llite.*.xattr_cache" > $save
27286         lctl set_param llite.*.xattr_cache=0
27287         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27288
27289         rm -rf $DIR/$tdir || error "rm $tdir failed"
27290         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27291         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27292         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27293         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27294                 error "truncate $tdir/trunc failed"
27295
27296         local bs=1048576
27297         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27298                 error "write $tfile failed"
27299
27300         # multi-client wirtes
27301         local num=$(get_node_count ${CLIENTS//,/ })
27302         local offset=0
27303         local i=0
27304
27305         echo "Test SOM for multi-client ($num) writes"
27306         touch $DIR/$tfile || error "touch $tfile failed"
27307         $TRUNCATE $DIR/$tfile 0
27308         for client in ${CLIENTS//,/ }; do
27309                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27310                 local pids[$i]=$!
27311                 i=$((i + 1))
27312                 offset=$((offset + $bs))
27313         done
27314         for (( i=0; i < $num; i++ )); do
27315                 wait ${pids[$i]}
27316         done
27317
27318         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27319         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27320         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27321         check_lsom_data $DIR/$tdir/trunc
27322         check_lsom_data $DIR/$tdir/single_dd
27323         check_lsom_data $DIR/$tfile
27324
27325         rm -rf $DIR/$tdir
27326         # Deregistration step
27327         changelog_deregister || error "changelog_deregister failed"
27328 }
27329 run_test 807 "verify LSOM syncing tool"
27330
27331 check_som_nologged()
27332 {
27333         local lines=$($LFS changelog $FSNAME-MDT0000 |
27334                 grep 'x=trusted.som' | wc -l)
27335         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27336 }
27337
27338 test_808() {
27339         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27340                 skip "Need MDS version at least 2.11.55"
27341
27342         # Registration step
27343         changelog_register || error "changelog_register failed"
27344
27345         touch $DIR/$tfile || error "touch $tfile failed"
27346         check_som_nologged
27347
27348         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27349                 error "write $tfile failed"
27350         check_som_nologged
27351
27352         $TRUNCATE $DIR/$tfile 1234
27353         check_som_nologged
27354
27355         $TRUNCATE $DIR/$tfile 1048576
27356         check_som_nologged
27357
27358         # Deregistration step
27359         changelog_deregister || error "changelog_deregister failed"
27360 }
27361 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27362
27363 check_som_nodata()
27364 {
27365         $LFS getsom $1
27366         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27367 }
27368
27369 test_809() {
27370         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27371                 skip "Need MDS version at least 2.11.56"
27372
27373         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27374                 error "failed to create DoM-only file $DIR/$tfile"
27375         touch $DIR/$tfile || error "touch $tfile failed"
27376         check_som_nodata $DIR/$tfile
27377
27378         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27379                 error "write $tfile failed"
27380         check_som_nodata $DIR/$tfile
27381
27382         $TRUNCATE $DIR/$tfile 1234
27383         check_som_nodata $DIR/$tfile
27384
27385         $TRUNCATE $DIR/$tfile 4097
27386         check_som_nodata $DIR/$file
27387 }
27388 run_test 809 "Verify no SOM xattr store for DoM-only files"
27389
27390 test_810() {
27391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27392         $GSS && skip_env "could not run with gss"
27393         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27394                 skip "OST < 2.12.58 doesn't align checksum"
27395
27396         set_checksums 1
27397         stack_trap "set_checksums $ORIG_CSUM" EXIT
27398         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27399
27400         local csum
27401         local before
27402         local after
27403         for csum in $CKSUM_TYPES; do
27404                 #define OBD_FAIL_OSC_NO_GRANT   0x411
27405                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
27406                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
27407                         eval set -- $i
27408                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
27409                         before=$(md5sum $DIR/$tfile)
27410                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
27411                         after=$(md5sum $DIR/$tfile)
27412                         [ "$before" == "$after" ] ||
27413                                 error "$csum: $before != $after bs=$1 seek=$2"
27414                 done
27415         done
27416 }
27417 run_test 810 "partial page writes on ZFS (LU-11663)"
27418
27419 test_812a() {
27420         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27421                 skip "OST < 2.12.51 doesn't support this fail_loc"
27422
27423         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27424         # ensure ost1 is connected
27425         stat $DIR/$tfile >/dev/null || error "can't stat"
27426         wait_osc_import_state client ost1 FULL
27427         # no locks, no reqs to let the connection idle
27428         cancel_lru_locks osc
27429
27430         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27431 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27432         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27433         wait_osc_import_state client ost1 CONNECTING
27434         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27435
27436         stat $DIR/$tfile >/dev/null || error "can't stat file"
27437 }
27438 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
27439
27440 test_812b() { # LU-12378
27441         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27442                 skip "OST < 2.12.51 doesn't support this fail_loc"
27443
27444         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
27445         # ensure ost1 is connected
27446         stat $DIR/$tfile >/dev/null || error "can't stat"
27447         wait_osc_import_state client ost1 FULL
27448         # no locks, no reqs to let the connection idle
27449         cancel_lru_locks osc
27450
27451         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27452 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27453         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27454         wait_osc_import_state client ost1 CONNECTING
27455         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27456
27457         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
27458         wait_osc_import_state client ost1 IDLE
27459 }
27460 run_test 812b "do not drop no resend request for idle connect"
27461
27462 test_812c() {
27463         local old
27464
27465         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
27466
27467         $LFS setstripe -c 1 -o 0 $DIR/$tfile
27468         $LFS getstripe $DIR/$tfile
27469         $LCTL set_param osc.*.idle_timeout=10
27470         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
27471         # ensure ost1 is connected
27472         stat $DIR/$tfile >/dev/null || error "can't stat"
27473         wait_osc_import_state client ost1 FULL
27474         # no locks, no reqs to let the connection idle
27475         cancel_lru_locks osc
27476
27477 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
27478         $LCTL set_param fail_loc=0x80000533
27479         sleep 15
27480         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
27481 }
27482 run_test 812c "idle import vs lock enqueue race"
27483
27484 test_813() {
27485         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
27486         [ -z "$file_heat_sav" ] && skip "no file heat support"
27487
27488         local readsample
27489         local writesample
27490         local readbyte
27491         local writebyte
27492         local readsample1
27493         local writesample1
27494         local readbyte1
27495         local writebyte1
27496
27497         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
27498         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
27499
27500         $LCTL set_param -n llite.*.file_heat=1
27501         echo "Turn on file heat"
27502         echo "Period second: $period_second, Decay percentage: $decay_pct"
27503
27504         echo "QQQQ" > $DIR/$tfile
27505         echo "QQQQ" > $DIR/$tfile
27506         echo "QQQQ" > $DIR/$tfile
27507         cat $DIR/$tfile > /dev/null
27508         cat $DIR/$tfile > /dev/null
27509         cat $DIR/$tfile > /dev/null
27510         cat $DIR/$tfile > /dev/null
27511
27512         local out=$($LFS heat_get $DIR/$tfile)
27513
27514         $LFS heat_get $DIR/$tfile
27515         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27516         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27517         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27518         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27519
27520         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
27521         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
27522         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
27523         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
27524
27525         sleep $((period_second + 3))
27526         echo "Sleep $((period_second + 3)) seconds..."
27527         # The recursion formula to calculate the heat of the file f is as
27528         # follow:
27529         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
27530         # Where Hi is the heat value in the period between time points i*I and
27531         # (i+1)*I; Ci is the access count in the period; the symbol P refers
27532         # to the weight of Ci.
27533         out=$($LFS heat_get $DIR/$tfile)
27534         $LFS heat_get $DIR/$tfile
27535         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27536         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27537         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27538         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27539
27540         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
27541                 error "read sample ($readsample) is wrong"
27542         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
27543                 error "write sample ($writesample) is wrong"
27544         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
27545                 error "read bytes ($readbyte) is wrong"
27546         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
27547                 error "write bytes ($writebyte) is wrong"
27548
27549         echo "QQQQ" > $DIR/$tfile
27550         echo "QQQQ" > $DIR/$tfile
27551         echo "QQQQ" > $DIR/$tfile
27552         cat $DIR/$tfile > /dev/null
27553         cat $DIR/$tfile > /dev/null
27554         cat $DIR/$tfile > /dev/null
27555         cat $DIR/$tfile > /dev/null
27556
27557         sleep $((period_second + 3))
27558         echo "Sleep $((period_second + 3)) seconds..."
27559
27560         out=$($LFS heat_get $DIR/$tfile)
27561         $LFS heat_get $DIR/$tfile
27562         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27563         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27564         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27565         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27566
27567         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
27568                 4 * $decay_pct) / 100") -eq 1 ] ||
27569                 error "read sample ($readsample1) is wrong"
27570         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
27571                 3 * $decay_pct) / 100") -eq 1 ] ||
27572                 error "write sample ($writesample1) is wrong"
27573         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
27574                 20 * $decay_pct) / 100") -eq 1 ] ||
27575                 error "read bytes ($readbyte1) is wrong"
27576         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
27577                 15 * $decay_pct) / 100") -eq 1 ] ||
27578                 error "write bytes ($writebyte1) is wrong"
27579
27580         echo "Turn off file heat for the file $DIR/$tfile"
27581         $LFS heat_set -o $DIR/$tfile
27582
27583         echo "QQQQ" > $DIR/$tfile
27584         echo "QQQQ" > $DIR/$tfile
27585         echo "QQQQ" > $DIR/$tfile
27586         cat $DIR/$tfile > /dev/null
27587         cat $DIR/$tfile > /dev/null
27588         cat $DIR/$tfile > /dev/null
27589         cat $DIR/$tfile > /dev/null
27590
27591         out=$($LFS heat_get $DIR/$tfile)
27592         $LFS heat_get $DIR/$tfile
27593         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27594         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27595         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27596         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27597
27598         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27599         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27600         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27601         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27602
27603         echo "Trun on file heat for the file $DIR/$tfile"
27604         $LFS heat_set -O $DIR/$tfile
27605
27606         echo "QQQQ" > $DIR/$tfile
27607         echo "QQQQ" > $DIR/$tfile
27608         echo "QQQQ" > $DIR/$tfile
27609         cat $DIR/$tfile > /dev/null
27610         cat $DIR/$tfile > /dev/null
27611         cat $DIR/$tfile > /dev/null
27612         cat $DIR/$tfile > /dev/null
27613
27614         out=$($LFS heat_get $DIR/$tfile)
27615         $LFS heat_get $DIR/$tfile
27616         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27617         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27618         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27619         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27620
27621         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
27622         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
27623         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
27624         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
27625
27626         $LFS heat_set -c $DIR/$tfile
27627         $LCTL set_param -n llite.*.file_heat=0
27628         echo "Turn off file heat support for the Lustre filesystem"
27629
27630         echo "QQQQ" > $DIR/$tfile
27631         echo "QQQQ" > $DIR/$tfile
27632         echo "QQQQ" > $DIR/$tfile
27633         cat $DIR/$tfile > /dev/null
27634         cat $DIR/$tfile > /dev/null
27635         cat $DIR/$tfile > /dev/null
27636         cat $DIR/$tfile > /dev/null
27637
27638         out=$($LFS heat_get $DIR/$tfile)
27639         $LFS heat_get $DIR/$tfile
27640         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27641         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27642         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27643         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27644
27645         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27646         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27647         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27648         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27649
27650         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
27651         rm -f $DIR/$tfile
27652 }
27653 run_test 813 "File heat verfication"
27654
27655 test_814()
27656 {
27657         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
27658         echo -n y >> $DIR/$tfile
27659         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
27660         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
27661 }
27662 run_test 814 "sparse cp works as expected (LU-12361)"
27663
27664 test_815()
27665 {
27666         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
27667         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
27668 }
27669 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
27670
27671 test_816() {
27672         local ost1_imp=$(get_osc_import_name client ost1)
27673         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27674                          cut -d'.' -f2)
27675
27676         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27677         # ensure ost1 is connected
27678
27679         stat $DIR/$tfile >/dev/null || error "can't stat"
27680         wait_osc_import_state client ost1 FULL
27681         # no locks, no reqs to let the connection idle
27682         cancel_lru_locks osc
27683         lru_resize_disable osc
27684         local before
27685         local now
27686         before=$($LCTL get_param -n \
27687                  ldlm.namespaces.$imp_name.lru_size)
27688
27689         wait_osc_import_state client ost1 IDLE
27690         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
27691         now=$($LCTL get_param -n \
27692               ldlm.namespaces.$imp_name.lru_size)
27693         [ $before == $now ] || error "lru_size changed $before != $now"
27694 }
27695 run_test 816 "do not reset lru_resize on idle reconnect"
27696
27697 cleanup_817() {
27698         umount $tmpdir
27699         exportfs -u localhost:$DIR/nfsexp
27700         rm -rf $DIR/nfsexp
27701 }
27702
27703 test_817() {
27704         systemctl restart nfs-server.service || skip "failed to restart nfsd"
27705
27706         mkdir -p $DIR/nfsexp
27707         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
27708                 error "failed to export nfs"
27709
27710         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
27711         stack_trap cleanup_817 EXIT
27712
27713         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
27714                 error "failed to mount nfs to $tmpdir"
27715
27716         cp /bin/true $tmpdir
27717         $DIR/nfsexp/true || error "failed to execute 'true' command"
27718 }
27719 run_test 817 "nfsd won't cache write lock for exec file"
27720
27721 test_818() {
27722         test_mkdir -i0 -c1 $DIR/$tdir
27723         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
27724         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
27725         stop $SINGLEMDS
27726
27727         # restore osp-syn threads
27728         stack_trap "fail $SINGLEMDS"
27729
27730         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
27731         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
27732         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
27733                 error "start $SINGLEMDS failed"
27734         rm -rf $DIR/$tdir
27735
27736         local testid=$(echo $TESTNAME | tr '_' ' ')
27737
27738         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
27739                 grep "run LFSCK" || error "run LFSCK is not suggested"
27740 }
27741 run_test 818 "unlink with failed llog"
27742
27743 test_819a() {
27744         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27745         cancel_lru_locks osc
27746         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27747         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27748         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
27749         rm -f $TDIR/$tfile
27750 }
27751 run_test 819a "too big niobuf in read"
27752
27753 test_819b() {
27754         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27755         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27756         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27757         cancel_lru_locks osc
27758         sleep 1
27759         rm -f $TDIR/$tfile
27760 }
27761 run_test 819b "too big niobuf in write"
27762
27763
27764 function test_820_start_ost() {
27765         sleep 5
27766
27767         for num in $(seq $OSTCOUNT); do
27768                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
27769         done
27770 }
27771
27772 test_820() {
27773         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27774
27775         mkdir $DIR/$tdir
27776         umount_client $MOUNT || error "umount failed"
27777         for num in $(seq $OSTCOUNT); do
27778                 stop ost$num
27779         done
27780
27781         # mount client with no active OSTs
27782         # so that the client can't initialize max LOV EA size
27783         # from OSC notifications
27784         mount_client $MOUNT || error "mount failed"
27785         # delay OST starting to keep this 0 max EA size for a while
27786         test_820_start_ost &
27787
27788         # create a directory on MDS2
27789         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
27790                 error "Failed to create directory"
27791         # open intent should update default EA size
27792         # see mdc_update_max_ea_from_body()
27793         # notice this is the very first RPC to MDS2
27794         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
27795         ret=$?
27796         echo $out
27797         # With SSK, this situation can lead to -EPERM being returned.
27798         # In that case, simply retry.
27799         if [ $ret -ne 0 ] && $SHARED_KEY; then
27800                 if echo "$out" | grep -q "not permitted"; then
27801                         cp /etc/services $DIR/$tdir/mds2
27802                         ret=$?
27803                 fi
27804         fi
27805         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
27806 }
27807 run_test 820 "update max EA from open intent"
27808
27809 test_822() {
27810         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27811
27812         save_lustre_params mds1 \
27813                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27814         do_facet $SINGLEMDS "$LCTL set_param -n \
27815                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
27816         do_facet $SINGLEMDS "$LCTL set_param -n \
27817                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
27818
27819         # wait for statfs update to clear OS_STATFS_NOPRECREATE
27820         local maxage=$(do_facet mds1 $LCTL get_param -n \
27821                        osp.$FSNAME-OST0000*MDT0000.maxage)
27822         sleep $((maxage + 1))
27823
27824         #define OBD_FAIL_NET_ERROR_RPC          0x532
27825         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
27826
27827         stack_trap "restore_lustre_params < $p; rm $p"
27828
27829         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
27830                       osp.$FSNAME-OST0000*MDT0000.create_count")
27831         for i in $(seq 1 $count); do
27832                 touch $DIR/$tfile.${i} || error "touch failed"
27833         done
27834 }
27835 run_test 822 "test precreate failure"
27836
27837 test_823() {
27838         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27839         local OST_MAX_PRECREATE=20000
27840
27841         save_lustre_params mds1 \
27842                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27843         do_facet $SINGLEMDS "$LCTL set_param -n \
27844                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
27845         do_facet $SINGLEMDS "$LCTL set_param -n \
27846                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
27847
27848         stack_trap "restore_lustre_params < $p; rm $p"
27849
27850         do_facet $SINGLEMDS "$LCTL set_param -n \
27851                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
27852
27853         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27854                       osp.$FSNAME-OST0000*MDT0000.create_count")
27855         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27856                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
27857         local expect_count=$(((($max/2)/256) * 256))
27858
27859         log "setting create_count to 100200:"
27860         log " -result- count: $count with max: $max, expecting: $expect_count"
27861
27862         [[ $count -eq expect_count ]] ||
27863                 error "Create count not set to max precreate."
27864 }
27865 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
27866
27867 test_831() {
27868         local sync_changes=$(do_facet $SINGLEMDS \
27869                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
27870
27871         [ "$sync_changes" -gt 100 ] &&
27872                 skip "Sync changes $sync_changes > 100 already"
27873
27874         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27875
27876         $LFS mkdir -i 0 $DIR/$tdir
27877         $LFS setstripe -c 1 -i 0 $DIR/$tdir
27878
27879         save_lustre_params mds1 \
27880                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
27881         save_lustre_params mds1 \
27882                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
27883
27884         do_facet mds1 "$LCTL set_param -n \
27885                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
27886                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
27887         stack_trap "restore_lustre_params < $p" EXIT
27888
27889         createmany -o $DIR/$tdir/f- 1000
27890         unlinkmany $DIR/$tdir/f- 1000 &
27891         local UNLINK_PID=$!
27892
27893         while sleep 1; do
27894                 sync_changes=$(do_facet mds1 \
27895                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
27896                 # the check in the code is racy, fail the test
27897                 # if the value above the limit by 10.
27898                 [ $sync_changes -gt 110 ] && {
27899                         kill -2 $UNLINK_PID
27900                         wait
27901                         error "osp changes throttling failed, $sync_changes>110"
27902                 }
27903                 kill -0 $UNLINK_PID 2> /dev/null || break
27904         done
27905         wait
27906 }
27907 run_test 831 "throttling unlink/setattr queuing on OSP"
27908
27909 #
27910 # tests that do cleanup/setup should be run at the end
27911 #
27912
27913 test_900() {
27914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27915         local ls
27916
27917         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
27918         $LCTL set_param fail_loc=0x903
27919
27920         cancel_lru_locks MGC
27921
27922         FAIL_ON_ERROR=true cleanup
27923         FAIL_ON_ERROR=true setup
27924 }
27925 run_test 900 "umount should not race with any mgc requeue thread"
27926
27927 # LUS-6253/LU-11185
27928 test_901() {
27929         local oldc
27930         local newc
27931         local olds
27932         local news
27933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27934
27935         # some get_param have a bug to handle dot in param name
27936         cancel_lru_locks MGC
27937         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27938         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27939         umount_client $MOUNT || error "umount failed"
27940         mount_client $MOUNT || error "mount failed"
27941         cancel_lru_locks MGC
27942         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27943         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27944
27945         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
27946         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
27947
27948         return 0
27949 }
27950 run_test 901 "don't leak a mgc lock on client umount"
27951
27952 # LU-13377
27953 test_902() {
27954         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
27955                 skip "client does not have LU-13377 fix"
27956         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
27957         $LCTL set_param fail_loc=0x1415
27958         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27959         cancel_lru_locks osc
27960         rm -f $DIR/$tfile
27961 }
27962 run_test 902 "test short write doesn't hang lustre"
27963
27964 # LU-14711
27965 test_903() {
27966         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
27967         echo "blah" > $DIR/${tfile}-2
27968         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
27969         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
27970         $LCTL set_param fail_loc=0x417 fail_val=20
27971
27972         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
27973         sleep 1 # To start the destroy
27974         wait_destroy_complete 150 || error "Destroy taking too long"
27975         cat $DIR/$tfile > /dev/null || error "Evicted"
27976 }
27977 run_test 903 "Test long page discard does not cause evictions"
27978
27979 test_904() {
27980         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
27981         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
27982                 grep -q project || skip "skip project quota not supported"
27983
27984         local testfile="$DIR/$tdir/$tfile"
27985         local xattr="trusted.projid"
27986         local projid
27987
27988         mkdir -p $DIR/$tdir
27989         touch $testfile
27990         #should be hidden when projid is 0
27991         $LFS project -p 0 $testfile ||
27992                 error "set $testfile project id failed"
27993         getfattr -m - $testfile | grep $xattr &&
27994                 error "do not show trusted.projid with project ID 0"
27995
27996         #still can getxattr explicitly
27997         projid=$(getfattr -n $xattr $testfile |
27998                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
27999         [ $projid == "0" ] ||
28000                 error "projid expected 0 not $projid"
28001
28002         #set the projid via setxattr
28003         setfattr -n $xattr -v "1000" $testfile ||
28004                 error "setattr failed with $?"
28005         projid=($($LFS project $testfile))
28006         [ ${projid[0]} == "1000" ] ||
28007                 error "projid expected 1000 not $projid"
28008
28009         #check the new projid via getxattr
28010         $LFS project -p 1001 $testfile ||
28011                 error "set $testfile project id failed"
28012         projid=$(getfattr -n $xattr $testfile |
28013                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28014         [ $projid == "1001" ] ||
28015                 error "projid expected 1001 not $projid"
28016
28017         #try to set invalid projid
28018         setfattr -n $xattr -v "4294967295" $testfile &&
28019                 error "set invalid projid should fail"
28020
28021         #remove the xattr means setting projid to 0
28022         setfattr -x $xattr $testfile ||
28023                 error "setfattr failed with $?"
28024         projid=($($LFS project $testfile))
28025         [ ${projid[0]} == "0" ] ||
28026                 error "projid expected 0 not $projid"
28027
28028         #should be hidden when parent has inherit flag and same projid
28029         $LFS project -srp 1002 $DIR/$tdir ||
28030                 error "set $tdir project id failed"
28031         getfattr -m - $testfile | grep $xattr &&
28032                 error "do not show trusted.projid with inherit flag"
28033
28034         #still can getxattr explicitly
28035         projid=$(getfattr -n $xattr $testfile |
28036                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28037         [ $projid == "1002" ] ||
28038                 error "projid expected 1002 not $projid"
28039 }
28040 run_test 904 "virtual project ID xattr"
28041
28042 complete $SECONDS
28043 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28044 check_and_cleanup_lustre
28045 if [ "$I_MOUNTED" != "yes" ]; then
28046         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28047 fi
28048 exit_status